diff --git a/nixos/doc/manual/release-notes/rl-2611.section.md b/nixos/doc/manual/release-notes/rl-2611.section.md index 1c4ac475952d..b4f95457eef0 100644 --- a/nixos/doc/manual/release-notes/rl-2611.section.md +++ b/nixos/doc/manual/release-notes/rl-2611.section.md @@ -98,6 +98,8 @@ - [ioquake3](https://ioquake3.org), a open-source port of the 3D action shooter Quake 3 Arena. Available as [programs.ioquake3](#opt-programs.ioquake3.enable). +- [Greenlight](https://github.com/bigbluebutton/greenlight), an end-user web interface for the virtual classroom software BigBlueButton. Available as [services.greenlight](#opt-services.greenlight.enable). + - [Matrix Authentication Service](https://github.com/element-hq/matrix-authentication-service) is an OAuth2.0 and OpenID Connect provider for Matrix homeservers (such as Synapse). It replaces standard password authentication with modern OpenID Connect flows, and can delegate authentication to upstream OIDC providers. Available as [services.matrix-authentication-service](#opt-services.matrix-authentication-service.enable). - [Krill](https://nlnetlabs.nl/projects/krill/about), RPKI CA and Publication Server written in Rust. Available as [services.krill](#opt-services.krill.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 481c33cbb2b9..1ad91b265901 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1730,6 +1730,7 @@ ./services/web-apps/gotosocial.nix ./services/web-apps/goupile.nix ./services/web-apps/grav.nix + ./services/web-apps/greenlight.nix ./services/web-apps/grocy.nix ./services/web-apps/guacamole-client.nix ./services/web-apps/guacamole-server.nix diff --git a/nixos/modules/services/web-apps/greenlight.nix b/nixos/modules/services/web-apps/greenlight.nix new file mode 100644 index 000000000000..eeb6fc3fcc83 --- /dev/null +++ b/nixos/modules/services/web-apps/greenlight.nix @@ -0,0 +1,567 @@ +{ + lib, + config, + pkgs, + options, + ... +}: + +let + + cfg = config.services.greenlight; + opt = options.services.greenlight; + + dataDir = "/var/lib/greenlight"; + + listeningAddress = "${cfg.settings.BINDING}:${lib.toString cfg.settings.PORT}"; + + configEnv = lib.concatMapAttrs ( + name: value: + lib.optionalAttrs (value != null) { + ${name} = if lib.isBool value then lib.boolToString value else toString value; + } + ) cfg.settings; + defaultSecretKeyBaseFile = "${dataDir}/secrets/secret-key-base"; + needsGenCredentialsUnit = cfg.secretKeyBaseFile == null; + credentials = { + SECRET_KEY_BASE = lib.defaultTo defaultSecretKeyBaseFile cfg.secretKeyBaseFile; + } + // lib.optionalAttrs (cfg.database.passwordFile != null) { + DATABASE_PASSWORD = cfg.database.passwordFile; + }; + loadCredentialsIntoEnv = lib.concatMapAttrsStringSep "\n" ( + name: _: ''export ${name}="$(systemd-creds cat ${name})"'' + ) credentials; + loadCredentials = lib.mapAttrsToList (name: path: "${name}:${path}") credentials; + + isRedisUnixSocket = lib.hasPrefix "/" cfg.redis.host; + isDatabaseUnixSocket = lib.hasPrefix "/" cfg.database.host; + databaseUrl = "postgresql://${lib.strings.escapeURL cfg.database.user}:$DATABASE_PASSWORD@${lib.strings.escapeURL cfg.database.host}${ + lib.optionalString ( + !isDatabaseUnixSocket && cfg.database.port != null + ) ":${toString cfg.database.port}" + }/${lib.strings.escapeURL cfg.database.name}"; + + redisEnv = + if isRedisUnixSocket then + { + REDIS_URL = "unix://${cfg.redis.host}"; + } + else + { + # Does not support passwords, but upstream does not provide an adequate env variable + # Perhaps patch or make a PR upstream in the future + REDIS_URL = "redis://${cfg.redis.host}:${toString cfg.redis.port}"; + }; + + greenlight-rake = pkgs.writeShellApplication { + name = "greenlight-rake"; + + text = + let + command = pkgs.writeShellScript "greenlight-rake-unwrapped" '' + ${loadCredentialsIntoEnv} + export DATABASE_PASSWORD="''${DATABASE_PASSWORD:-}" + export DATABASE_URL="${databaseUrl}" + exec ${lib.getExe' cfg.package.rubyEnv "rake"} "$@" + ''; + env' = lib.filterAttrs (_: value: value != null) configEnv; + supplementaryGroups = lib.optionalString (cfg.redis.createLocally && isRedisUnixSocket) ( + lib.escapeShellArg "--property=SupplementaryGroups=${config.services.redis.servers.greenlight.group}" + ); + in + '' + exec ${lib.getExe' config.systemd.package "systemd-run"} \ + ${ + lib.escapeShellArgs (map (credential: "--property=LoadCredential=${credential}") loadCredentials) + } \ + ${ + lib.escapeShellArgs (lib.mapAttrsToList (name: value: "--setenv=${name}=${toString value}") env') + } \ + --uid=${lib.escapeShellArg cfg.user} \ + --gid=${lib.escapeShellArg cfg.group} \ + ${supplementaryGroups} \ + --working-directory=${lib.escapeShellArg cfg.package}/share/greenlight \ + --property=PrivateTmp=yes \ + --pty \ + --wait \ + --collect \ + --service-type=exec \ + --quiet \ + -- \ + ${command} "$@" + ''; + }; + + defaultServiceConfig = { + User = cfg.user; + Group = cfg.group; + WorkingDirectory = "${cfg.package}/share/greenlight"; + StateDirectory = [ + "greenlight" + "greenlight/secrets" + "greenlight/storage" + ]; + StateDirectoryMode = "0700"; + LogsDirectory = "greenlight"; + # Service hardening + ReadWritePaths = [ + dataDir + "/var/log/greenlight" + ]; + CacheDirectory = "greenlight"; + AmbientCapabilities = ""; + CapabilityBoundingSet = ""; + # ProtectClock adds DeviceAllow=char-rtc r + DeviceAllow = ""; + DevicePolicy = "closed"; + LockPersonality = true; + # Loosening setting, required by Ruby daemon + MemoryDenyWriteExecute = false; + NoNewPrivileges = true; + RemoveIPC = true; + PrivateDevices = true; + PrivateMounts = true; + PrivateTmp = true; + PrivateUsers = true; + ProtectClock = true; + ProtectHome = true; + ProtectHostname = true; + ProtectSystem = "strict"; + ProtectControlGroups = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProcSubset = "pid"; + RestrictAddressFamilies = [ + "AF_UNIX" + "AF_INET" + "AF_INET6" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service" + # Loosening setting, required by Ruby daemon + #"~@privileged @setuid @keyring" + ]; + UMask = "0077"; + + # ensure permissions to connect to the redis socket + SupplementaryGroups = lib.mkIf (cfg.redis.createLocally && isRedisUnixSocket) [ + config.services.redis.servers.greenlight.group + ]; + }; + +in +{ + meta = { + buildDocsInSandbox = false; + maintainers = [ lib.maintainers.onny ]; + teams = [ lib.teams.ngi ]; + }; + + options.services.greenlight = { + + enable = lib.mkEnableOption "Greenlight web interface for BigBlueButton"; + + package = lib.mkPackageOption pkgs "greenlight" { }; + + database = { + createLocally = lib.mkOption { + description = '' + Whether to configure a local PostgreSQL server and database for Greenlight. + The connection is performed via Unix sockets. + ''; + type = lib.types.bool; + default = true; + }; + + host = lib.mkOption { + type = lib.types.str; + default = "/run/postgresql"; + example = "127.0.0.1"; + description = "Hostname or address of the postgresql server. If an absolute path is given here, it will be interpreted as a unix socket path."; + }; + + port = lib.mkOption { + type = lib.types.nullOr lib.types.port; + default = 5432; + description = "Port of the postgresql server."; + }; + + name = lib.mkOption { + type = lib.types.str; + default = "greenlight"; + description = "The name of the Greenlight database."; + }; + + user = lib.mkOption { + type = lib.types.str; + default = "greenlight"; + description = "The database user for Greenlight."; + }; + + passwordFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + example = "/run/keys/greenlight-db-password"; + description = '' + A file containing the password corresponding to {option}`${opt.database.user}`. + ''; + }; + }; + + redis = { + createLocally = lib.mkOption { + description = '' + Whether to configure a local Redis server for Greenlight. + The connection is performed via Unix sockets by default, + but that can be changed by configuring {option}`${opt.redis.host}` and {option}`${opt.redis.port}`. + ''; + type = lib.types.bool; + default = true; + }; + + host = lib.mkOption { + description = "The redis host Greenlight will connect to."; + type = lib.types.str; + default = + if cfg.redis.createLocally then config.services.redis.servers.greenlight.unixSocket else null; + defaultText = lib.literalExpression "config.services.redis.servers.greenlight.unixSocket"; + }; + + port = lib.mkOption { + description = "The port of the redis server Greenlight will connect to. Set to zero to disable TCP and use Unix sockets instead."; + type = lib.types.port; + default = 0; + }; + }; + + configureNginx = lib.mkOption { + description = '' + Configure nginx as a reverse proxy for Greenlight. + Alternatively you can configure a reverse-proxy of your choice to serve specific + paths. Take a look at Greenlight's provided reverse proxy configurations at + `https://github.com/bigbluebutton/greenlight/blob/master/greenlight-v3.nginx`. + ''; + type = lib.types.bool; + default = true; + }; + + user = lib.mkOption { + description = '' + User under which Greenlight runs. If it is set to "greenlight", + that user will be created, otherwise it should be set to the + name of a user created elsewhere. + ''; + type = lib.types.str; + default = "greenlight"; + }; + + group = lib.mkOption { + description = '' + Group under which Greenlight runs. + ''; + type = lib.types.str; + default = "greenlight"; + }; + + settings = lib.mkOption { + type = lib.types.submodule { + freeformType = lib.types.attrsOf ( + lib.types.nullOr ( + lib.types.oneOf [ + lib.types.str + lib.types.bool + lib.types.int + lib.types.port + lib.types.path + ] + ) + ); + options = { + URL_HOST = lib.mkOption { + type = lib.types.str; + default = "localhost"; + description = "Hostname to use"; + }; + PORT = lib.mkOption { + type = lib.types.port; + default = 6346; + description = "Port for the puma daemon to bind to."; + }; + BINDING = lib.mkOption { + type = lib.types.str; + default = "127.0.0.1"; + description = "Address for the puma daemon to bind to."; + }; + }; + }; + default = { }; + description = '' + Extra configuration options to append or override. + For available and default option values see + [upstream configuration file](https://github.com/bigbluebutton/greenlight/blob/master/sample.env). + ''; + }; + + secretKeyBaseFile = lib.mkOption { + description = '' + Path to file containing the secret key base. + The content of the file will be sourced into {env}`SECRET_KEY_BASE` environment + variable. The secret has a minimum length requirement of 64 bytes. + + One way to generate such a secret is to use `openssl rand -hex 64`. + + This file is loaded using systemd credentials, and therefore does not need to be + owned by the greenlight user. + + If this option is null, it will be created at ${defaultSecretKeyBaseFile} + with a new secret key base. + ''; + default = null; + type = lib.types.nullOr lib.types.str; + }; + + }; + + config = lib.mkIf cfg.enable { + + assertions = [ + { + assertion = !isRedisUnixSocket -> cfg.redis.port != 0; + message = '' + `services.greenlight.redis.port` needs to be configured if `services.greenlight.redis.host` is not a unix socket. + ''; + } + { + assertion = !isDatabaseUnixSocket -> cfg.database.port != null; + message = '' + `services.greenlight.database.port` needs to be configured if `services.greenlight.database.host` is not a unix socket. + ''; + } + { + assertion = cfg.database.passwordFile == null || !isDatabaseUnixSocket; + message = '' + `services.greenlight.database.passwordFile` has no effect when `services.greenlight.database.host` + is a unix socket, since local socket connections normally authenticate via peer/ident, not a password. + Either point `database.host` at a TCP address, or drop `passwordFile`. + ''; + } + { + assertion = !(cfg.database.createLocally && cfg.database.passwordFile != null); + message = '' + `services.greenlight.database.passwordFile` is set, but `database.createLocally` is also enabled. + The PostgreSQL role created via `ensureUsers` has no password configured, so authentication would + fail. Either disable `database.createLocally` and use an external database, or configure the local + role's password yourself (e.g. via `services.postgresql.initialScript`) and keep it in sync with + `passwordFile`. + ''; + } + { + assertion = cfg.database.createLocally && isDatabaseUnixSocket -> cfg.database.user == cfg.user; + message = '' + services.greenlight.database.user must equal services.greenlight.user when + services.greenlight.database.createLocally is true and services.greenlight.database.host + is a unix socket, since the local PostgreSQL connection authenticates via peer auth + (OS user must match the Postgres role name). + ''; + } + ]; + + services.greenlight.settings = lib.mkMerge [ + { + RAILS_ENV = lib.mkDefault "production"; + RAILS_ROOT = "${cfg.package}/share/greenlight"; + BUNDLE_WITHOUT = "development:test"; + BUNDLE_USER_HOME = "/tmp/bundle"; # will use private tmp inside systemd unit + } + redisEnv + ]; + + systemd.services.greenlight-init-credentials = lib.mkIf needsGenCredentialsUnit { + script = '' + if ! test -f ${defaultSecretKeyBaseFile}; then + ${lib.getExe' cfg.package.rubyEnv "bundle"} exec rails secret > ${defaultSecretKeyBaseFile} + fi + ''; + serviceConfig = { + Type = "oneshot"; + SyslogIdentifier = "greenlight-init-dirs"; + } + // defaultServiceConfig; + environment = configEnv; + after = [ "network.target" ]; + }; + + systemd.services."greenlight-seeder" = { + script = '' + set -o pipefail -o nounset + shopt -s inherit_errexit + ${loadCredentialsIntoEnv} + + export DATABASE_PASSWORD="''${DATABASE_PASSWORD:-}" + export DATABASE_URL="${databaseUrl}" + + # Auto-migrate on first run or if the package has changed + versionFile="${dataDir}/src-version" + version=$(cat "$versionFile" 2>/dev/null || echo 0) + + if [[ $version == 0 ]]; then + echo "Initialising database and running seed..." + DISABLE_DATABASE_ENVIRONMENT_CHECK=1 rails db:migrate db:migrate:with_data + echo ${cfg.package.version} > "$versionFile" + elif [[ $version != ${cfg.package.version} ]]; then + echo "Executing database migration and database seed..." + rails db:migrate db:migrate:with_data + echo ${cfg.package.version} > "$versionFile" + fi + ''; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + LoadCredential = loadCredentials; + } + // defaultServiceConfig; + path = [ cfg.package.rubyEnv ]; + environment = configEnv; + wants = lib.optional cfg.database.createLocally "postgresql.target"; + after = [ + "network.target" + ] + ++ lib.optional cfg.database.createLocally "postgresql.target" + ++ lib.optional needsGenCredentialsUnit "greenlight-init-credentials.service" + ++ lib.optional cfg.redis.createLocally "redis-greenlight.service"; + requires = + lib.optional needsGenCredentialsUnit "greenlight-init-credentials.service" + ++ lib.optional cfg.database.createLocally "postgresql.target" + ++ lib.optional cfg.redis.createLocally "redis-greenlight.service"; + }; + + systemd.services."greenlight-web" = { + script = '' + ${loadCredentialsIntoEnv} + + export DATABASE_PASSWORD="''${DATABASE_PASSWORD:-}" + export DATABASE_URL="${databaseUrl}" + + ${lib.getExe' cfg.package.rubyEnv "bundle"} exec rails server -u puma + ''; + serviceConfig = { + LoadCredential = loadCredentials; + } + // defaultServiceConfig; + environment = configEnv; + bindsTo = [ "greenlight-seeder.service" ]; + after = [ + "greenlight-seeder.service" + ] + ++ lib.optional needsGenCredentialsUnit "greenlight-init-credentials.service" + ++ lib.optional cfg.database.createLocally "postgresql.target" + ++ lib.optional cfg.redis.createLocally "redis-greenlight.service"; + requires = + lib.optional needsGenCredentialsUnit "greenlight-init-credentials.service" + ++ lib.optional cfg.database.createLocally "postgresql.target" + ++ lib.optional cfg.redis.createLocally "redis-greenlight.service"; + wantedBy = [ "multi-user.target" ]; + }; + + services.redis.servers = lib.mkIf cfg.redis.createLocally { + greenlight = { + enable = true; + port = cfg.redis.port; + bind = lib.mkIf (!isRedisUnixSocket) cfg.redis.host; + }; + }; + + services.postgresql = lib.mkIf cfg.database.createLocally { + enable = true; + ensureUsers = [ + { + name = cfg.database.user; + ensureDBOwnership = true; + } + ]; + ensureDatabases = [ cfg.database.name ]; + }; + + services.nginx = lib.mkIf cfg.configureNginx { + enable = true; + # See https://github.com/bigbluebutton/greenlight/blob/master/greenlight-v3.nginx + virtualHosts."${cfg.settings.URL_HOST}" = + let + bbbProxyHeaders = '' + proxy_redirect off; + proxy_http_version 1.1; + proxy_set_header Host "${cfg.settings.URL_HOST}"; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + ''; + in + { + root = "${cfg.package}/share/greenlight/public"; + locations."/" = { + tryFiles = "$uri @greenlight"; + }; + locations."@greenlight" = { + proxyPass = "http://${listeningAddress}"; + extraConfig = bbbProxyHeaders; + }; + locations."/cable" = { + proxyPass = "http://${listeningAddress}"; + extraConfig = bbbProxyHeaders + '' + proxy_set_header Connection "upgrade"; + proxy_set_header Upgrade $http_upgrade; + ''; + }; + locations."@bbb-fe" = { + proxyPass = "http://${listeningAddress}"; + extraConfig = bbbProxyHeaders + '' + proxy_set_header Connection ""; + proxy_buffer_size 128k; + proxy_buffers 4 256k; + proxy_busy_buffers_size 256k; + ''; + }; + locations."~ '/api/v1/rooms/\\w{3}-\\w{3}-\\w{3}-\\w{3}\\.json$'" = { + proxyPass = "http://${listeningAddress}"; + extraConfig = bbbProxyHeaders + '' + proxy_set_header Connection ""; + client_max_body_size 31m; + ''; + }; + locations."~ '/api/v1/users/\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12}\\.json$'" = { + proxyPass = "http://${listeningAddress}"; + extraConfig = bbbProxyHeaders + '' + proxy_set_header Connection ""; + client_max_body_size 4m; + ''; + }; + locations."~ /api/v1/admin/site_settings/BrandingImage\\.json$" = { + proxyPass = "http://${listeningAddress}"; + extraConfig = bbbProxyHeaders + '' + proxy_set_header Connection ""; + client_max_body_size 4m; + ''; + }; + }; + }; + + users.users = lib.mkIf (cfg.user == "greenlight") { + greenlight = { + isSystemUser = true; + home = cfg.package; + inherit (cfg) group; + }; + }; + users.groups = lib.mkIf (cfg.group == "greenlight") { ${cfg.group} = { }; }; + + environment.systemPackages = [ greenlight-rake ]; + + }; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 43a70e8f8085..2f0815a42671 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -804,6 +804,7 @@ in graphite = runTest ./graphite.nix; grav = runTest ./web-apps/grav.nix; graylog = runTest ./graylog.nix; + greenlight = runTest ./greenlight.nix; greetd-no-shadow = runTest ./greetd-no-shadow.nix; grocy = runTest ./grocy.nix; grow-partition = runTest ./grow-partition.nix; diff --git a/nixos/tests/greenlight.nix b/nixos/tests/greenlight.nix new file mode 100644 index 000000000000..fcda63df21b0 --- /dev/null +++ b/nixos/tests/greenlight.nix @@ -0,0 +1,56 @@ +{ + lib, + pkgs, + ... +}: + +{ + name = "greenlight"; + meta = { + maintainers = [ lib.maintainers.onny ]; + teams = [ lib.teams.ngi ]; + }; + + nodes = { + greenlight = { + services.greenlight = { + enable = true; + # For local testing without SSL + settings = { + RAILS_ENV = "development"; + RAILS_DUMP_SCHEMA = false; + }; + }; + }; + }; + + testScript = '' + greenlight.start + greenlight.wait_for_unit("greenlight-web.service") + greenlight.wait_for_open_port(80) + greenlight.wait_for_open_port(6346) + greenlight.succeed("curl -sSfL http://greenlight:80 | grep 'BigBlueButton open source conferencing system'") + + greenlight.succeed( + "greenlight-rake admin:create", + ) + + # grab session cookie + CSRF token + greenlight.succeed("curl -sS -c /tmp/cookies.txt http://localhost/ -o /tmp/page.html") + csrf_token = greenlight.succeed( + "grep -o 'name=\"csrf-token\" content=\"[^\"]*\"' /tmp/page.html " + "| sed 's/.*content=\"//;s/\"$//'" + ).strip() + + # log in with default credentials + login_result = greenlight.succeed( + f"curl -sSf -c /tmp/cookies.txt -b /tmp/cookies.txt " + f"-X POST http://localhost/api/v1/sessions.json " + f"-H 'Content-Type: application/json' -H 'Accept: application/json' " + f"-H 'X-CSRF-Token: {csrf_token}' " + f"-d '{{\"session\":{{\"email\":\"admin@example.com\",\"password\":\"Administrator1!\"}}}}'" + ) + assert '"signed_in":true' in login_result, f"login failed: {login_result}" + ''; + +} diff --git a/pkgs/by-name/gr/greenlight/Gemfile.lock b/pkgs/by-name/gr/greenlight/Gemfile.lock new file mode 100644 index 000000000000..29d3bb56fd48 --- /dev/null +++ b/pkgs/by-name/gr/greenlight/Gemfile.lock @@ -0,0 +1,583 @@ +GEM + remote: https://rubygems.org/ + specs: + actioncable (7.2.3.1) + actionpack (= 7.2.3.1) + activesupport (= 7.2.3.1) + nio4r (~> 2.0) + websocket-driver (>= 0.6.1) + zeitwerk (~> 2.6) + actionmailbox (7.2.3.1) + actionpack (= 7.2.3.1) + activejob (= 7.2.3.1) + activerecord (= 7.2.3.1) + activestorage (= 7.2.3.1) + activesupport (= 7.2.3.1) + mail (>= 2.8.0) + actionmailer (7.2.3.1) + actionpack (= 7.2.3.1) + actionview (= 7.2.3.1) + activejob (= 7.2.3.1) + activesupport (= 7.2.3.1) + mail (>= 2.8.0) + rails-dom-testing (~> 2.2) + actionpack (7.2.3.1) + actionview (= 7.2.3.1) + activesupport (= 7.2.3.1) + cgi + nokogiri (>= 1.8.5) + racc + rack (>= 2.2.4, < 3.3) + rack-session (>= 1.0.1) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + useragent (~> 0.16) + actiontext (7.2.3.1) + actionpack (= 7.2.3.1) + activerecord (= 7.2.3.1) + activestorage (= 7.2.3.1) + activesupport (= 7.2.3.1) + globalid (>= 0.6.0) + nokogiri (>= 1.8.5) + actionview (7.2.3.1) + activesupport (= 7.2.3.1) + builder (~> 3.1) + cgi + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + active_model_serializers (0.10.15) + actionpack (>= 4.1) + activemodel (>= 4.1) + case_transform (>= 0.2) + jsonapi-renderer (>= 0.1.1.beta1, < 0.3) + active_storage_validations (3.0.2) + activejob (>= 6.1.4) + activemodel (>= 6.1.4) + activestorage (>= 6.1.4) + activesupport (>= 6.1.4) + marcel (>= 1.0.3) + activejob (7.2.3.1) + activesupport (= 7.2.3.1) + globalid (>= 0.3.6) + activemodel (7.2.3.1) + activesupport (= 7.2.3.1) + activerecord (7.2.3.1) + activemodel (= 7.2.3.1) + activesupport (= 7.2.3.1) + timeout (>= 0.4.0) + activestorage (7.2.3.1) + actionpack (= 7.2.3.1) + activejob (= 7.2.3.1) + activerecord (= 7.2.3.1) + activesupport (= 7.2.3.1) + marcel (~> 1.0) + activesupport (7.2.3.1) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + logger (>= 1.4.2) + minitest (>= 5.1, < 6) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + addressable (2.9.0) + public_suffix (>= 2.0.2, < 8.0) + aes_key_wrap (1.1.0) + ast (2.4.3) + attr_required (1.0.2) + aws-eventstream (1.4.0) + aws-partitions (1.1196.0) + aws-sdk-core (3.240.0) + aws-eventstream (~> 1, >= 1.3.0) + aws-partitions (~> 1, >= 1.992.0) + aws-sigv4 (~> 1.9) + base64 + bigdecimal + jmespath (~> 1, >= 1.6.1) + logger + aws-sdk-kms (1.118.0) + aws-sdk-core (~> 3, >= 3.239.1) + aws-sigv4 (~> 1.5) + aws-sdk-s3 (1.208.0) + aws-sdk-core (~> 3, >= 3.234.0) + aws-sdk-kms (~> 1) + aws-sigv4 (~> 1.5) + aws-sigv4 (1.12.1) + aws-eventstream (~> 1, >= 1.0.2) + base64 (0.3.0) + bcrypt (3.1.22) + benchmark (0.5.0) + bigbluebutton-api-ruby (2.0.0) + base64 (>= 0.1.0) + xml-simple (~> 1.1) + bigdecimal (4.1.1) + bindata (2.5.1) + bindex (0.8.1) + bootsnap (1.16.0) + msgpack (~> 1.2) + builder (3.3.0) + capybara (3.40.0) + addressable + matrix + mini_mime (>= 0.1.3) + nokogiri (~> 1.11) + rack (>= 1.6.0) + rack-test (>= 0.6.3) + regexp_parser (>= 1.5, < 3.0) + xpath (~> 3.2) + case_transform (0.2) + activesupport + cgi (0.5.1) + clamby (1.6.10) + concurrent-ruby (1.3.7) + connection_pool (2.5.5) + crack (1.0.0) + bigdecimal + rexml + crass (1.0.6) + cssbundling-rails (1.4.3) + railties (>= 6.0.0) + data_migrate (11.3.1) + activerecord (>= 6.1) + railties (>= 6.1) + date (3.5.1) + debug (1.11.0) + irb (~> 1.10) + reline (>= 0.3.8) + declarative (0.0.20) + diff-lcs (1.6.2) + digest-crc (0.7.0) + rake (>= 12.0.0, < 14.0.0) + dotenv (3.2.0) + dotenv-rails (3.2.0) + dotenv (= 3.2.0) + railties (>= 6.1) + drb (2.2.3) + email_validator (2.2.4) + activemodel + erb (6.0.1.1) + erubi (1.13.1) + factory_bot (6.5.6) + activesupport (>= 6.1.0) + factory_bot_rails (6.5.1) + factory_bot (~> 6.5) + railties (>= 6.1.0) + faker (3.1.1) + i18n (>= 1.8.11, < 2) + faraday (2.14.3) + faraday-net_http (>= 2.0, < 3.5) + json + logger + faraday-follow_redirects (0.4.0) + faraday (>= 1, < 3) + faraday-net_http (3.4.4) + net-http (~> 0.5) + ffi (1.17.2) + globalid (1.3.0) + activesupport (>= 6.1) + google-apis-core (1.0.2) + addressable (~> 2.8, >= 2.8.7) + faraday (~> 2.13) + faraday-follow_redirects (~> 0.3) + googleauth (~> 1.14) + mini_mime (~> 1.1) + representable (~> 3.0) + retriable (~> 3.1) + google-apis-iamcredentials_v1 (0.26.0) + google-apis-core (>= 0.15.0, < 2.a) + google-apis-storage_v1 (0.60.0) + google-apis-core (>= 0.15.0, < 2.a) + google-cloud-core (1.8.0) + google-cloud-env (>= 1.0, < 3.a) + google-cloud-errors (~> 1.0) + google-cloud-env (2.3.1) + base64 (~> 0.2) + faraday (>= 1.0, < 3.a) + google-cloud-errors (1.5.0) + google-cloud-storage (1.58.0) + addressable (~> 2.8) + digest-crc (~> 0.4) + google-apis-core (>= 0.18, < 2) + google-apis-iamcredentials_v1 (~> 0.18) + google-apis-storage_v1 (>= 0.42) + google-cloud-core (~> 1.6) + googleauth (~> 1.9) + mini_mime (~> 1.0) + google-logging-utils (0.2.0) + googleauth (1.16.1) + faraday (>= 1.0, < 3.a) + google-cloud-env (~> 2.2) + google-logging-utils (~> 0.1) + jwt (>= 1.4, < 4.0) + multi_json (~> 1.11) + os (>= 0.9, < 2.0) + signet (>= 0.16, < 2.a) + hashdiff (1.1.2) + hashie (5.0.0) + hcaptcha (7.1.0) + json + i18n (1.14.8) + concurrent-ruby (~> 1.0) + i18n-language-mapping (0.1.3.1) + image_processing (1.12.2) + mini_magick (>= 4.9.5, < 5) + ruby-vips (>= 2.0.17, < 3) + io-console (0.8.1) + irb (1.15.3) + pp (>= 0.6.0) + rdoc (>= 4.0.0) + reline (>= 0.4.2) + jbuilder (2.13.0) + actionview (>= 5.0.0) + activesupport (>= 5.0.0) + jmespath (1.6.2) + jsbundling-rails (1.3.1) + railties (>= 6.0.0) + json (2.19.9) + json-jwt (1.17.0) + activesupport (>= 4.2) + aes_key_wrap + base64 + bindata + faraday (~> 2.0) + faraday-follow_redirects + jsonapi-renderer (0.2.2) + jwt (3.2.0) + base64 + language_server-protocol (3.17.0.5) + lint_roller (1.1.0) + logger (1.7.0) + lograge (0.14.0) + actionpack (>= 4) + activesupport (>= 4) + railties (>= 4) + request_store (~> 1.0) + loofah (2.25.1) + crass (~> 1.0.2) + nokogiri (>= 1.12.0) + mail (2.9.0) + logger + mini_mime (>= 0.1.1) + net-imap + net-pop + net-smtp + marcel (1.1.0) + matrix (0.4.3) + mini_magick (4.12.0) + mini_mime (1.1.5) + mini_portile2 (2.8.9) + minitest (5.27.0) + msgpack (1.6.0) + multi_json (1.19.1) + net-http (0.9.1) + uri (>= 0.11.1) + net-imap (0.5.15) + date + net-protocol + net-pop (0.1.2) + net-protocol + net-protocol (0.2.2) + timeout + net-smtp (0.5.1) + net-protocol + nio4r (2.7.5) + nkf (0.2.0) + nokogiri (1.19.4) + mini_portile2 (~> 2.8.2) + racc (~> 1.4) + omniauth (2.1.4) + hashie (>= 3.4.6) + logger + rack (>= 2.2.3) + rack-protection + omniauth-rails_csrf_protection (2.0.0) + actionpack (>= 4.2) + omniauth (~> 2.0) + omniauth_openid_connect (0.8.0) + omniauth (>= 1.9, < 3) + openid_connect (~> 2.2) + openid_connect (2.3.1) + activemodel + attr_required (>= 1.0.0) + email_validator + faraday (~> 2.0) + faraday-follow_redirects + json-jwt (>= 1.16) + mail + rack-oauth2 (~> 2.2) + swd (~> 2.0) + tzinfo + validate_url + webfinger (~> 2.0) + os (1.1.4) + pagy (6.0.4) + parallel (1.27.0) + parser (3.3.10.0) + ast (~> 2.4.1) + racc + pg (1.4.5) + pp (0.6.3) + prettyprint + prettyprint (0.2.0) + prism (1.6.0) + psych (5.2.6) + date + stringio + public_suffix (7.0.5) + puma (7.2.1) + nio4r (~> 2.0) + racc (1.8.1) + rack (3.2.6) + rack-oauth2 (2.3.0) + activesupport + attr_required + faraday (~> 2.0) + faraday-follow_redirects + json-jwt (>= 1.11.0) + rack (>= 2.1.0) + rack-protection (4.2.1) + base64 (>= 0.1.0) + logger (>= 1.6.0) + rack (>= 3.0.0, < 4) + rack-session (2.1.2) + base64 (>= 0.1.0) + rack (>= 3.0.0) + rack-test (2.2.0) + rack (>= 1.3) + rackup (2.2.1) + rack (>= 3) + rails (7.2.3.1) + actioncable (= 7.2.3.1) + actionmailbox (= 7.2.3.1) + actionmailer (= 7.2.3.1) + actionpack (= 7.2.3.1) + actiontext (= 7.2.3.1) + actionview (= 7.2.3.1) + activejob (= 7.2.3.1) + activemodel (= 7.2.3.1) + activerecord (= 7.2.3.1) + activestorage (= 7.2.3.1) + activesupport (= 7.2.3.1) + bundler (>= 1.15.0) + railties (= 7.2.3.1) + rails-dom-testing (2.3.0) + activesupport (>= 5.0.0) + minitest + nokogiri (>= 1.6) + rails-html-sanitizer (1.7.0) + loofah (~> 2.25) + nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) + railties (7.2.3.1) + actionpack (= 7.2.3.1) + activesupport (= 7.2.3.1) + cgi + irb (~> 1.13) + rackup (>= 1.0.0) + rake (>= 12.2) + thor (~> 1.0, >= 1.2.2) + tsort (>= 0.2) + zeitwerk (~> 2.6) + rainbow (3.1.1) + rake (13.3.1) + rdoc (6.16.1) + erb + psych (>= 4.0.0) + tsort + redis (4.8.0) + regexp_parser (2.11.3) + reline (0.6.3) + io-console (~> 0.5) + remote_syslog_logger (1.0.4) + syslog_protocol + representable (3.2.0) + declarative (< 0.1.0) + trailblazer-option (>= 0.1.1, < 0.2.0) + uber (< 0.2.0) + request_store (1.5.1) + rack (>= 1.4) + retriable (3.1.2) + rexml (3.4.4) + rspec-core (3.13.6) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.7) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-rails (7.1.1) + actionpack (>= 7.0) + activesupport (>= 7.0) + railties (>= 7.0) + rspec-core (~> 3.13) + rspec-expectations (~> 3.13) + rspec-mocks (~> 3.13) + rspec-support (~> 3.13) + rspec-support (3.13.6) + rubocop (1.81.7) + json (~> 2.3) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.47.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.48.0) + parser (>= 3.3.7.2) + prism (~> 1.4) + rubocop-capybara (2.19.0) + rubocop (~> 1.41) + rubocop-factory_bot (2.24.0) + rubocop (~> 1.33) + rubocop-performance (1.16.0) + rubocop (>= 1.7.0, < 2.0) + rubocop-ast (>= 0.4.0) + rubocop-rails (2.34.2) + activesupport (>= 4.2.0) + lint_roller (~> 1.1) + rack (>= 1.1) + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.44.0, < 2.0) + rubocop-rspec (2.9.0) + rubocop (~> 1.19) + ruby-progressbar (1.13.0) + ruby-vips (2.1.4) + ffi (~> 1.12) + rubyzip (2.4.1) + securerandom (0.4.1) + selenium-webdriver (4.8.0) + rexml (~> 3.2, >= 3.2.5) + rubyzip (>= 1.2.2, < 3.0) + websocket (~> 1.0) + shoulda-matchers (5.3.0) + activesupport (>= 5.2.0) + signet (0.21.0) + addressable (~> 2.8) + faraday (>= 0.17.5, < 3.a) + jwt (>= 1.5, < 4.0) + multi_json (~> 1.10) + sprockets (4.2.2) + concurrent-ruby (~> 1.0) + logger + rack (>= 2.2.4, < 4) + sprockets-rails (3.5.2) + actionpack (>= 6.1) + activesupport (>= 6.1) + sprockets (>= 3.0.0) + stringio (3.1.9) + swd (2.0.3) + activesupport (>= 3) + attr_required (>= 0.0.5) + faraday (~> 2.0) + faraday-follow_redirects + syslog_protocol (0.9.2) + thor (1.4.0) + timeout (0.6.1) + trailblazer-option (0.1.2) + tsort (0.2.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + uber (0.1.0) + unicode-display_width (3.2.0) + unicode-emoji (~> 4.1) + unicode-emoji (4.1.0) + uri (1.1.1) + useragent (0.16.11) + validate_url (1.0.15) + activemodel (>= 3.0.0) + public_suffix + web-console (4.2.1) + actionview (>= 6.0.0) + activemodel (>= 6.0.0) + bindex (>= 0.4.0) + railties (>= 6.0.0) + webdrivers (5.2.0) + nokogiri (~> 1.6) + rubyzip (>= 1.3.0) + selenium-webdriver (~> 4.0) + webfinger (2.1.3) + activesupport + faraday (~> 2.0) + faraday-follow_redirects + webmock (3.24.0) + addressable (>= 2.8.0) + crack (>= 0.3.2) + hashdiff (>= 0.4.0, < 2.0.0) + websocket (1.2.9) + websocket-driver (0.8.1) + base64 + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.5) + xml-simple (1.1.9) + rexml + xpath (3.2.0) + nokogiri (~> 1.8) + zeitwerk (2.7.3) + +PLATFORMS + ruby + +DEPENDENCIES + active_model_serializers (>= 0.10.15) + active_storage_validations (>= 1.4.0) + aws-sdk-s3 + bcrypt (~> 3.1.22) + bigbluebutton-api-ruby (= 2.0.0) + bootsnap + capybara (>= 3.39.0) + clamby (~> 1.6.10) + connection_pool (~> 2.4) + cssbundling-rails (>= 1.4.0) + data_migrate (>= 11.3.0) + debug + dotenv-rails (>= 3.0.0) + factory_bot (>= 6.4.1) + factory_bot_rails (>= 6.4.4) + faker + google-cloud-storage (~> 1.45, >= 1.45.0) + hcaptcha + i18n-language-mapping + image_processing (~> 1.2) + jbuilder (>= 2.12) + jsbundling-rails (>= 1.3.0) + jwt + lograge (~> 0.14.0) + mini_magick (>= 4.9.5) + nkf (~> 0.2.0) + omniauth (~> 2.1.3) + omniauth-rails_csrf_protection (~> 2.0.0) + omniauth_openid_connect (>= 0.8.0) + pagy (~> 6.0, >= 6.0.0) + pg + puma (~> 7.2) + rails (~> 7.2.3) + redis (~> 4.8.0) + remote_syslog_logger + rspec-rails (~> 7.1, >= 7.1.1) + rubocop (~> 1.26) + rubocop-capybara (~> 2.19.0) + rubocop-factory_bot (~> 2.24.0) + rubocop-performance (~> 1.13) + rubocop-rails (~> 2.21, >= 2.21.0) + rubocop-rspec (~> 2.9.0) + selenium-webdriver + shoulda-matchers (~> 5.0) + sprockets-rails (>= 3.5.1) + tzinfo-data + web-console (>= 4.2.1) + webdrivers + webmock (>= 3.23.1) + +RUBY VERSION + ruby 3.3.10p183 + +BUNDLED WITH + 2.5.22 diff --git a/pkgs/by-name/gr/greenlight/expose_rails_dev_configs.patch b/pkgs/by-name/gr/greenlight/expose_rails_dev_configs.patch new file mode 100644 index 000000000000..8e5caf2400b6 --- /dev/null +++ b/pkgs/by-name/gr/greenlight/expose_rails_dev_configs.patch @@ -0,0 +1,17 @@ +diff --git a/config/environments/development.rb b/config/environments/development.rb +index c0cba740..a4a3f4d1 100644 +--- a/config/environments/development.rb ++++ b/config/environments/development.rb +@@ -117,6 +117,12 @@ Rails.application.configure do + # Suppress logger output for asset requests. + config.assets.quiet = true + ++ # Do not dump schema after migrations. ++ config.active_record.dump_schema_after_migration = Rails.env.development? && ENV["RAILS_DUMP_SCHEMA"] != "false" ++ ++ # Ensure requests are considered secure if they come through a reverse proxy with the correct headers ++ config.action_controller.forgery_protection_origin_check = ENV['FORGERY_ORIGIN_CHECK'] != 'false' ++ + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true + diff --git a/pkgs/by-name/gr/greenlight/gemset.nix b/pkgs/by-name/gr/greenlight/gemset.nix new file mode 100644 index 000000000000..65701b33e950 --- /dev/null +++ b/pkgs/by-name/gr/greenlight/gemset.nix @@ -0,0 +1,2838 @@ +{ + actioncable = { + dependencies = [ + "actionpack" + "activesupport" + "nio4r" + "websocket-driver" + "zeitwerk" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0g5kbrqvhwlliyrzd2bhc3kdiqm58df0x3w716bs0ygwyjil1gyk"; + type = "gem"; + }; + version = "7.2.3.1"; + }; + actionmailbox = { + dependencies = [ + "actionpack" + "activejob" + "activerecord" + "activestorage" + "activesupport" + "mail" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0hf59r6sk0qb5va0ga549rbadcb5n1a2ry8nlkszzcksr6039rx4"; + type = "gem"; + }; + version = "7.2.3.1"; + }; + actionmailer = { + dependencies = [ + "actionpack" + "actionview" + "activejob" + "activesupport" + "mail" + "rails-dom-testing" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0rq4aan18y6gwziabnj1q1486349k1v1i5m7ysv206pqqpavcy7m"; + type = "gem"; + }; + version = "7.2.3.1"; + }; + actionpack = { + dependencies = [ + "actionview" + "activesupport" + "cgi" + "nokogiri" + "racc" + "rack" + "rack-session" + "rack-test" + "rails-dom-testing" + "rails-html-sanitizer" + "useragent" + ]; + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1jp4w493wvfh9246wxk7g00m1a3vmzkvs0rznq62fwvjjdzzwsmn"; + type = "gem"; + }; + version = "7.2.3.1"; + }; + actiontext = { + dependencies = [ + "actionpack" + "activerecord" + "activestorage" + "activesupport" + "globalid" + "nokogiri" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1qs350j3zm7sd6xxn61d93mv3lx1ravbjqja12c7nd7a0zs1h52v"; + type = "gem"; + }; + version = "7.2.3.1"; + }; + actionview = { + dependencies = [ + "activesupport" + "builder" + "cgi" + "erubi" + "rails-dom-testing" + "rails-html-sanitizer" + ]; + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0z7zy6ibfpsdj9jbdm54bx3ws4dszcq7qa564jn645rr8dlbh6fy"; + type = "gem"; + }; + version = "7.2.3.1"; + }; + active_model_serializers = { + dependencies = [ + "actionpack" + "activemodel" + "case_transform" + "jsonapi-renderer" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0k0cig5ic38vfd7iba3rv3h7hs2lmycqp0wx4w286kmbhch5n9q8"; + type = "gem"; + }; + version = "0.10.15"; + }; + active_storage_validations = { + dependencies = [ + "activejob" + "activemodel" + "activestorage" + "activesupport" + "marcel" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0yzi57ss7mqi8vfw87dsdqlbpgx3sqisivplf9ylqglj5hjaqxs2"; + type = "gem"; + }; + version = "3.0.2"; + }; + activejob = { + dependencies = [ + "activesupport" + "globalid" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1n3fiwm1x3dxwj36n9pspd2bgffyw28ys9yd36hjvf3iwdy25i0b"; + type = "gem"; + }; + version = "7.2.3.1"; + }; + activemodel = { + dependencies = [ "activesupport" ]; + groups = [ + "default" + "development" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1l60a6mqx1wgp15ki1cp68djci0czgrikpydii5bd877hndqdq9r"; + type = "gem"; + }; + version = "7.2.3.1"; + }; + activerecord = { + dependencies = [ + "activemodel" + "activesupport" + "timeout" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0pd0f1hy6rvyanmrklqir33xq0jb2my4jajz7hc38nysfpi175dq"; + type = "gem"; + }; + version = "7.2.3.1"; + }; + activestorage = { + dependencies = [ + "actionpack" + "activejob" + "activerecord" + "activesupport" + "marcel" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1azzbpfp726yigwzmj8g2jji149wisnwrgb86zix6mk25sj4w8hb"; + type = "gem"; + }; + version = "7.2.3.1"; + }; + activesupport = { + dependencies = [ + "base64" + "benchmark" + "bigdecimal" + "concurrent-ruby" + "connection_pool" + "drb" + "i18n" + "logger" + "minitest" + "securerandom" + "tzinfo" + ]; + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0d6bhg9cim83g8cypjd7cms45ng4p9ga69v26i3vp823d98yvsqi"; + type = "gem"; + }; + version = "7.2.3.1"; + }; + addressable = { + dependencies = [ "public_suffix" ]; + groups = [ + "default" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1by7h2lwziiblizpd5yx87jsq8ppdhzvwf08ga34wzqgcv1nmpvz"; + type = "gem"; + }; + version = "2.9.0"; + }; + aes_key_wrap = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "19bn0y70qm6mfj4y1m0j3s8ggh6dvxwrwrj5vfamhdrpddsz8ddr"; + type = "gem"; + }; + version = "1.1.0"; + }; + ast = { + groups = [ + "default" + "development" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "10yknjyn0728gjn6b5syynvrvrwm66bhssbxq8mkhshxghaiailm"; + type = "gem"; + }; + version = "2.4.3"; + }; + attr_required = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "16fbwr6nmsn97n0a6k1nwbpyz08zpinhd6g7196lz1syndbgrszh"; + type = "gem"; + }; + version = "1.0.2"; + }; + aws-eventstream = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0fqqdqg15rgwgz3mn4pj91agd20csk9gbrhi103d20328dfghsqi"; + type = "gem"; + }; + version = "1.4.0"; + }; + aws-partitions = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0r2mqf3mi41nfa3pqm6c7gbrvd6fydvsnnfakyzqbxwq29zwyqhs"; + type = "gem"; + }; + version = "1.1196.0"; + }; + aws-sdk-core = { + dependencies = [ + "aws-eventstream" + "aws-partitions" + "aws-sigv4" + "base64" + "bigdecimal" + "jmespath" + "logger" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "17hqin6ngvlhhb414pxlq8q95j0fndljcblp09kzbajwaa83idl6"; + type = "gem"; + }; + version = "3.240.0"; + }; + aws-sdk-kms = { + dependencies = [ + "aws-sdk-core" + "aws-sigv4" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1gbgf7xgg2hrrc51g3mpf0isba801w0r0z45mjnh45agdmcm3iy9"; + type = "gem"; + }; + version = "1.118.0"; + }; + aws-sdk-s3 = { + dependencies = [ + "aws-sdk-core" + "aws-sdk-kms" + "aws-sigv4" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0vbxg6hy0j2b931llwc0jxg1q27grbs31zdhzwjy9fki05817kiz"; + type = "gem"; + }; + version = "1.208.0"; + }; + aws-sigv4 = { + dependencies = [ "aws-eventstream" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "003ch8qzh3mppsxch83ns0jra8d222ahxs96p9cdrl0grfazywv9"; + type = "gem"; + }; + version = "1.12.1"; + }; + base64 = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0yx9yn47a8lkfcjmigk79fykxvr80r4m1i35q82sxzynpbm7lcr7"; + type = "gem"; + }; + version = "0.3.0"; + }; + bcrypt = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0clhya4p8lhjj7hp31inp321wgzb0b5wbwppmya5sw1dikl7400z"; + type = "gem"; + }; + version = "3.1.22"; + }; + benchmark = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0v1337j39w1z7x9zs4q7ag0nfv4vs4xlsjx2la0wpv8s6hig2pa6"; + type = "gem"; + }; + version = "0.5.0"; + }; + bigbluebutton-api-ruby = { + dependencies = [ + "base64" + "xml-simple" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0iwklxlsl0bxdn7dc9inx7nhi6n5dmk0safbh2s1v03dh2v5w55l"; + type = "gem"; + }; + version = "2.0.0"; + }; + bigdecimal = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1jjlh2zkxdl4jm2xslmrmpgr3wqgxkd0qsrir01m590xjsmyy28w"; + type = "gem"; + }; + version = "4.1.1"; + }; + bindata = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0n4ymlgik3xcg94h52dzmh583ss40rl3sn0kni63v56sq8g6l62k"; + type = "gem"; + }; + version = "2.5.1"; + }; + bindex = { + groups = [ + "default" + "development" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0zmirr3m02p52bzq4xgksq4pn8j641rx5d4czk68pv9rqnfwq7kv"; + type = "gem"; + }; + version = "0.8.1"; + }; + bootsnap = { + dependencies = [ "msgpack" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1vcg52gwl64xhhal6kwk1pc01y1klzdlnv1awyk89kb91z010x7q"; + type = "gem"; + }; + version = "1.16.0"; + }; + builder = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0pw3r2lyagsxkm71bf44v5b74f7l9r7di22brbyji9fwz791hya9"; + type = "gem"; + }; + version = "3.3.0"; + }; + capybara = { + dependencies = [ + "addressable" + "matrix" + "mini_mime" + "nokogiri" + "rack" + "rack-test" + "regexp_parser" + "xpath" + ]; + groups = [ "test" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1vxfah83j6zpw3v5hic0j70h519nvmix2hbszmjwm8cfawhagns2"; + type = "gem"; + }; + version = "3.40.0"; + }; + case_transform = { + dependencies = [ "activesupport" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0fzyws6spn5arqf6q604dh9mrj84a36k5hsc8z7jgcpfvhc49bg2"; + type = "gem"; + }; + version = "0.2"; + }; + cgi = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1s8qdw1nfh3njd47q154njlfyc2llcgi4ik13vz39adqd7yclgz9"; + type = "gem"; + }; + version = "0.5.1"; + }; + clamby = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0ic994a40clll23i99fdp4aikhd4c6hhzr9m32wahnzv38i0hk1r"; + type = "gem"; + }; + version = "1.6.10"; + }; + concurrent-ruby = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1c2i64xsd35vijnb50rxb70g508s0x674xi0qpyyb8jy7bncl4j4"; + type = "gem"; + }; + version = "1.3.7"; + }; + connection_pool = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1b8nlxr5z843ii7hfk6igpr5acw3k2ih9yjrgkyz2gbmallgjkz5"; + type = "gem"; + }; + version = "2.5.5"; + }; + crack = { + dependencies = [ + "bigdecimal" + "rexml" + ]; + groups = [ + "default" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0jaa7is4fw1cxigm8vlyhg05bw4nqy4f91zjqxk7pp4c8bdyyfn8"; + type = "gem"; + }; + version = "1.0.0"; + }; + crass = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0pfl5c0pyqaparxaqxi6s4gfl21bdldwiawrc0aknyvflli60lfw"; + type = "gem"; + }; + version = "1.0.6"; + }; + cssbundling-rails = { + dependencies = [ "railties" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0hbfji8lddlvsk9x70s5xvafl3w31v6mm5wjrn7rrb14gmdcvbjk"; + type = "gem"; + }; + version = "1.4.3"; + }; + data_migrate = { + dependencies = [ + "activerecord" + "railties" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1ywg2qvpf1yxfbcdwmw2pl274i4bicjc4gsz6gaq5r0mklcb5f8q"; + type = "gem"; + }; + version = "11.3.1"; + }; + date = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ + { + engine = "maglev"; + } + { + engine = "mingw"; + } + { + engine = "mingw"; + } + { + engine = "ruby"; + } + ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1h0db8r2v5llxdbzkzyllkfniqw9gm092qn7cbaib73v9lw0c3bm"; + type = "gem"; + }; + version = "3.5.1"; + }; + debug = { + dependencies = [ + "irb" + "reline" + ]; + groups = [ + "development" + "test" + ]; + platforms = [ + { + engine = "maglev"; + } + { + engine = "mingw"; + } + { + engine = "mingw"; + } + { + engine = "ruby"; + } + ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1wmfy5n5v2rzpr5vz698sqfj1gl596bxrqw44sahq4x0rxjdn98l"; + type = "gem"; + }; + version = "1.11.0"; + }; + declarative = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1yczgnqrbls7shrg63y88g7wand2yp9h6sf56c9bdcksn5nds8c0"; + type = "gem"; + }; + version = "0.0.20"; + }; + diff-lcs = { + groups = [ + "default" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0qlrj2qyysc9avzlr4zs1py3x684hqm61n4czrsk1pyllz5x5q4s"; + type = "gem"; + }; + version = "1.6.2"; + }; + digest-crc = { + dependencies = [ "rake" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "01wcsyhaadss4zzvqh12kvbq3hmkl5y4fck7pr608hd24qxc5bb4"; + type = "gem"; + }; + version = "0.7.0"; + }; + dotenv = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "17b1zr9kih0i3wb7h4yq9i8vi6hjfq07857j437a8z7a44qvhxg3"; + type = "gem"; + }; + version = "3.2.0"; + }; + dotenv-rails = { + dependencies = [ + "dotenv" + "railties" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1axy0frn3xn3jf1gdafx5rzz843551q1ckwcbp4zy8m69dajazk5"; + type = "gem"; + }; + version = "3.2.0"; + }; + drb = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0wrkl7yiix268s2md1h6wh91311w95ikd8fy8m5gx589npyxc00b"; + type = "gem"; + }; + version = "2.2.3"; + }; + email_validator = { + dependencies = [ "activemodel" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0106y8xakq6frv2xc68zz76q2l2cqvhfjc7ji69yyypcbc4kicjs"; + type = "gem"; + }; + version = "2.2.4"; + }; + erb = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ + { + engine = "maglev"; + } + { + engine = "mingw"; + } + { + engine = "mingw"; + } + { + engine = "ruby"; + } + ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1faq0y37pmxiqz3illx82hmyl7jmzjprwxn5cx3akaaj0r35flyf"; + type = "gem"; + }; + version = "6.0.1.1"; + }; + erubi = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1naaxsqkv5b3vklab5sbb9sdpszrjzlfsbqpy7ncbnw510xi10m0"; + type = "gem"; + }; + version = "1.13.1"; + }; + factory_bot = { + dependencies = [ "activesupport" ]; + groups = [ "test" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0xz02xlnfhj418g51w06asfpcjccf7b66dx6ly3c1k2d45rv7ghj"; + type = "gem"; + }; + version = "6.5.6"; + }; + factory_bot_rails = { + dependencies = [ + "factory_bot" + "railties" + ]; + groups = [ "test" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0s3dpi8x754bwv4mlasdal8ffiahi4b4ajpccnkaipp4x98lik6k"; + type = "gem"; + }; + version = "6.5.1"; + }; + faker = { + dependencies = [ "i18n" ]; + groups = [ "test" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1b8772jybi0vxzbcs5zw17k40z661c8adn2rd6vqqr7ay71bzl09"; + type = "gem"; + }; + version = "3.1.1"; + }; + faraday = { + dependencies = [ + "faraday-net_http" + "json" + "logger" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0y7j6yzv07zggic6g0p2v1ivnvkzsbqjnfdl4215qqb6cxz290hq"; + type = "gem"; + }; + version = "2.14.3"; + }; + faraday-follow_redirects = { + dependencies = [ "faraday" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1nfmmnmqgbxci7dlca0qnwxn8j29yv7v8wm26m0f4l0kmcc13ynk"; + type = "gem"; + }; + version = "0.4.0"; + }; + faraday-net_http = { + dependencies = [ "net-http" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "125m3qri52vwh5v9dhq0dkqxf8629cxrf99yyc01pva72wasyy0f"; + type = "gem"; + }; + version = "3.4.4"; + }; + ffi = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "19kdyjg3kv7x0ad4xsd4swy5izsbb1vl1rpb6qqcqisr5s23awi9"; + type = "gem"; + }; + version = "1.17.2"; + }; + globalid = { + dependencies = [ "activesupport" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "04gzhqvsm4z4l12r9dkac9a75ah45w186ydhl0i4andldsnkkih5"; + type = "gem"; + }; + version = "1.3.0"; + }; + google-apis-core = { + dependencies = [ + "addressable" + "faraday" + "faraday-follow_redirects" + "googleauth" + "mini_mime" + "representable" + "retriable" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0a961x3jq0wskwgb8ym83viza05bcvsqiny8gg6dc0n9mnm7jids"; + type = "gem"; + }; + version = "1.0.2"; + }; + google-apis-iamcredentials_v1 = { + dependencies = [ "google-apis-core" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "18s8kshls6amld400434xgmgssn2y9fpqnz9ahjxzkfnl480mxrz"; + type = "gem"; + }; + version = "0.26.0"; + }; + google-apis-storage_v1 = { + dependencies = [ "google-apis-core" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0yinfpzcrb3pgddla99rslvqzd5isimbbb8n5a628i432avi29dd"; + type = "gem"; + }; + version = "0.60.0"; + }; + google-cloud-core = { + dependencies = [ + "google-cloud-env" + "google-cloud-errors" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1kw10897ardky1chwwsb8milygzcdi8qlqlhcnqwmkw9y75yswp5"; + type = "gem"; + }; + version = "1.8.0"; + }; + google-cloud-env = { + dependencies = [ + "base64" + "faraday" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1rvqj6n6qhjmjy0lynpmga7ly48s7dk36i6nj4jqrrvvn8gc1ahg"; + type = "gem"; + }; + version = "2.3.1"; + }; + google-cloud-errors = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0jvv9w8s4dqc4ncfa6c6qpdypz2wj8dmgpjd44jq2qhhij5y4sxm"; + type = "gem"; + }; + version = "1.5.0"; + }; + google-cloud-storage = { + dependencies = [ + "addressable" + "digest-crc" + "google-apis-core" + "google-apis-iamcredentials_v1" + "google-apis-storage_v1" + "google-cloud-core" + "googleauth" + "mini_mime" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1zfzix33r060ch1ms2g7m7zzjhgrp43d67fy3sg1dbvmkixc1v8v"; + type = "gem"; + }; + version = "1.58.0"; + }; + google-logging-utils = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0yyzlgy9hx104xhrbl51ana0dl3m5p5989j4lcjsizssxas64m37"; + type = "gem"; + }; + version = "0.2.0"; + }; + googleauth = { + dependencies = [ + "faraday" + "google-cloud-env" + "google-logging-utils" + "jwt" + "multi_json" + "os" + "signet" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "173h8r5dzhn4dvq2idx59jaybkhd02dr7333qshc3n2mkp76nxrn"; + type = "gem"; + }; + version = "1.16.1"; + }; + hashdiff = { + groups = [ + "default" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0xqsnx25lm1wwgchvrl5xla5zzk3d6gbkdfj062cwggdsvgfwc1c"; + type = "gem"; + }; + version = "1.1.2"; + }; + hashie = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1nh3arcrbz1rc1cr59qm53sdhqm137b258y8rcb4cvd3y98lwv4x"; + type = "gem"; + }; + version = "5.0.0"; + }; + hcaptcha = { + dependencies = [ "json" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0fh6391zlv2ikvzqj2gymb70k1avk1j9da8bzgw0scsz2wqq98m2"; + type = "gem"; + }; + version = "7.1.0"; + }; + i18n = { + dependencies = [ "concurrent-ruby" ]; + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1994i044vdmzzkyr76g8rpl1fq1532wf0sb21xg5r1ilj5iphmr8"; + type = "gem"; + }; + version = "1.14.8"; + }; + i18n-language-mapping = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0p1pidcl80iyqavbrlczh8dccpzgb489nbm40mxq2n5qjm07ysbx"; + type = "gem"; + }; + version = "0.1.3.1"; + }; + image_processing = { + dependencies = [ + "mini_magick" + "ruby-vips" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1f32dzj77p9mfp4q95930vfkp80psf88phjc46jhf9ncl72ykffk"; + type = "gem"; + }; + version = "1.12.2"; + }; + io-console = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ + { + engine = "maglev"; + } + { + engine = "mingw"; + } + { + engine = "mingw"; + } + { + engine = "ruby"; + } + ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1jszj95hazqqpnrjjzr326nn1j32xmsc9xvd97mbcrrgdc54858y"; + type = "gem"; + }; + version = "0.8.1"; + }; + irb = { + dependencies = [ + "pp" + "rdoc" + "reline" + ]; + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ + { + engine = "maglev"; + } + { + engine = "mingw"; + } + { + engine = "mingw"; + } + { + engine = "ruby"; + } + ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1aja320qnimlnfc80wf2i2x8i99kl5sdzfacsfzzfzzs3vzysja3"; + type = "gem"; + }; + version = "1.15.3"; + }; + jbuilder = { + dependencies = [ + "actionview" + "activesupport" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1mi7s8kida8rg754bzgiik2mpdwx55x7wxd9ny0sm0803j5a603j"; + type = "gem"; + }; + version = "2.13.0"; + }; + jmespath = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1cdw9vw2qly7q7r41s7phnac264rbsdqgj4l0h4nqgbjb157g393"; + type = "gem"; + }; + version = "1.6.2"; + }; + jsbundling-rails = { + dependencies = [ "railties" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1jn2n5i9qdw6iybb4f6gqkr7k61rafzdh8m0anzlqs8w0mnkz80g"; + type = "gem"; + }; + version = "1.3.1"; + }; + json = { + groups = [ + "default" + "development" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "16mp8vzgxa8nsa81np042za453j8b0ihpjkf666s7byxrnvjb44v"; + type = "gem"; + }; + version = "2.19.9"; + }; + json-jwt = { + dependencies = [ + "activesupport" + "aes_key_wrap" + "base64" + "bindata" + "faraday" + "faraday-follow_redirects" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1k64mp59jlbqd5hyy46pf93s3yl1xdngfy8i8flq2hn5nhk91ybg"; + type = "gem"; + }; + version = "1.17.0"; + }; + jsonapi-renderer = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0ys4drd0k9rw5ixf8n8fx8v0pjh792w4myh0cpdspd317l1lpi5m"; + type = "gem"; + }; + version = "0.2.2"; + }; + jwt = { + dependencies = [ "base64" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1mqps8z4ly74hpksfajcfamqk1wb79biy187pn10knmi6zzb26al"; + type = "gem"; + }; + version = "3.2.0"; + }; + language_server-protocol = { + groups = [ + "default" + "development" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1k0311vah76kg5m6zr7wmkwyk5p2f9d9hyckjpn3xgr83ajkj7px"; + type = "gem"; + }; + version = "3.17.0.5"; + }; + lint_roller = { + groups = [ + "default" + "development" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "11yc0d84hsnlvx8cpk4cbj6a4dz9pk0r1k29p0n1fz9acddq831c"; + type = "gem"; + }; + version = "1.1.0"; + }; + logger = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "00q2zznygpbls8asz5knjvvj2brr3ghmqxgr83xnrdj4rk3xwvhr"; + type = "gem"; + }; + version = "1.7.0"; + }; + lograge = { + dependencies = [ + "actionpack" + "activesupport" + "railties" + "request_store" + ]; + groups = [ "production" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1qcsvh9k4c0cp6agqm9a8m4x2gg7vifryqr7yxkg2x9ph9silds2"; + type = "gem"; + }; + version = "0.14.0"; + }; + loofah = { + dependencies = [ + "crass" + "nokogiri" + ]; + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "011fdngxzr1p9dq2hxqz7qq1glj2g44xnhaadjqlf48cplywfdnl"; + type = "gem"; + }; + version = "2.25.1"; + }; + mail = { + dependencies = [ + "logger" + "mini_mime" + "net-imap" + "net-pop" + "net-smtp" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0ha9sgkfqna62c1basc17dkx91yk7ppgjq32k4nhrikirlz6g9kg"; + type = "gem"; + }; + version = "2.9.0"; + }; + marcel = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1vhb1sbzlq42k2pzd9v0w5ws4kjx184y8h4d63296bn57jiwzkzx"; + type = "gem"; + }; + version = "1.1.0"; + }; + matrix = { + groups = [ + "default" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0nscas3a4mmrp1rc07cdjlbbpb2rydkindmbj3v3z5y1viyspmd0"; + type = "gem"; + }; + version = "0.4.3"; + }; + mini_magick = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0slh78f9z6n0l1i2km7m48yz7l4fjrk88sj1f4mh1wb39sl2yc37"; + type = "gem"; + }; + version = "4.12.0"; + }; + mini_mime = { + groups = [ + "default" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1vycif7pjzkr29mfk4dlqv3disc5dn0va04lkwajlpr1wkibg0c6"; + type = "gem"; + }; + version = "1.1.5"; + }; + mini_portile2 = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "12f2830x7pq3kj0v8nz0zjvaw02sv01bqs1zwdrc04704kwcgmqc"; + type = "gem"; + }; + version = "2.8.9"; + }; + minitest = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1mbpz92ml19rcxxfjrj91gmkif9khb1xpzyw38f81rvglgw1ffrd"; + type = "gem"; + }; + version = "5.27.0"; + }; + msgpack = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1q03pb0vq8388s431nbxabsfxnch6p304c8vnjlk0zzpcv713yr3"; + type = "gem"; + }; + version = "1.6.0"; + }; + multi_json = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1drisvysgvnjlz49a0qcbs294id6mvj3i8iik5rvym68ybwfzvvs"; + type = "gem"; + }; + version = "1.19.1"; + }; + net-http = { + dependencies = [ "uri" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "15k96fj6qwbaiv6g52l538ass95ds1qwgynqdridz29yqrkhpfi5"; + type = "gem"; + }; + version = "0.9.1"; + }; + net-imap = { + dependencies = [ + "date" + "net-protocol" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0506bhwr62szwcagcvxayhwz0d20k5ax1sh742va3mjnnkqcfkgn"; + type = "gem"; + }; + version = "0.5.15"; + }; + net-pop = { + dependencies = [ "net-protocol" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1wyz41jd4zpjn0v1xsf9j778qx1vfrl24yc20cpmph8k42c4x2w4"; + type = "gem"; + }; + version = "0.1.2"; + }; + net-protocol = { + dependencies = [ "timeout" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1a32l4x73hz200cm587bc29q8q9az278syw3x6fkc9d1lv5y0wxa"; + type = "gem"; + }; + version = "0.2.2"; + }; + net-smtp = { + dependencies = [ "net-protocol" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0dh7nzjp0fiaqq1jz90nv4nxhc2w359d7c199gmzq965cfps15pd"; + type = "gem"; + }; + version = "0.5.1"; + }; + nio4r = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "18fwy5yqnvgixq3cn0h63lm8jaxsjjxkmj8rhiv8wpzv9271d43c"; + type = "gem"; + }; + version = "2.7.5"; + }; + nkf = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "09piyp2pd74klb9wcn0zw4mb5l0k9wzwppxggxi1yi95l2ym3hgv"; + type = "gem"; + }; + version = "0.2.0"; + }; + nokogiri = { + dependencies = [ + "mini_portile2" + "racc" + ]; + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1d9safb4dly6qmc2g06444l0zifby52yy6j1a5fa1g4j3ihm3jah"; + type = "gem"; + }; + version = "1.19.4"; + }; + omniauth = { + dependencies = [ + "hashie" + "logger" + "rack" + "rack-protection" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0g3n12k5npmmgai2cs3snimy6r7h0bvalhjxv0fjxlphjq25p822"; + type = "gem"; + }; + version = "2.1.4"; + }; + omniauth-rails_csrf_protection = { + dependencies = [ + "actionpack" + "omniauth" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0cdr13881iq087bq30xg7k9hr1i6ffl8sjf63fyj3f712qvy90xx"; + type = "gem"; + }; + version = "2.0.0"; + }; + omniauth_openid_connect = { + dependencies = [ + "omniauth" + "openid_connect" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "099xg7s6450wlfzs77mbdx78g3dp0glx5q6f44i78akf7283hbqz"; + type = "gem"; + }; + version = "0.8.0"; + }; + openid_connect = { + dependencies = [ + "activemodel" + "attr_required" + "email_validator" + "faraday" + "faraday-follow_redirects" + "json-jwt" + "mail" + "rack-oauth2" + "swd" + "tzinfo" + "validate_url" + "webfinger" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "10i13cn40jiiw8lslkv7bj1isinnwbmzlk6msgiph3gqry08702x"; + type = "gem"; + }; + version = "2.3.1"; + }; + os = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0gwd20smyhxbm687vdikfh1gpi96h8qb1x28s2pdcysf6dm6v0ap"; + type = "gem"; + }; + version = "1.1.4"; + }; + pagy = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "06vk6hcp8jfijksf0rfmr47la87raw19mr9gmsp3a112nhi75pvz"; + type = "gem"; + }; + version = "6.0.4"; + }; + parallel = { + groups = [ + "default" + "development" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0c719bfgcszqvk9z47w2p8j2wkz5y35k48ywwas5yxbbh3hm3haa"; + type = "gem"; + }; + version = "1.27.0"; + }; + parser = { + dependencies = [ + "ast" + "racc" + ]; + groups = [ + "default" + "development" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1mmb59323ldv6vxfmy98azgsla9k3di3fasvpb28hnn5bkx8fdff"; + type = "gem"; + }; + version = "3.3.10.0"; + }; + pg = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1wd6nl81nbdwck04hccsm7wf23ghpi8yddd9j4rbwyvyj0sbsff1"; + type = "gem"; + }; + version = "1.4.5"; + }; + pp = { + dependencies = [ "prettyprint" ]; + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ + { + engine = "maglev"; + } + { + engine = "mingw"; + } + { + engine = "mingw"; + } + { + engine = "ruby"; + } + ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1xlxmg86k5kifci1xvlmgw56x88dmqf04zfzn7zcr4qb8ladal99"; + type = "gem"; + }; + version = "0.6.3"; + }; + prettyprint = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ + { + engine = "maglev"; + } + { + engine = "mingw"; + } + { + engine = "mingw"; + } + { + engine = "ruby"; + } + ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "14zicq3plqi217w6xahv7b8f7aj5kpxv1j1w98344ix9h5ay3j9b"; + type = "gem"; + }; + version = "0.2.0"; + }; + prism = { + groups = [ + "default" + "development" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0sqwckzzpj1mmmjnqcvqmq6adlxbhkf5ij3b6ir4i33ih4d2ih5z"; + type = "gem"; + }; + version = "1.6.0"; + }; + psych = { + dependencies = [ + "date" + "stringio" + ]; + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ + { + engine = "maglev"; + } + { + engine = "mingw"; + } + { + engine = "mingw"; + } + { + engine = "ruby"; + } + ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0vii1xc7x81hicdbp7dlllhmbw5w3jy20shj696n0vfbbnm2hhw1"; + type = "gem"; + }; + version = "5.2.6"; + }; + public_suffix = { + groups = [ + "default" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "08znfv30pxmdkjyihvbjqbvv874dj3nybmmyscl958dy3f7v12qs"; + type = "gem"; + }; + version = "7.0.5"; + }; + puma = { + dependencies = [ "nio4r" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1c0l2jb2d75zdw7diqhh6sciwlxcwfacshp107af0cnmmff0xgyp"; + type = "gem"; + }; + version = "7.2.1"; + }; + racc = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0byn0c9nkahsl93y9ln5bysq4j31q8xkf2ws42swighxd4lnjzsa"; + type = "gem"; + }; + version = "1.8.1"; + }; + rack = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1hhjy9gcp52dzij05gmidqac8g28ski5xm67prwmdqmjfcgqxmsy"; + type = "gem"; + }; + version = "3.2.6"; + }; + rack-oauth2 = { + dependencies = [ + "activesupport" + "attr_required" + "faraday" + "faraday-follow_redirects" + "json-jwt" + "rack" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0cn6a9v8nry9fx4zrzp1xakfp2n5xv5075j90q56m20k7zvjrq23"; + type = "gem"; + }; + version = "2.3.0"; + }; + rack-protection = { + dependencies = [ + "base64" + "logger" + "rack" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1b4bamcbpk29i7jvly3i7ayfj69yc1g03gm4s7jgamccvx12hvng"; + type = "gem"; + }; + version = "4.2.1"; + }; + rack-session = { + dependencies = [ + "base64" + "rack" + ]; + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1s7zcxlmg88a6dam4aqbgk9xkpy6dkdfqmmcszkkliy3q3w38m2r"; + type = "gem"; + }; + version = "2.1.2"; + }; + rack-test = { + dependencies = [ "rack" ]; + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0qy4ylhcfdn65a5mz2hly7g9vl0g13p5a0rmm6sc0sih5ilkcnh0"; + type = "gem"; + }; + version = "2.2.0"; + }; + rackup = { + dependencies = [ "rack" ]; + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "13brkq5xkj6lcdxj3f0k7v28hgrqhqxjlhd4y2vlicy5slgijdzp"; + type = "gem"; + }; + version = "2.2.1"; + }; + rails = { + dependencies = [ + "actioncable" + "actionmailbox" + "actionmailer" + "actionpack" + "actiontext" + "actionview" + "activejob" + "activemodel" + "activerecord" + "activestorage" + "activesupport" + "railties" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "155skqkjrckvzj1qy37lrnafrillc47qhf3l80g3zvw100ba1h4n"; + type = "gem"; + }; + version = "7.2.3.1"; + }; + rails-dom-testing = { + dependencies = [ + "activesupport" + "minitest" + "nokogiri" + ]; + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "07awj8bp7jib54d0khqw391ryw8nphvqgw4bb12cl4drlx9pkk4a"; + type = "gem"; + }; + version = "2.3.0"; + }; + rails-html-sanitizer = { + dependencies = [ + "loofah" + "nokogiri" + ]; + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "128y5g3fyi8fds41jasrr4va1jrs7hcamzklk1523k7rxb64bc98"; + type = "gem"; + }; + version = "1.7.0"; + }; + railties = { + dependencies = [ + "actionpack" + "activesupport" + "cgi" + "irb" + "rackup" + "rake" + "thor" + "tsort" + "zeitwerk" + ]; + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0np1m8xqb4wbzwpg66yjnqjban0di92lbjzcrgnwwhq2w4z3k8xf"; + type = "gem"; + }; + version = "7.2.3.1"; + }; + rainbow = { + groups = [ + "default" + "development" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0smwg4mii0fm38pyb5fddbmrdpifwv22zv3d3px2xx497am93503"; + type = "gem"; + }; + version = "3.1.1"; + }; + rake = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "175iisqb211n0qbfyqd8jz2g01q6xj038zjf4q0nm8k6kz88k7lc"; + type = "gem"; + }; + version = "13.3.1"; + }; + rdoc = { + dependencies = [ + "erb" + "psych" + "tsort" + ]; + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ + { + engine = "maglev"; + } + { + engine = "mingw"; + } + { + engine = "mingw"; + } + { + engine = "ruby"; + } + ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0p4z1cs2zvkkvl0xiiy76ys1ipbhx0df15241jx7gnp61317qdbi"; + type = "gem"; + }; + version = "6.16.1"; + }; + redis = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0i4a8hxxcxci3n8hhlm9a8wa7a9m58r6sjvh4749v7362i8cy010"; + type = "gem"; + }; + version = "4.8.0"; + }; + regexp_parser = { + groups = [ + "default" + "development" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "192mzi0wgwl024pwpbfa6c2a2xlvbh3mjd75a0sakdvkl60z64ya"; + type = "gem"; + }; + version = "2.11.3"; + }; + reline = { + dependencies = [ "io-console" ]; + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ + { + engine = "maglev"; + } + { + engine = "mingw"; + } + { + engine = "mingw"; + } + { + engine = "ruby"; + } + ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0d8q5c4nh2g9pp758kizh8sfrvngynrjlm0i1zn3cnsnfd4v160i"; + type = "gem"; + }; + version = "0.6.3"; + }; + remote_syslog_logger = { + dependencies = [ "syslog_protocol" ]; + groups = [ "production" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1g8h2rfw80ay5yqaj8wddagpagpznk403pxnw6wcxvazrwqcb9h2"; + type = "gem"; + }; + version = "1.0.4"; + }; + representable = { + dependencies = [ + "declarative" + "trailblazer-option" + "uber" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1kms3r6w6pnryysnaqqa9fsn0v73zx1ilds9d1c565n3xdzbyafc"; + type = "gem"; + }; + version = "3.2.0"; + }; + request_store = { + dependencies = [ "rack" ]; + groups = [ + "default" + "production" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "13ppgmsbrqah08j06bybd3cddv6dml79yzyjn7r8j1src78h98h7"; + type = "gem"; + }; + version = "1.5.1"; + }; + retriable = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1q48hqws2dy1vws9schc0kmina40gy7sn5qsndpsfqdslh65snha"; + type = "gem"; + }; + version = "3.1.2"; + }; + rexml = { + groups = [ + "default" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0hninnbvqd2pn40h863lbrn9p11gvdxp928izkag5ysx8b1s5q0r"; + type = "gem"; + }; + version = "3.4.4"; + }; + rspec-core = { + dependencies = [ "rspec-support" ]; + groups = [ + "default" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0bcbh9yv6cs6pv299zs4bvalr8yxa51kcdd1pjl60yv625j3r0m8"; + type = "gem"; + }; + version = "3.13.6"; + }; + rspec-expectations = { + dependencies = [ + "diff-lcs" + "rspec-support" + ]; + groups = [ + "default" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0dl8npj0jfpy31bxi6syc7jymyd861q277sfr6jawq2hv6hx791k"; + type = "gem"; + }; + version = "3.13.5"; + }; + rspec-mocks = { + dependencies = [ + "diff-lcs" + "rspec-support" + ]; + groups = [ + "default" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "071bqrk2rblk3zq3jk1xxx0dr92y0szi5pxdm8waimxici706y89"; + type = "gem"; + }; + version = "3.13.7"; + }; + rspec-rails = { + dependencies = [ + "actionpack" + "activesupport" + "railties" + "rspec-core" + "rspec-expectations" + "rspec-mocks" + "rspec-support" + ]; + groups = [ "test" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0cg3ay2jin7jv20carhx3icv3gnwka0hqcr15zcjy7i1xnmwqpg1"; + type = "gem"; + }; + version = "7.1.1"; + }; + rspec-support = { + groups = [ + "default" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1cmgz34hwj5s3jwxhyl8mszs24nci12ffbrmr5jb1si74iqf739f"; + type = "gem"; + }; + version = "3.13.6"; + }; + rubocop = { + dependencies = [ + "json" + "language_server-protocol" + "lint_roller" + "parallel" + "parser" + "rainbow" + "regexp_parser" + "rubocop-ast" + "ruby-progressbar" + "unicode-display_width" + ]; + groups = [ "development" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "157hg99cq6ys670sw8xbggnvxc9yl50h1zhllki925kkihlwrdbg"; + type = "gem"; + }; + version = "1.81.7"; + }; + rubocop-ast = { + dependencies = [ + "parser" + "prism" + ]; + groups = [ + "default" + "development" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0xifbp09jfl1hdy9wwgq9dq2l7mf8y2ycm5d1zgcqvks7yzrppr2"; + type = "gem"; + }; + version = "1.48.0"; + }; + rubocop-capybara = { + dependencies = [ "rubocop" ]; + groups = [ "development" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1jwwi5a05947q9zsk6i599zxn657hdphbmmbbpx17qsv307rwcps"; + type = "gem"; + }; + version = "2.19.0"; + }; + rubocop-factory_bot = { + dependencies = [ "rubocop" ]; + groups = [ "development" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1y79flwjwlaslyhfpg84di9n756ir6bm52n964620xsj658d661h"; + type = "gem"; + }; + version = "2.24.0"; + }; + rubocop-performance = { + dependencies = [ + "rubocop" + "rubocop-ast" + ]; + groups = [ "development" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1n7g0vg06ldjaq4f8c11c7yqy99zng1qdrkkk4kfziippy24yxnc"; + type = "gem"; + }; + version = "1.16.0"; + }; + rubocop-rails = { + dependencies = [ + "activesupport" + "lint_roller" + "rack" + "rubocop" + "rubocop-ast" + ]; + groups = [ "development" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "08kf3nhhhxcwb9shb4bv7jxr1mjrs63fwpywppmgy9cbwip29zqh"; + type = "gem"; + }; + version = "2.34.2"; + }; + rubocop-rspec = { + dependencies = [ "rubocop" ]; + groups = [ "development" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "051gq9pz49iv4gq34d3n089iaa6cb418n2fhin6gd6fpysbi3nf6"; + type = "gem"; + }; + version = "2.9.0"; + }; + ruby-progressbar = { + groups = [ + "default" + "development" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0cwvyb7j47m7wihpfaq7rc47zwwx9k4v7iqd9s1xch5nm53rrz40"; + type = "gem"; + }; + version = "1.13.0"; + }; + ruby-vips = { + dependencies = [ "ffi" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "19pzpx406rr9s3qk527rn9y3b76sjq5pi7y0xzqiy50q3k0hhg7g"; + type = "gem"; + }; + version = "2.1.4"; + }; + rubyzip = { + groups = [ + "default" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "05an0wz87vkmqwcwyh5rjiaavydfn5f4q1lixcsqkphzvj7chxw5"; + type = "gem"; + }; + version = "2.4.1"; + }; + securerandom = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1cd0iriqfsf1z91qg271sm88xjnfd92b832z49p1nd542ka96lfc"; + type = "gem"; + }; + version = "0.4.1"; + }; + selenium-webdriver = { + dependencies = [ + "rexml" + "rubyzip" + "websocket" + ]; + groups = [ "test" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1dkcyq2hfvf4wdj7q5cqqlka1dw6gz28dckxf4r17jmd53ymwg28"; + type = "gem"; + }; + version = "4.8.0"; + }; + shoulda-matchers = { + dependencies = [ "activesupport" ]; + groups = [ "test" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "11igjgh16dl5pwqizdmclzlzpv7mbmnh8fx7m9b5kfsjhwxqdfpn"; + type = "gem"; + }; + version = "5.3.0"; + }; + signet = { + dependencies = [ + "addressable" + "faraday" + "jwt" + "multi_json" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0nydm087m5c3j85gvzvz30w1qb9pl2lzpznw746jha29ybxyj5yn"; + type = "gem"; + }; + version = "0.21.0"; + }; + sprockets = { + dependencies = [ + "concurrent-ruby" + "logger" + "rack" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1car3fpzhn1l06x2zmanz2l4bj346mv3jcgpcd3p1262y54ml7kn"; + type = "gem"; + }; + version = "4.2.2"; + }; + sprockets-rails = { + dependencies = [ + "actionpack" + "activesupport" + "sprockets" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "17hiqkdpcjyyhlm997mgdcr45v35j5802m5a979i5jgqx5n8xs59"; + type = "gem"; + }; + version = "3.5.2"; + }; + stringio = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ + { + engine = "maglev"; + } + { + engine = "mingw"; + } + { + engine = "mingw"; + } + { + engine = "ruby"; + } + ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "08aii379my5zvk0jb3nb50yx321pz7n5a9mwlfbangm7sc9sy4f1"; + type = "gem"; + }; + version = "3.1.9"; + }; + swd = { + dependencies = [ + "activesupport" + "attr_required" + "faraday" + "faraday-follow_redirects" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0m86fzmwgw0vc8p6fwvnsdbldpgbqdz9cbp2zj9z06bc4jjf5nsc"; + type = "gem"; + }; + version = "2.0.3"; + }; + syslog_protocol = { + groups = [ + "default" + "production" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1yb2cmbyj0zmb2yhkgnmghcngrkhcxs4g1svcmgfj90l2hs23nmc"; + type = "gem"; + }; + version = "0.9.2"; + }; + thor = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0gcarlmpfbmqnjvwfz44gdjhcmm634di7plcx2zdgwdhrhifhqw7"; + type = "gem"; + }; + version = "1.4.0"; + }; + timeout = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1jxcji88mh6xsqz0mfzwnxczpg7cyniph7wpavnavfz7lxl77xbq"; + type = "gem"; + }; + version = "0.6.1"; + }; + trailblazer-option = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "18s48fndi2kfvrfzmq6rxvjfwad347548yby0341ixz1lhpg3r10"; + type = "gem"; + }; + version = "0.1.2"; + }; + tsort = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ + { + engine = "maglev"; + } + { + engine = "mingw"; + } + { + engine = "mingw"; + } + { + engine = "ruby"; + } + ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "17q8h020dw73wjmql50lqw5ddsngg67jfw8ncjv476l5ys9sfl4n"; + type = "gem"; + }; + version = "0.2.0"; + }; + tzinfo = { + dependencies = [ "concurrent-ruby" ]; + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "16w2g84dzaf3z13gxyzlzbf748kylk5bdgg3n1ipvkvvqy685bwd"; + type = "gem"; + }; + version = "2.0.6"; + }; + uber = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1p1mm7mngg40x05z52md3mbamkng0zpajbzqjjwmsyw0zw3v9vjv"; + type = "gem"; + }; + version = "0.1.0"; + }; + unicode-display_width = { + dependencies = [ "unicode-emoji" ]; + groups = [ + "default" + "development" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0hiwhnqpq271xqari6mg996fgjps42sffm9cpk6ljn8sd2srdp8c"; + type = "gem"; + }; + version = "3.2.0"; + }; + unicode-emoji = { + groups = [ + "default" + "development" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1995yfjbvjlwrslq48gzzc9j0blkdzlbda9h90pjbm0yvzax55s9"; + type = "gem"; + }; + version = "4.1.0"; + }; + uri = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "1ijpbj7mdrq7rhpq2kb51yykhrs2s54wfs6sm9z3icgz4y6sb7rp"; + type = "gem"; + }; + version = "1.1.1"; + }; + useragent = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0i1q2xdjam4d7gwwc35lfnz0wyyzvnca0zslcfxm9fabml9n83kh"; + type = "gem"; + }; + version = "0.16.11"; + }; + validate_url = { + dependencies = [ + "activemodel" + "public_suffix" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0lblym140w5n88ijyfgcvkxvpfj8m6z00rxxf2ckmmhk0x61dzkj"; + type = "gem"; + }; + version = "1.0.15"; + }; + web-console = { + dependencies = [ + "actionview" + "activemodel" + "bindex" + "railties" + ]; + groups = [ "development" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "087y4byl2s3fg0nfhix4s0r25cv1wk7d2j8n5324waza21xg7g77"; + type = "gem"; + }; + version = "4.2.1"; + }; + webdrivers = { + dependencies = [ + "nokogiri" + "rubyzip" + "selenium-webdriver" + ]; + groups = [ "test" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0nxk9719nyk7vsc15mz2hxc8whciihcs40skpn2rncnzsppbv1w3"; + type = "gem"; + }; + version = "5.2.0"; + }; + webfinger = { + dependencies = [ + "activesupport" + "faraday" + "faraday-follow_redirects" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0p39802sfnm62r4x5hai8vn6d1wqbxsxnmbynsk8rcvzwyym4yjn"; + type = "gem"; + }; + version = "2.1.3"; + }; + webmock = { + dependencies = [ + "addressable" + "crack" + "hashdiff" + ]; + groups = [ "test" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "08kixkdp41dw39kqfxf2wp5m4z9b6fxg6yfa6xin0wy7dxzka0dy"; + type = "gem"; + }; + version = "3.24.0"; + }; + websocket = { + groups = [ + "default" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0dib6p55sl606qb4vpwrvj5wh881kk4aqn2zpfapf8ckx7g14jw8"; + type = "gem"; + }; + version = "1.2.9"; + }; + websocket-driver = { + dependencies = [ + "base64" + "websocket-extensions" + ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "15idgibqpdaj97f734drx8a7k1jcc8wvxlk2nbafac72ihikicjs"; + type = "gem"; + }; + version = "0.8.1"; + }; + websocket-extensions = { + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0hc2g9qps8lmhibl5baa91b4qx8wqw872rgwagml78ydj8qacsqw"; + type = "gem"; + }; + version = "0.1.5"; + }; + xml-simple = { + dependencies = [ "rexml" ]; + groups = [ "default" ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0pb9plyl71mdbjr4kllfy53qx6g68ryxblmnq9dilvy837jk24fj"; + type = "gem"; + }; + version = "1.1.9"; + }; + xpath = { + dependencies = [ "nokogiri" ]; + groups = [ + "default" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "0bh8lk9hvlpn7vmi6h4hkcwjzvs2y0cmkk3yjjdr8fxvj6fsgzbd"; + type = "gem"; + }; + version = "3.2.0"; + }; + zeitwerk = { + groups = [ + "default" + "development" + "production" + "test" + ]; + platforms = [ ]; + source = { + remotes = [ "https://rubygems.org" ]; + sha256 = "119ypabas886gd0n9kiid3q41w76gz60s8qmiak6pljpkd56ps5j"; + type = "gem"; + }; + version = "2.7.3"; + }; +} diff --git a/pkgs/by-name/gr/greenlight/package.nix b/pkgs/by-name/gr/greenlight/package.nix new file mode 100644 index 000000000000..f7f9609a6e04 --- /dev/null +++ b/pkgs/by-name/gr/greenlight/package.nix @@ -0,0 +1,119 @@ +{ + lib, + stdenv, + fetchFromGitHub, + bundlerEnv, + fetchNpmDeps, + nodejs_26, + npmHooks, + ruby_3_3, + makeWrapper, + which, + nixosTests, + nix-update-script, + _experimental-update-script-combinators, +}: + +let + ruby = ruby_3_3; + nodejs = nodejs_26; +in +stdenv.mkDerivation (finalAttrs: { + pname = "greenlight"; + version = "3.8.2.4"; + + __structuredAttrs = true; + strictDeps = true; + + src = fetchFromGitHub { + owner = "bigbluebutton"; + repo = "greenlight"; + tag = "release-${finalAttrs.version}"; + hash = "sha256-GOgOEP6dx1E/rIe4HBR35TM294ad8ywcBXVea1xFOag="; + }; + + patches = [ + # Expose further Rails development configurations as env vars + ./expose_rails_dev_configs.patch + ]; + + postPatch = '' + # jsbundling-rails dependency would executes yarn install but + # we'll stick with npm + rm -f yarn.lock + + substituteInPlace "config/storage.yml" --replace-fail \ + 'root: <%= Rails.root.join("storage") %>' \ + 'root: "/var/lib/greenlight/storage"' + + substituteInPlace "config/environments/development.rb" --replace-fail \ + ' config.hosts = nil' \ + ' config.hosts = nil; config.paths["log"] = ["/var/log/greenlight/development.log"]' + ''; + + nativeBuildInputs = [ + makeWrapper + which + nodejs + npmHooks.npmConfigHook + finalAttrs.rubyEnv.wrappedRuby + ]; + + npmDeps = fetchNpmDeps { + inherit (finalAttrs) src; + hash = "sha256-aTDd6+mc3DIE5FiaPVjjorJ0r8RfodhEVCs3o2zHbZk="; + }; + + rubyEnv = bundlerEnv { + name = "greenlight-env-${finalAttrs.version}"; + inherit ruby; + gemfile = "${finalAttrs.src}/Gemfile"; + # Manually need to remove platform not supported by bundix + # See https://github.com/bigbluebutton/greenlight/pull/6317 + lockfile = ./Gemfile.lock; + gemset = ./gemset.nix; + groups = [ "production" ]; + }; + makeCacheWritable = true; + + buildPhase = '' + runHook preBuild + + export BUNDLE_WITHOUT=development:test + export SECRET_KEY_BASE=1 + bundle exec rails assets:precompile + + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + + mkdir -p $out/share/greenlight $out/bin + cp -r app bin config config.ru db lib public vendor Gemfile Gemfile.lock Rakefile $out/share/greenlight/ + ln -s $out/share/greenlight/lib $out/lib + ln -s $out/share/greenlight/bin $out/bin + ln -sf /tmp $out/share/greenlight/tmp + + runHook postInstall + ''; + + passthru = { + inherit (finalAttrs) rubyEnv; + tests = { inherit (nixosTests) greenlight; }; + # run with: nix-shell ./maintainers/scripts/update.nix --argstr package greenlight + updateScript = _experimental-update-script-combinators.sequence [ + (nix-update-script { }) + ./update.sh + ]; + }; + + meta = { + description = "End-user web interface for BigBlueButton server"; + homepage = "https://github.com/bigbluebutton/greenlight"; + platforms = lib.platforms.linux; + license = lib.licenses.lgpl3Only; + maintainers = [ lib.maintainers.onny ]; + teams = [ lib.teams.ngi ]; + }; +}) diff --git a/pkgs/by-name/gr/greenlight/update.sh b/pkgs/by-name/gr/greenlight/update.sh new file mode 100755 index 000000000000..163488e6ba33 --- /dev/null +++ b/pkgs/by-name/gr/greenlight/update.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i bash -p bundix ruby_3_3 nixfmt +set -eu -o pipefail +set -x +dir="$(dirname "$(readlink -f "$0")")" + +# nix-update-script already bumped src.tag/hash before this runs. +# Just regenerate the gem lockfiles for the current (already-updated) source. +repo=$(mktemp -d /tmp/greenlight-update.XXX) +rm -f "$dir/gemset.nix" "$dir/Gemfile.lock" +greenlight_storepath=$(nix build --no-link --print-out-paths -f . greenlight.src) +cp -r --no-preserve=mode,ownership "$greenlight_storepath/." "$repo/" + +# remove binary platform otherwise building will fail +# see https://github.com/bigbluebutton/greenlight/pull/6317 +BUNDLE_GEMFILE="$repo/Gemfile" bundler lock --remove-platform x86_64-linux --lockfile="$repo/Gemfile.lock" +bundix --lock --lockfile="$repo/Gemfile.lock" --gemfile="$repo/Gemfile" --gemset="$dir/gemset.nix" + +cp "$repo/Gemfile.lock" "$dir/" +nixfmt "$dir/gemset.nix"