From 67dd26ca9d19daded279b7fe9f45227aa8c63e16 Mon Sep 17 00:00:00 2001 From: Celina Lopez Date: Wed, 25 Sep 2024 13:52:06 -0700 Subject: [PATCH] Initial commit --- .dockerignore | 11 + .foreman | 1 + .github/dependabot.yml | 12 + .github/workflows/ci.yml | 101 +++ .gitignore | 6 +- .rubocop.yml | 8 + .ruby-version | 2 +- Dockerfile | 35 +- Gemfile | 147 ++-- Gemfile.lock | 593 ++++----------- Procfile | 2 +- Procfile.dev | 2 +- app/assets/config/manifest.js | 2 +- .../stylesheets/jumpstart/announcements.scss | 21 + app/channels/application_cable/connection.rb | 17 + app/controllers/announcements_controller.rb | 13 + app/controllers/application_controller.rb | 13 + app/controllers/home_controller.rb | 10 + .../madmin/impersonates_controller.rb | 14 + app/controllers/notifications_controller.rb | 7 + .../users/omniauth_callbacks_controller.rb | 84 +++ app/helpers/announcements_helper.rb | 19 + app/helpers/avatar_helper.rb | 17 + app/helpers/bootstrap_helper.rb | 10 + app/javascript/application.js | 28 + app/javascript/channels/consumer.js | 6 - app/javascript/channels/index.js | 5 - app/javascript/controllers/index.js | 6 + app/javascript/packs/application.js | 13 - app/models/announcement.rb | 23 +- app/models/cluster.rb | 21 - app/models/service.rb | 59 +- app/models/user.rb | 34 +- app/views/announcements/index.html.erb | 28 + app/views/devise/confirmations/new.html.erb | 22 + .../mailer/confirmation_instructions.html.erb | 5 + .../devise/mailer/email_changed.html.erb | 7 + .../devise/mailer/password_change.html.erb | 3 + .../reset_password_instructions.html.erb | 8 + .../mailer/unlock_instructions.html.erb | 7 + app/views/devise/passwords/edit.html.erb | 29 + app/views/devise/passwords/new.html.erb | 20 + app/views/devise/registrations/edit.html.erb | 49 ++ app/views/devise/registrations/new.html.erb | 33 + app/views/devise/sessions/new.html.erb | 32 + .../devise/shared/_error_messages.html.erb | 15 + app/views/devise/shared/_links.html.erb | 25 + app/views/devise/unlocks/new.html.erb | 20 + app/views/home/index.html.erb | 2 + app/views/home/privacy.html.erb | 2 + app/views/home/terms.html.erb | 2 + app/views/layouts/application.html.erb | 23 +- app/views/notifications/index.html.erb | 10 + app/views/pwa/manifest.json.erb | 22 + app/views/pwa/service-worker.js | 26 + app/views/shared/_footer.html.erb | 10 + app/views/shared/_head.html.erb | 10 + app/views/shared/_navbar.html.erb | 52 ++ app/views/shared/_notices.html.erb | 8 + bin/brakeman | 7 + bin/docker-entrypoint | 5 + bin/jobs | 6 - bin/rubocop | 8 + bin/setup | 6 +- bin/spring | 14 - bin/yarn | 17 - config/application.rb | 10 +- config/cable.yml | 9 +- config/credentials.yml.enc | 2 +- config/database.yml | 13 +- config/environments/development.rb | 24 +- config/environments/production.rb | 11 +- config/environments/test.rb | 13 +- .../application_controller_renderer.rb | 8 - config/initializers/assets.rb | 2 +- config/initializers/backtrace_silencers.rb | 8 - config/initializers/cookies_serializer.rb | 5 - config/initializers/devise.rb | 4 +- .../initializers/filter_parameter_logging.rb | 2 +- config/initializers/mime_types.rb | 4 - config/initializers/wrap_parameters.rb | 14 - config/puma.rb | 60 +- config/queue.yml | 18 - config/recurring.yml | 9 - config/routes.rb | 26 +- config/solid_queue.yml | 18 - config/spring.rb | 6 - db/migrate/20240925185426_create_clusters.rb | 11 - ... => 20240925205144_devise_create_users.rb} | 2 +- ...=> 20240925205147_create_announcements.rb} | 2 +- ...25205148_create_noticed_tables.noticed.rb} | 0 ...cations_count_to_noticed_event.noticed.rb} | 0 ...s.rb => 20240925205150_create_services.rb} | 2 +- ...0240925205151_create_friendly_id_slugs.rb} | 0 ...e_active_storage_tables.active_storage.rb} | 2 +- db/queue_schema.rb | 129 ---- db/schema.rb | 132 ---- esbuild.config.mjs | 96 +++ lib/tasks/auto_annotate_models.rake | 59 -- lib/templates/erb/scaffold/_form.html.erb | 50 ++ lib/templates/erb/scaffold/edit.html.erb | 3 + lib/templates/erb/scaffold/index.html.erb | 51 ++ lib/templates/erb/scaffold/new.html.erb | 3 + lib/templates/erb/scaffold/show.html.erb | 16 + package.json | 40 +- public/406-unsupported-browser.html | 66 ++ public/apple-touch-icon-precomposed.png | 0 public/apple-touch-icon.png | 0 public/favicon.ico | 0 public/icon.png | Bin 0 -> 5599 bytes public/icon.svg | 3 + test/application_system_test_case.rb | 2 +- test/fixtures/announcements.yml | 17 +- test/fixtures/clusters.yml | 29 - test/fixtures/services.yml | 29 +- test/fixtures/users.yml | 23 +- test/models/announcement_test.rb | 12 - test/models/cluster_test.rb | 26 - test/models/service_test.rb | 24 - test/models/user_test.rb | 22 - yarn.lock | 677 +++++++++++++++++- 121 files changed, 2254 insertions(+), 1415 deletions(-) create mode 100644 .foreman create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .rubocop.yml create mode 100644 app/assets/stylesheets/jumpstart/announcements.scss create mode 100644 app/controllers/announcements_controller.rb create mode 100644 app/controllers/home_controller.rb create mode 100644 app/controllers/madmin/impersonates_controller.rb create mode 100644 app/controllers/notifications_controller.rb create mode 100644 app/controllers/users/omniauth_callbacks_controller.rb create mode 100644 app/helpers/announcements_helper.rb create mode 100644 app/helpers/avatar_helper.rb create mode 100644 app/helpers/bootstrap_helper.rb create mode 100644 app/javascript/application.js delete mode 100644 app/javascript/channels/consumer.js delete mode 100644 app/javascript/channels/index.js create mode 100644 app/javascript/controllers/index.js delete mode 100644 app/javascript/packs/application.js delete mode 100644 app/models/cluster.rb create mode 100644 app/views/announcements/index.html.erb create mode 100644 app/views/devise/confirmations/new.html.erb create mode 100644 app/views/devise/mailer/confirmation_instructions.html.erb create mode 100644 app/views/devise/mailer/email_changed.html.erb create mode 100644 app/views/devise/mailer/password_change.html.erb create mode 100644 app/views/devise/mailer/reset_password_instructions.html.erb create mode 100644 app/views/devise/mailer/unlock_instructions.html.erb create mode 100644 app/views/devise/passwords/edit.html.erb create mode 100644 app/views/devise/passwords/new.html.erb create mode 100644 app/views/devise/registrations/edit.html.erb create mode 100644 app/views/devise/registrations/new.html.erb create mode 100644 app/views/devise/sessions/new.html.erb create mode 100644 app/views/devise/shared/_error_messages.html.erb create mode 100644 app/views/devise/shared/_links.html.erb create mode 100644 app/views/devise/unlocks/new.html.erb create mode 100644 app/views/home/index.html.erb create mode 100644 app/views/home/privacy.html.erb create mode 100644 app/views/home/terms.html.erb create mode 100644 app/views/notifications/index.html.erb create mode 100644 app/views/pwa/manifest.json.erb create mode 100644 app/views/pwa/service-worker.js create mode 100644 app/views/shared/_footer.html.erb create mode 100644 app/views/shared/_head.html.erb create mode 100644 app/views/shared/_navbar.html.erb create mode 100644 app/views/shared/_notices.html.erb create mode 100755 bin/brakeman delete mode 100755 bin/jobs create mode 100755 bin/rubocop delete mode 100755 bin/spring delete mode 100755 bin/yarn delete mode 100644 config/initializers/application_controller_renderer.rb delete mode 100644 config/initializers/backtrace_silencers.rb delete mode 100644 config/initializers/cookies_serializer.rb delete mode 100644 config/initializers/mime_types.rb delete mode 100644 config/initializers/wrap_parameters.rb delete mode 100644 config/queue.yml delete mode 100644 config/recurring.yml delete mode 100644 config/solid_queue.yml delete mode 100644 config/spring.rb delete mode 100644 db/migrate/20240925185426_create_clusters.rb rename db/migrate/{20240925184128_devise_create_users.rb => 20240925205144_devise_create_users.rb} (96%) rename db/migrate/{20240925184133_create_announcements.rb => 20240925205147_create_announcements.rb} (77%) rename db/migrate/{20240925184134_create_noticed_tables.noticed.rb => 20240925205148_create_noticed_tables.noticed.rb} (100%) rename db/migrate/{20240925184135_add_notifications_count_to_noticed_event.noticed.rb => 20240925205149_add_notifications_count_to_noticed_event.noticed.rb} (100%) rename db/migrate/{20240925184136_create_services.rb => 20240925205150_create_services.rb} (86%) rename db/migrate/{20240925184137_create_friendly_id_slugs.rb => 20240925205151_create_friendly_id_slugs.rb} (100%) rename db/migrate/{20240925184150_create_active_storage_tables.active_storage.rb => 20240925205204_create_active_storage_tables.active_storage.rb} (97%) delete mode 100644 db/queue_schema.rb delete mode 100644 db/schema.rb create mode 100644 esbuild.config.mjs delete mode 100644 lib/tasks/auto_annotate_models.rake create mode 100644 lib/templates/erb/scaffold/_form.html.erb create mode 100644 lib/templates/erb/scaffold/edit.html.erb create mode 100644 lib/templates/erb/scaffold/index.html.erb create mode 100644 lib/templates/erb/scaffold/new.html.erb create mode 100644 lib/templates/erb/scaffold/show.html.erb create mode 100644 public/406-unsupported-browser.html delete mode 100644 public/apple-touch-icon-precomposed.png delete mode 100644 public/apple-touch-icon.png delete mode 100644 public/favicon.ico create mode 100644 public/icon.png create mode 100644 public/icon.svg delete mode 100644 test/fixtures/clusters.yml delete mode 100644 test/models/cluster_test.rb diff --git a/.dockerignore b/.dockerignore index 96123753..cd7190b4 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,6 +2,7 @@ # Ignore git directory. /.git/ +/.gitignore # Ignore bundler config. /.bundle @@ -35,3 +36,13 @@ /app/assets/builds/* !/app/assets/builds/.keep /public/assets + +# Ignore CI service files. +/.github + +# Ignore development files +/.devcontainer + +# Ignore Docker-related files +/.dockerignore +/Dockerfile* diff --git a/.foreman b/.foreman new file mode 100644 index 00000000..722b491f --- /dev/null +++ b/.foreman @@ -0,0 +1 @@ +procfile: Procfile.dev diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..f0527e6b --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +version: 2 +updates: +- package-ecosystem: bundler + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 +- package-ecosystem: github-actions + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..038861c2 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,101 @@ +name: CI + +on: + pull_request: + push: + branches: [ main ] + +jobs: + scan_ruby: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: .ruby-version + bundler-cache: true + + - name: Scan for common Rails security vulnerabilities using static analysis + run: bin/brakeman --no-pager + + scan_js: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: .ruby-version + bundler-cache: true + + - name: Scan for security vulnerabilities in JavaScript dependencies + run: bin/importmap audit + + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: .ruby-version + bundler-cache: true + + - name: Lint code for consistent style + run: bin/rubocop -f github + + test: + runs-on: ubuntu-latest + + services: + postgres: + image: postgres + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + ports: + - 5432:5432 + options: --health-cmd="pg_isready" --health-interval=10s --health-timeout=5s --health-retries=3 + + # redis: + # image: redis + # ports: + # - 6379:6379 + # options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5 + + steps: + - name: Install packages + run: sudo apt-get update && sudo apt-get install --no-install-recommends -y google-chrome-stable curl libjemalloc2 libvips postgresql-client + + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: .ruby-version + bundler-cache: true + + - name: Run tests + env: + RAILS_ENV: test + DATABASE_URL: postgres://postgres:postgres@localhost:5432 + # REDIS_URL: redis://localhost:6379/0 + run: bin/rails db:test:prepare test test:system + + - name: Keep screenshots from failed system tests + uses: actions/upload-artifact@v4 + if: failure() + with: + name: screenshots + path: ${{ github.workspace }}/tmp/screenshots + if-no-files-found: ignore diff --git a/.gitignore b/.gitignore index 288c5a2d..1a2d2ceb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,8 @@ # See https://help.github.com/articles/ignoring-files for more about ignoring files. # -# If you find yourself ignoring temporary files generated by your text editor -# or operating system, you probably want to add a global ignore instead: -# git config --global core.excludesfile '~/.gitignore_global' +# Temporary files generated by your text editor or operating system +# belong in git's global ignore instead: +# `$XDG_CONFIG_HOME/git/ignore` or `~/.config/git/ignore` # Ignore bundler config. /.bundle diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 00000000..f9d86d4a --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,8 @@ +# Omakase Ruby styling for Rails +inherit_gem: { rubocop-rails-omakase: rubocop.yml } + +# Overwrite or add rules to create your own house style +# +# # Use `[a, [b, c]]` not `[ a, [ b, c ] ]` +# Layout/SpaceInsideArrayLiteralBrackets: +# Enabled: false diff --git a/.ruby-version b/.ruby-version index bea438e9..a0891f56 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.3.1 +3.3.4 diff --git a/Dockerfile b/Dockerfile index 161acd10..2539bb92 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,25 +1,34 @@ # syntax = docker/dockerfile:1 -# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile -ARG RUBY_VERSION=3.3.1 -FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base +# This Dockerfile is designed for production, not development. Use with Kamal or build'n'run by hand: +# docker build -t my-app . +# docker run -d -p 80:80 -p 443:443 --name my-app -e RAILS_MASTER_KEY= my-app + +# Make sure RUBY_VERSION matches the Ruby version in .ruby-version +ARG RUBY_VERSION=3.3.4 +FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base # Rails app lives here WORKDIR /rails +# Install base packages +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y curl libjemalloc2 libvips postgresql-client && \ + rm -rf /var/lib/apt/lists /var/cache/apt/archives + # Set production environment ENV RAILS_ENV="production" \ BUNDLE_DEPLOYMENT="1" \ BUNDLE_PATH="/usr/local/bundle" \ BUNDLE_WITHOUT="development" - # Throw-away build stage to reduce size of final image -FROM base as build +FROM base AS build # Install packages needed to build gems RUN apt-get update -qq && \ - apt-get install --no-install-recommends -y build-essential git libpq-dev libvips pkg-config + apt-get install --no-install-recommends -y build-essential git libpq-dev pkg-config && \ + rm -rf /var/lib/apt/lists /var/cache/apt/archives # Install application gems COPY Gemfile Gemfile.lock ./ @@ -37,22 +46,20 @@ RUN bundle exec bootsnap precompile app/ lib/ RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile + + # Final stage for app image FROM base -# Install packages needed for deployment -RUN apt-get update -qq && \ - apt-get install --no-install-recommends -y curl libvips postgresql-client && \ - rm -rf /var/lib/apt/lists /var/cache/apt/archives - # Copy built artifacts: gems, application -COPY --from=build /usr/local/bundle /usr/local/bundle +COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}" COPY --from=build /rails /rails # Run and own only the runtime files as a non-root user for security -RUN useradd rails --create-home --shell /bin/bash && \ +RUN groupadd --system --gid 1000 rails && \ + useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \ chown -R rails:rails db log storage tmp -USER rails:rails +USER 1000:1000 # Entrypoint prepares the database. ENTRYPOINT ["/rails/bin/docker-entrypoint"] diff --git a/Gemfile b/Gemfile index 5ca0098e..aa9ad45d 100644 --- a/Gemfile +++ b/Gemfile @@ -1,106 +1,73 @@ -# frozen_string_literal: true +source "https://rubygems.org" -source 'https://rubygems.org' -git_source(:github) { |repo| "https://github.com/#{repo}.git" } - -ruby file: '.ruby-version' - -gem 'rails', '~> 7.1.3' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' - -gem 'bootsnap', '>= 1.4.2', require: false # Reduces boot times through caching; required in config/boot.rb -gem 'dotenv', '~> 3.1' -gem 'image_processing', '~> 1.12' # Use Active Storage variants -gem 'jbuilder', github: 'excid3/jbuilder', branch: 'partial-paths' # "~> 2.11" # Build JSON APIs with ease -gem 'k8s-ruby', '~> 0.16.0' -gem 'kubeclient', '~> 4.11' -gem 'light-service', '~> 0.18.0' # business logic framework -gem 'nokogiri', '>= 1.12.5' # Security update -gem 'octokit', '~> 9.1' # github API client -gem 'omniauth-digitalocean', '~> 0.3.2' # DigitalOcean OAuth2 strategy for OmniAuth -gem 'pg' # Use postgresql as the database for Active Record -gem 'puma', '~> 6.0' # Use the Puma web server -gem 'redis', '~> 5.1' # Use Redis adapter to run Action Cable in production -gem 'sprockets-rails', '>= 3.4.1' # The original asset pipeline for Rails -gem 'stimulus-rails', '~> 1.0', '>= 1.0.2' # Hotwire's modest JavaScript framework -gem 'turbo-rails', '~> 2.0.3' # Hotwire's SPA-like page accelerator -gem 'tzinfo-data', platforms: %i[windows jruby] # Windows does not include zoneinfo files, so bundle the tzinfo-data gem +# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" +gem "rails", "~> 7.2.1" +# The original asset pipeline for Rails [https://github.com/rails/sprockets-rails] +gem "sprockets-rails" +# Use postgresql as the database for Active Record +gem "pg", "~> 1.1" +# Use the Puma web server [https://github.com/puma/puma] +gem "puma", ">= 5.0" +# Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] +gem "importmap-rails" +# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev] +gem "turbo-rails" +# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev] +gem "stimulus-rails" +# Build JSON APIs with ease [https://github.com/rails/jbuilder] +gem "jbuilder" +# Use Redis adapter to run Action Cable in production +# gem "redis", ">= 4.0.1" # Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis] # gem "kredis" +# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] +# gem "bcrypt", "~> 3.1.7" + +# Windows does not include zoneinfo files, so bundle the tzinfo-data gem +gem "tzinfo-data", platforms: %i[ windows jruby ] + +# Reduces boot times through caching; required in config/boot.rb +gem "bootsnap", require: false + +# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] +# gem "image_processing", "~> 1.2" + group :development, :test do - # debug gems - gem 'debug', platforms: %i[mri windows], require: 'debug/prelude' - gem 'pry', '~> 0.14.2' + # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem + gem "debug", platforms: %i[ mri windows ], require: "debug/prelude" - # Lint code for consistent style - gem 'erb_lint', require: false - gem 'standard', require: false + # Static analysis for security vulnerabilities [https://brakemanscanner.org/] + gem "brakeman", require: false - gem 'brakeman', require: false # Static analysis for security vulnerabilities [https://brakemanscanner.org/] - gem 'letter_opener_web', '~> 3.0' # Preview mail in the browser instead of sending - - # Optional debugging tools - # gem "byebug", platforms: [:mri, :mingw, :x64_mingw] - # gem "pry-rails" + # Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/] + gem "rubocop-rails-omakase", require: false end group :development do # Use console on exceptions pages [https://github.com/rails/web-console] - gem 'annotate', '~> 3.2' # Annotate models and tests with database columns - gem 'web-console', '>= 4.1.0' - - gem 'overcommit', require: false # A fully configurable and extendable Git hook manager - - # Add speed badges - # gem "rack-mini-profiler", ">= 2.3.3" - - # Speed up commands on slow machines / big apps - # gem "spring" + gem "web-console" end group :test do - # Use system testing - gem 'capybara', '>= 3.39' - gem 'selenium-webdriver', '>= 4.20.1' - gem 'webmock' + # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing] + gem "capybara" + gem "selenium-webdriver" end - -# We recommend using strong migrations when your app is in production -# gem "strong_migrations" -# Add dependencies for your application in the main Gemfile - -gem 'administrate', github: 'excid3/administrate' -gem 'administrate-field-active_storage', '~> 1.0.0' -gem 'country_select', '~> 9.0' -gem 'cssbundling-rails', '~> 1.4.0' -gem 'devise', github: 'excid3/devise', branch: 'sign-in-after-reset-password-proc' # "~> 4.9.0" -gem 'devise-i18n', '~> 1.10' -gem 'inline_svg', '~> 1.6' -gem 'invisible_captcha', '~> 2.0' -gem 'jsbundling-rails', '~> 1.3.0' -gem 'local_time', '~> 3.0' -gem 'name_of_person', '~> 1.0' -gem 'noticed', '~> 2.2' -gem 'pagy', '~> 8.0' -gem 'pay', '~> 7.1' -gem 'prefixed_ids', '~> 1.2' -gem 'pretender', '~> 0.4' -gem 'pundit', '~> 2.1' -gem 'receipts', '~> 2.1' -gem 'rotp', '~> 6.2' -gem 'rqrcode', '~> 2.1' -gem 'ruby-oembed', '~> 0.17.0', require: 'oembed' - -gem 'oj', '~> 3.8' - -gem 'omniauth', '~> 2.1' -gem 'omniauth-github' -gem 'omniauth-rails_csrf_protection', '~> 1.0' - -gem 'mission_control-jobs' -gem 'solid_queue' - -gem "tailwindcss-rails", "~> 2.7" - -gem "friendly_id", "~> 5.5" +gem "cssbundling-rails" +gem "devise", "~> 4.9" +gem "friendly_id", "~> 5.4" +gem "jsbundling-rails" +gem "madmin" +gem "name_of_person", github: "basecamp/name_of_person" +gem "noticed", "~> 2.0" +gem "omniauth-facebook", "~> 8.0" +gem "omniauth-github", "~> 2.0" +gem "omniauth-twitter", "~> 1.4" +gem "pretender", "~> 0.3.4" +gem "pundit", "~> 2.1" +gem "sidekiq", "~> 6.2" +gem "sitemap_generator", "~> 6.1" +gem "whenever", require: false +gem "responders", github: "heartcombo/responders", branch: "main" diff --git a/Gemfile.lock b/Gemfile.lock index 454f2b7c..42b45cea 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,132 +1,97 @@ GIT - remote: https://github.com/excid3/administrate.git - revision: a345248f4e66237816f3195893e1edf02d7be28f + remote: https://github.com/basecamp/name_of_person.git + revision: bab0a4496a167fc5e153f4eb6514ba45f5d26338 specs: - administrate (0.20.1) - actionpack (>= 6.0, < 8.0) - actionview (>= 6.0, < 8.0) - activerecord (>= 6.0, < 8.0) - jquery-rails (~> 4.6.0) - kaminari (~> 1.2.2) - sassc-rails (~> 2.1) - selectize-rails (~> 0.6) + name_of_person (1.1.3) + activesupport (>= 5.2.0) GIT - remote: https://github.com/excid3/devise.git - revision: 871c1b7cf6a0cc24b5f8fd5bc165d9c261a6da23 - branch: sign-in-after-reset-password-proc + remote: https://github.com/heartcombo/responders.git + revision: 9bdc60dfbfa8001641c1c4df7bc73c3fc2a4cf41 + branch: main specs: - devise (4.9.3) - bcrypt (~> 3.0) - orm_adapter (~> 0.1) - railties (>= 6.0.0) - responders - warden (~> 1.2.3) - -GIT - remote: https://github.com/excid3/jbuilder.git - revision: 52791b57350b200b2fcf25b674aca91384d56e1d - branch: partial-paths - specs: - jbuilder (2.12.0) - actionview (>= 5.0.0) - activesupport (>= 5.0.0) + responders (3.1.1) + actionpack (>= 5.2) + railties (>= 5.2) GEM remote: https://rubygems.org/ specs: - actioncable (7.1.4) - actionpack (= 7.1.4) - activesupport (= 7.1.4) + actioncable (7.2.1) + actionpack (= 7.2.1) + activesupport (= 7.2.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.1.4) - actionpack (= 7.1.4) - activejob (= 7.1.4) - activerecord (= 7.1.4) - activestorage (= 7.1.4) - activesupport (= 7.1.4) - mail (>= 2.7.1) - net-imap - net-pop - net-smtp - actionmailer (7.1.4) - actionpack (= 7.1.4) - actionview (= 7.1.4) - activejob (= 7.1.4) - activesupport (= 7.1.4) - mail (~> 2.5, >= 2.5.4) - net-imap - net-pop - net-smtp + actionmailbox (7.2.1) + actionpack (= 7.2.1) + activejob (= 7.2.1) + activerecord (= 7.2.1) + activestorage (= 7.2.1) + activesupport (= 7.2.1) + mail (>= 2.8.0) + actionmailer (7.2.1) + actionpack (= 7.2.1) + actionview (= 7.2.1) + activejob (= 7.2.1) + activesupport (= 7.2.1) + mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (7.1.4) - actionview (= 7.1.4) - activesupport (= 7.1.4) + actionpack (7.2.1) + actionview (= 7.2.1) + activesupport (= 7.2.1) nokogiri (>= 1.8.5) racc - rack (>= 2.2.4) + rack (>= 2.2.4, < 3.2) rack-session (>= 1.0.1) rack-test (>= 0.6.3) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - actiontext (7.1.4) - actionpack (= 7.1.4) - activerecord (= 7.1.4) - activestorage (= 7.1.4) - activesupport (= 7.1.4) + useragent (~> 0.16) + actiontext (7.2.1) + actionpack (= 7.2.1) + activerecord (= 7.2.1) + activestorage (= 7.2.1) + activesupport (= 7.2.1) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.1.4) - activesupport (= 7.1.4) + actionview (7.2.1) + activesupport (= 7.2.1) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (7.1.4) - activesupport (= 7.1.4) + activejob (7.2.1) + activesupport (= 7.2.1) globalid (>= 0.3.6) - activemodel (7.1.4) - activesupport (= 7.1.4) - activerecord (7.1.4) - activemodel (= 7.1.4) - activesupport (= 7.1.4) + activemodel (7.2.1) + activesupport (= 7.2.1) + activerecord (7.2.1) + activemodel (= 7.2.1) + activesupport (= 7.2.1) timeout (>= 0.4.0) - activestorage (7.1.4) - actionpack (= 7.1.4) - activejob (= 7.1.4) - activerecord (= 7.1.4) - activesupport (= 7.1.4) + activestorage (7.2.1) + actionpack (= 7.2.1) + activejob (= 7.2.1) + activerecord (= 7.2.1) + activesupport (= 7.2.1) marcel (~> 1.0) - activesupport (7.1.4) + activesupport (7.2.1) base64 bigdecimal - concurrent-ruby (~> 1.0, >= 1.0.2) + concurrent-ruby (~> 1.0, >= 1.3.1) connection_pool (>= 2.2.5) drb i18n (>= 1.6, < 2) + logger (>= 1.4.2) minitest (>= 5.1) - mutex_m - tzinfo (~> 2.0) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) - administrate-field-active_storage (1.0.3) - administrate (>= 0.2.2) - rails (>= 7.0) - annotate (3.2.0) - activerecord (>= 3.2, < 8.0) - rake (>= 10.4, < 14.0) ast (2.4.2) base64 (0.2.0) bcrypt (3.1.20) - better_html (2.1.1) - actionview (>= 6.0) - activesupport (>= 6.0) - ast (~> 2.0) - erubi (~> 1.4) - parser (>= 2.4) - smart_properties bigdecimal (3.1.8) bindex (0.8.1) bootsnap (1.18.4) @@ -143,19 +108,9 @@ GEM rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) - childprocess (5.1.0) - logger (~> 1.5) - chunky_png (1.4.0) - coderay (1.1.3) + chronic (0.10.2) concurrent-ruby (1.3.4) connection_pool (2.4.1) - countries (6.0.1) - unaccent (~> 0.3) - country_select (9.0.0) - countries (> 5.0, < 7.0) - crack (1.0.0) - bigdecimal - rexml crass (1.0.6) cssbundling-rails (1.4.1) railties (>= 6.0.0) @@ -163,160 +118,51 @@ GEM debug (1.9.2) irb (~> 1.10) reline (>= 0.3.8) - devise-i18n (1.12.1) - devise (>= 4.9.0) - domain_name (0.6.20240107) - dotenv (3.1.4) + devise (4.9.4) + bcrypt (~> 3.0) + orm_adapter (~> 0.1) + railties (>= 4.1.0) + responders + warden (~> 1.2.3) drb (2.2.1) - dry-configurable (1.2.0) - dry-core (~> 1.0, < 2) - zeitwerk (~> 2.6) - dry-core (1.0.1) - concurrent-ruby (~> 1.0) - zeitwerk (~> 2.6) - dry-inflector (1.1.0) - dry-logic (1.5.0) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0, < 2) - zeitwerk (~> 2.6) - dry-struct (1.6.0) - dry-core (~> 1.0, < 2) - dry-types (>= 1.7, < 2) - ice_nine (~> 0.11) - zeitwerk (~> 2.6) - dry-types (1.7.2) - bigdecimal (~> 3.0) - concurrent-ruby (~> 1.0) - dry-core (~> 1.0) - dry-inflector (~> 1.0) - dry-logic (~> 1.4) - zeitwerk (~> 2.6) - erb_lint (0.6.0) - activesupport - better_html (>= 2.0.1) - parser (>= 2.7.1.4) - rainbow - rubocop (>= 1) - smart_properties erubi (1.13.0) - et-orbi (1.2.11) - tzinfo - excon (0.111.0) faraday (2.12.0) faraday-net_http (>= 2.0, < 3.4) json logger faraday-net_http (3.3.0) net-http - ffi (1.17.0-aarch64-linux-gnu) - ffi (1.17.0-arm-linux-gnu) - ffi (1.17.0-arm64-darwin) - ffi (1.17.0-x86-linux-gnu) - ffi (1.17.0-x86_64-darwin) - ffi (1.17.0-x86_64-linux-gnu) - ffi-compiler (1.3.2) - ffi (>= 1.15.5) - rake friendly_id (5.5.1) activerecord (>= 4.0.0) - fugit (1.11.1) - et-orbi (~> 1, >= 1.2.11) - raabro (~> 1.4) globalid (1.2.1) activesupport (>= 6.1) - hashdiff (1.0.1) - hashids (1.0.6) hashie (5.0.0) - http (5.2.0) - addressable (~> 2.8) - base64 (~> 0.1) - http-cookie (~> 1.0) - http-form_data (~> 2.2) - llhttp-ffi (~> 0.5.0) - http-accept (1.7.0) - http-cookie (1.0.7) - domain_name (~> 0.5) - http-form_data (2.3.0) i18n (1.14.6) concurrent-ruby (~> 1.0) - ice_nine (0.11.2) - image_processing (1.13.0) - mini_magick (>= 4.9.5, < 5) - ruby-vips (>= 2.0.17, < 3) importmap-rails (2.0.1) actionpack (>= 6.0.0) activesupport (>= 6.0.0) railties (>= 6.0.0) - iniparse (1.5.0) - inline_svg (1.10.0) - activesupport (>= 3.0) - nokogiri (>= 1.6) - invisible_captcha (2.3.0) - rails (>= 5.2) io-console (0.7.2) irb (1.14.0) rdoc (>= 4.0.0) reline (>= 0.4.2) - jquery-rails (4.6.0) - rails-dom-testing (>= 1, < 3) - railties (>= 4.2.0) - thor (>= 0.14, < 2.0) + jbuilder (2.13.0) + actionview (>= 5.0.0) + activesupport (>= 5.0.0) jsbundling-rails (1.3.1) railties (>= 6.0.0) json (2.7.2) - jsonpath (1.1.5) - multi_json jwt (2.9.1) base64 - k8s-ruby (0.16.0) - dry-configurable - dry-struct - dry-types - excon (~> 0.71) - hashdiff (~> 1.0.0) - jsonpath (~> 1.1) - recursive-open-struct (~> 1.1.3) - yajl-ruby (~> 1.4.0) - yaml-safe_load_stream3 - kaminari (1.2.2) - activesupport (>= 4.1.0) - kaminari-actionview (= 1.2.2) - kaminari-activerecord (= 1.2.2) - kaminari-core (= 1.2.2) - kaminari-actionview (1.2.2) - actionview - kaminari-core (= 1.2.2) - kaminari-activerecord (1.2.2) - activerecord - kaminari-core (= 1.2.2) - kaminari-core (1.2.2) - kubeclient (4.12.0) - http (>= 3.0, < 6.0) - jsonpath (~> 1.0) - recursive-open-struct (~> 1.1, >= 1.1.1) - rest-client (~> 2.0) language_server-protocol (3.17.0.3) - launchy (3.0.1) - addressable (~> 2.8) - childprocess (~> 5.0) - letter_opener (1.10.0) - launchy (>= 2.2, < 4) - letter_opener_web (3.0.0) - actionmailer (>= 6.1) - letter_opener (~> 1.9) - railties (>= 6.1) - rexml - light-service (0.18.0) - activesupport (>= 4.0.0) - lint_roller (1.1.0) - llhttp-ffi (0.5.0) - ffi-compiler (~> 1.0) - rake (~> 13.0) - local_time (3.0.2) logger (1.6.1) loofah (2.22.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) + madmin (1.2.11) + pagy (>= 3.5) + rails (>= 6.0.3) mail (2.8.1) mini_mime (>= 0.1.1) net-imap @@ -324,26 +170,11 @@ GEM net-smtp marcel (1.0.4) matrix (0.4.2) - method_source (1.1.0) - mime-types (3.5.2) - mime-types-data (~> 3.2015) - mime-types-data (3.2024.0903) - mini_magick (4.13.2) mini_mime (1.1.5) minitest (5.25.1) - mission_control-jobs (0.3.1) - importmap-rails - irb (~> 1.13) - rails (>= 7.1) - stimulus-rails - turbo-rails msgpack (1.7.2) - multi_json (1.15.0) multi_xml (0.7.1) bigdecimal (~> 3.1) - mutex_m (0.2.0) - name_of_person (1.1.3) - activesupport (>= 5.2.0) net-http (0.4.1) uri net-imap (0.4.16) @@ -355,7 +186,6 @@ GEM timeout net-smtp (0.5.0) net-protocol - netrc (0.11.0) nio4r (2.7.3) nokogiri (1.16.7-aarch64-linux) racc (~> 1.4) @@ -371,6 +201,12 @@ GEM racc (~> 1.4) noticed (2.4.3) rails (>= 6.1.0) + oauth (1.1.0) + oauth-tty (~> 1.0, >= 1.0.1) + snaky_hash (~> 2.0) + version_gem (~> 1.1) + oauth-tty (1.0.5) + version_gem (~> 1.1, >= 1.1.1) oauth2 (2.0.9) faraday (>= 0.17.3, < 3.0) jwt (>= 1.0, < 3.0) @@ -378,58 +214,34 @@ GEM rack (>= 1.2, < 4) snaky_hash (~> 2.0) version_gem (~> 1.1) - octokit (9.1.0) - faraday (>= 1, < 3) - sawyer (~> 0.9) - oj (3.16.6) - bigdecimal (>= 3.0) - ostruct (>= 0.2) omniauth (2.1.2) hashie (>= 3.4.6) rack (>= 2.2.3) rack-protection - omniauth-digitalocean (0.3.2) - multi_json (~> 1.15) - omniauth (~> 2.0) - omniauth-oauth2 (~> 1.0) + omniauth-facebook (8.0.0) + omniauth-oauth2 (~> 1.2) omniauth-github (2.0.1) omniauth (~> 2.0) omniauth-oauth2 (~> 1.8) + omniauth-oauth (1.2.1) + oauth + omniauth (>= 1.0, < 3) + rack (>= 1.6.2, < 4) omniauth-oauth2 (1.8.0) oauth2 (>= 1.4, < 3) omniauth (~> 2.0) - omniauth-rails_csrf_protection (1.0.2) - actionpack (>= 4.2) - omniauth (~> 2.0) + omniauth-twitter (1.4.0) + omniauth-oauth (~> 1.1) + rack orm_adapter (0.5.0) - ostruct (0.6.0) - overcommit (0.64.0) - childprocess (>= 0.6.3, < 6) - iniparse (~> 1.4) - rexml (~> 3.2) - pagy (8.6.3) + pagy (9.0.9) parallel (1.26.3) parser (3.3.5.0) ast (~> 2.4.1) racc - pay (7.3.0) - rails (>= 6.0.0) - pdf-core (0.10.0) pg (1.5.8) - prawn (2.5.0) - matrix (~> 0.4) - pdf-core (~> 0.10.0) - ttfunk (~> 1.8) - prawn-table (0.2.2) - prawn (>= 1.3.0, < 3.0.0) - prefixed_ids (1.8.1) - hashids (>= 1.0.0, < 2.0.0) - rails (>= 6.0.0) - pretender (0.5.0) - actionpack (>= 6.1) - pry (0.14.2) - coderay (~> 1.1) - method_source (~> 1.0) + pretender (0.3.4) + actionpack (>= 4.2) psych (5.1.2) stringio public_suffix (6.0.1) @@ -437,7 +249,6 @@ GEM nio4r (~> 2.0) pundit (2.4.0) activesupport (>= 3.0.0) - raabro (1.4.0) racc (1.8.1) rack (2.2.9) rack-protection (3.2.0) @@ -450,20 +261,20 @@ GEM rackup (1.0.0) rack (< 3) webrick - rails (7.1.4) - actioncable (= 7.1.4) - actionmailbox (= 7.1.4) - actionmailer (= 7.1.4) - actionpack (= 7.1.4) - actiontext (= 7.1.4) - actionview (= 7.1.4) - activejob (= 7.1.4) - activemodel (= 7.1.4) - activerecord (= 7.1.4) - activestorage (= 7.1.4) - activesupport (= 7.1.4) + rails (7.2.1) + actioncable (= 7.2.1) + actionmailbox (= 7.2.1) + actionmailer (= 7.2.1) + actionpack (= 7.2.1) + actiontext (= 7.2.1) + actionview (= 7.2.1) + activejob (= 7.2.1) + activemodel (= 7.2.1) + activerecord (= 7.2.1) + activestorage (= 7.2.1) + activesupport (= 7.2.1) bundler (>= 1.15.0) - railties (= 7.1.4) + railties (= 7.2.1) rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest @@ -471,10 +282,10 @@ GEM rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) - railties (7.1.4) - actionpack (= 7.1.4) - activesupport (= 7.1.4) - irb + railties (7.2.1) + actionpack (= 7.2.1) + activesupport (= 7.2.1) + irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) thor (~> 1.0, >= 1.2.2) @@ -483,82 +294,57 @@ GEM rake (13.2.1) rdoc (6.7.0) psych (>= 4.0.0) - receipts (2.4.0) - prawn (>= 1.3.0, < 3.0.0) - prawn-table (~> 0.2.1) - recursive-open-struct (1.1.3) - redis (5.3.0) - redis-client (>= 0.22.0) - redis-client (0.22.2) - connection_pool + redis (4.8.1) regexp_parser (2.9.2) reline (0.5.10) io-console (~> 0.5) - responders (3.1.1) - actionpack (>= 5.2) - railties (>= 5.2) - rest-client (2.1.0) - http-accept (>= 1.7.0, < 2.0) - http-cookie (>= 1.0.2, < 2.0) - mime-types (>= 1.16, < 4.0) - netrc (~> 0.8) rexml (3.3.7) - rotp (6.3.0) - rqrcode (2.2.0) - chunky_png (~> 1.0) - rqrcode_core (~> 1.0) - rqrcode_core (1.2.0) - rubocop (1.65.1) + rubocop (1.66.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.4, < 3.0) - rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.31.1, < 2.0) + rubocop-ast (>= 1.32.2, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) rubocop-ast (1.32.3) parser (>= 3.3.1.0) - rubocop-performance (1.21.1) + rubocop-minitest (0.36.0) + rubocop (>= 1.61, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-performance (1.22.1) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) - ruby-oembed (0.17.0) + rubocop-rails (2.26.2) + activesupport (>= 4.2.0) + rack (>= 1.1) + rubocop (>= 1.52.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rails-omakase (1.0.0) + rubocop + rubocop-minitest + rubocop-performance + rubocop-rails ruby-progressbar (1.13.0) - ruby-vips (2.2.2) - ffi (~> 1.12) - logger rubyzip (2.3.2) - sassc (2.4.0) - ffi (~> 1.9) - sassc-rails (2.1.2) - railties (>= 4.0.0) - sassc (>= 2.0) - sprockets (> 3.0) - sprockets-rails - tilt - sawyer (0.9.2) - addressable (>= 2.3.5) - faraday (>= 0.17.3, < 3) - selectize-rails (0.12.6) + securerandom (0.3.1) selenium-webdriver (4.25.0) base64 (~> 0.2) logger (~> 1.4) rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) - smart_properties (1.17.0) + sidekiq (6.5.12) + connection_pool (>= 2.2.5, < 3) + rack (~> 2.0) + redis (>= 4.5.0, < 5) + sitemap_generator (6.3.0) + builder (~> 3.0) snaky_hash (2.0.1) hashie version_gem (~> 1.1, >= 1.1.1) - solid_queue (0.9.0) - activejob (>= 7.1) - activerecord (>= 7.1) - concurrent-ruby (>= 1.3.1) - fugit (~> 1.11.0) - railties (>= 7.1) - thor (~> 1.3.1) sprockets (4.2.1) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) @@ -566,46 +352,19 @@ GEM actionpack (>= 6.1) activesupport (>= 6.1) sprockets (>= 3.0.0) - standard (1.40.0) - language_server-protocol (~> 3.17.0.2) - lint_roller (~> 1.0) - rubocop (~> 1.65.0) - standard-custom (~> 1.0.0) - standard-performance (~> 1.4) - standard-custom (1.0.2) - lint_roller (~> 1.0) - rubocop (~> 1.50) - standard-performance (1.4.0) - lint_roller (~> 1.1) - rubocop-performance (~> 1.21.0) stimulus-rails (1.3.4) railties (>= 6.0.0) stringio (3.1.1) - tailwindcss-rails (2.7.6) - railties (>= 7.0.0) - tailwindcss-rails (2.7.6-aarch64-linux) - railties (>= 7.0.0) - tailwindcss-rails (2.7.6-arm-linux) - railties (>= 7.0.0) - tailwindcss-rails (2.7.6-arm64-darwin) - railties (>= 7.0.0) - tailwindcss-rails (2.7.6-x86_64-darwin) - railties (>= 7.0.0) - tailwindcss-rails (2.7.6-x86_64-linux) - railties (>= 7.0.0) thor (1.3.2) - tilt (2.4.0) timeout (0.4.1) - ttfunk (1.8.0) - bigdecimal (~> 3.1) turbo-rails (2.0.10) actionpack (>= 6.0.0) railties (>= 6.0.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - unaccent (0.4.0) unicode-display_width (2.6.0) uri (0.13.1) + useragent (0.16.10) version_gem (1.1.4) warden (1.2.9) rack (>= 2.0.9) @@ -614,19 +373,15 @@ GEM activemodel (>= 6.0.0) bindex (>= 0.4.0) railties (>= 6.0.0) - webmock (3.23.1) - addressable (>= 2.8.0) - crack (>= 0.3.2) - hashdiff (>= 0.4.0, < 2.0.0) webrick (1.8.2) websocket (1.2.11) websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) + whenever (1.0.0) + chronic (>= 0.6.3) xpath (3.2.0) nokogiri (~> 1.8) - yajl-ruby (1.4.3) - yaml-safe_load_stream3 (0.1.2) zeitwerk (2.6.18) PLATFORMS @@ -638,68 +393,38 @@ PLATFORMS x86_64-linux DEPENDENCIES - administrate! - administrate-field-active_storage (~> 1.0.0) - annotate (~> 3.2) - bootsnap (>= 1.4.2) + bootsnap brakeman - capybara (>= 3.39) - country_select (~> 9.0) - cssbundling-rails (~> 1.4.0) + capybara + cssbundling-rails debug - devise! - devise-i18n (~> 1.10) - dotenv (~> 3.1) - erb_lint - friendly_id (~> 5.5) - image_processing (~> 1.12) - inline_svg (~> 1.6) - invisible_captcha (~> 2.0) - jbuilder! - jsbundling-rails (~> 1.3.0) - k8s-ruby (~> 0.16.0) - kubeclient (~> 4.11) - letter_opener_web (~> 3.0) - light-service (~> 0.18.0) - local_time (~> 3.0) - mission_control-jobs - name_of_person (~> 1.0) - nokogiri (>= 1.12.5) - noticed (~> 2.2) - octokit (~> 9.1) - oj (~> 3.8) - omniauth (~> 2.1) - omniauth-digitalocean (~> 0.3.2) - omniauth-github - omniauth-rails_csrf_protection (~> 1.0) - overcommit - pagy (~> 8.0) - pay (~> 7.1) - pg - prefixed_ids (~> 1.2) - pretender (~> 0.4) - pry (~> 0.14.2) - puma (~> 6.0) + devise (~> 4.9) + friendly_id (~> 5.4) + importmap-rails + jbuilder + jsbundling-rails + madmin + name_of_person! + noticed (~> 2.0) + omniauth-facebook (~> 8.0) + omniauth-github (~> 2.0) + omniauth-twitter (~> 1.4) + pg (~> 1.1) + pretender (~> 0.3.4) + puma (>= 5.0) pundit (~> 2.1) - rails (~> 7.1.3) - receipts (~> 2.1) - redis (~> 5.1) - rotp (~> 6.2) - rqrcode (~> 2.1) - ruby-oembed (~> 0.17.0) - selenium-webdriver (>= 4.20.1) - solid_queue - sprockets-rails (>= 3.4.1) - standard - stimulus-rails (~> 1.0, >= 1.0.2) - tailwindcss-rails (~> 2.7) - turbo-rails (~> 2.0.3) + rails (~> 7.2.1) + responders! + rubocop-rails-omakase + selenium-webdriver + sidekiq (~> 6.2) + sitemap_generator (~> 6.1) + sprockets-rails + stimulus-rails + turbo-rails tzinfo-data - web-console (>= 4.1.0) - webmock - -RUBY VERSION - ruby 3.3.1p55 + web-console + whenever BUNDLED WITH - 2.5.9 + 2.5.20 diff --git a/Procfile b/Procfile index 5d7bb32e..a9adec8f 100644 --- a/Procfile +++ b/Procfile @@ -1,2 +1,2 @@ web: bin/rails server -worker: bundle exec rake solid_queue:start +worker: bundle exec sidekiq diff --git a/Procfile.dev b/Procfile.dev index 2a3e8b14..d44b54d3 100644 --- a/Procfile.dev +++ b/Procfile.dev @@ -1,4 +1,4 @@ web: bin/rails server -p 3000 -worker: bundle exec rake solid_queue:start +worker: bundle exec sidekiq js: yarn build --reload css: yarn build:css --watch diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js index 9a99757a..decf0a9d 100644 --- a/app/assets/config/manifest.js +++ b/app/assets/config/manifest.js @@ -1,2 +1,2 @@ -//= link_tree ../images //= link_tree ../builds +//= link_tree ../images diff --git a/app/assets/stylesheets/jumpstart/announcements.scss b/app/assets/stylesheets/jumpstart/announcements.scss new file mode 100644 index 00000000..a228f026 --- /dev/null +++ b/app/assets/stylesheets/jumpstart/announcements.scss @@ -0,0 +1,21 @@ +.announcement { + strong { + color: $gray-700; + font-weight: 900; + } +} + +.unread-announcements:before { + -moz-border-radius: 50%; + -webkit-border-radius: 50%; + border-radius: 50%; + -moz-background-clip: padding-box; + -webkit-background-clip: padding-box; + background-clip: padding-box; + background: $red; + content: ''; + display: inline-block; + height: 8px; + width: 8px; + margin-right: 6px; +} diff --git a/app/channels/application_cable/connection.rb b/app/channels/application_cable/connection.rb index 0ff5442f..39ed58a7 100644 --- a/app/channels/application_cable/connection.rb +++ b/app/channels/application_cable/connection.rb @@ -1,4 +1,21 @@ module ApplicationCable class Connection < ActionCable::Connection::Base + identified_by :current_user, :true_user + impersonates :user + + def connect + self.current_user = find_verified_user + logger.add_tags "ActionCable", "User #{current_user.id}" + end + + protected + + def find_verified_user + if (current_user = env['warden'].user) + current_user + else + reject_unauthorized_connection + end + end end end diff --git a/app/controllers/announcements_controller.rb b/app/controllers/announcements_controller.rb new file mode 100644 index 00000000..1f671d1c --- /dev/null +++ b/app/controllers/announcements_controller.rb @@ -0,0 +1,13 @@ +class AnnouncementsController < ApplicationController + before_action :mark_as_read, if: :user_signed_in? + + def index + @announcements = Announcement.order(published_at: :desc) + end + + private + + def mark_as_read + current_user.update(announcements_last_read_at: Time.zone.now) + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 09705d12..ce537e97 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,2 +1,15 @@ class ApplicationController < ActionController::Base + impersonates :user + include Pundit::Authorization + + protect_from_forgery with: :exception + + before_action :configure_permitted_parameters, if: :devise_controller? + + protected + + def configure_permitted_parameters + devise_parameter_sanitizer.permit(:sign_up, keys: [:name]) + devise_parameter_sanitizer.permit(:account_update, keys: [:name, :avatar]) + end end diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb new file mode 100644 index 00000000..4bf0ee77 --- /dev/null +++ b/app/controllers/home_controller.rb @@ -0,0 +1,10 @@ +class HomeController < ApplicationController + def index + end + + def terms + end + + def privacy + end +end diff --git a/app/controllers/madmin/impersonates_controller.rb b/app/controllers/madmin/impersonates_controller.rb new file mode 100644 index 00000000..a329cee7 --- /dev/null +++ b/app/controllers/madmin/impersonates_controller.rb @@ -0,0 +1,14 @@ +class Madmin::ImpersonatesController < Madmin::ApplicationController + impersonates :user + + def impersonate + user = User.find(params[:id]) + impersonate_user(user) + redirect_to root_path + end + + def stop_impersonating + stop_impersonating_user + redirect_to root_path + end +end diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb new file mode 100644 index 00000000..2a73c5c5 --- /dev/null +++ b/app/controllers/notifications_controller.rb @@ -0,0 +1,7 @@ +class NotificationsController < ApplicationController + before_action :authenticate_user! + + def index + @notifications = current_user.notifications.includes(:event) + end +end diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb new file mode 100644 index 00000000..25046f2f --- /dev/null +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -0,0 +1,84 @@ +module Users + class OmniauthCallbacksController < Devise::OmniauthCallbacksController + before_action :set_service, except: [:failure] + before_action :set_user, except: [:failure] + + attr_reader :service, :user + + def failure + redirect_to root_path, alert: "Something went wrong" + end + + def facebook + handle_auth "Facebook" + end + + def twitter + handle_auth "Twitter" + end + + def github + handle_auth "Github" + end + + private + + def handle_auth(kind) + if service.present? + service.update(service_attrs) + else + user.services.create(service_attrs) + end + + if user_signed_in? + flash[:notice] = "Your #{kind} account was connected." + redirect_to edit_user_registration_path + else + sign_in_and_redirect user, event: :authentication + set_flash_message :notice, :success, kind: kind + end + end + + def auth + request.env['omniauth.auth'] + end + + def set_service + @service = Service.where(provider: auth.provider, uid: auth.uid).first + end + + def set_user + if user_signed_in? + @user = current_user + elsif service.present? + @user = service.user + elsif User.where(email: auth.info.email).any? + # 5. User is logged out and they login to a new account which doesn't match their old one + flash[:alert] = "An account with this email already exists. Please sign in with that account before connecting your #{auth.provider.titleize} account." + redirect_to new_user_session_path + else + @user = create_user + end + end + + def service_attrs + expires_at = auth.credentials.expires_at.present? ? Time.at(auth.credentials.expires_at) : nil + { + provider: auth.provider, + uid: auth.uid, + expires_at: expires_at, + access_token: auth.credentials.token, + access_token_secret: auth.credentials.secret, + } + end + + def create_user + User.create( + email: auth.info.email, + #name: auth.info.name, + password: Devise.friendly_token[0,20] + ) + end + + end +end diff --git a/app/helpers/announcements_helper.rb b/app/helpers/announcements_helper.rb new file mode 100644 index 00000000..224e428f --- /dev/null +++ b/app/helpers/announcements_helper.rb @@ -0,0 +1,19 @@ +module AnnouncementsHelper + def unread_announcements(user) + last_announcement = Announcement.order(published_at: :desc).first + return if last_announcement.nil? + + # Highlight announcements for anyone not logged in, cuz tempting + if user.nil? || user.announcements_last_read_at.nil? || user.announcements_last_read_at < last_announcement.published_at + "unread-announcements" + end + end + + def announcement_class(type) + { + "new" => "text-success", + "update" => "text-warning", + "fix" => "text-danger", + }.fetch(type, "text-success") + end +end diff --git a/app/helpers/avatar_helper.rb b/app/helpers/avatar_helper.rb new file mode 100644 index 00000000..177dfe9f --- /dev/null +++ b/app/helpers/avatar_helper.rb @@ -0,0 +1,17 @@ +module AvatarHelper + def avatar_path(object, options = {}) + size = options[:size] || 180 + default_image = options[:default] || "mp" + base_url = "https://secure.gravatar.com/avatar" + base_url_params = "?s=#{size}&d=#{default_image}" + + if object.respond_to?(:avatar) && object.avatar.attached? && object.avatar.variable? + object.avatar.variant(resize_to_fill: [size, size]) + elsif object.respond_to?(:email) && object.email + gravatar_id = Digest::MD5::hexdigest(object.email.downcase) + "#{base_url}/#{gravatar_id}#{base_url_params}" + else + "#{base_url}/00000000000000000000000000000000#{base_url_params}" + end + end +end diff --git a/app/helpers/bootstrap_helper.rb b/app/helpers/bootstrap_helper.rb new file mode 100644 index 00000000..52127e20 --- /dev/null +++ b/app/helpers/bootstrap_helper.rb @@ -0,0 +1,10 @@ +module BootstrapHelper + def bootstrap_class_for(flash_type) + { + success: "alert-success", + error: "alert-danger", + alert: "alert-warning", + notice: "alert-primary" + }.stringify_keys[flash_type.to_s] || flash_type.to_s + end +end diff --git a/app/javascript/application.js b/app/javascript/application.js new file mode 100644 index 00000000..81d6c6a2 --- /dev/null +++ b/app/javascript/application.js @@ -0,0 +1,28 @@ +// This file is automatically compiled by Webpack, along with any other files +// present in this directory. You're encouraged to place your actual application logic in +// a relevant structure within app/javascript and only use these pack files to reference +// that code so it'll be compiled. + +import "@hotwired/turbo-rails" +require("@rails/activestorage").start() +//require("trix") +//require("@rails/actiontext") +require("local-time").start() +require("@rails/ujs").start() + +import './channels/**/*_channel.js' +import "./controllers" + +import * as bootstrap from "bootstrap" + +document.addEventListener("turbo:load", () => { + var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')) + var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) { + return new bootstrap.Tooltip(tooltipTriggerEl) + }) + + var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]')) + var popoverList = popoverTriggerList.map(function (popoverTriggerEl) { + return new bootstrap.Popover(popoverTriggerEl) + }) +}) diff --git a/app/javascript/channels/consumer.js b/app/javascript/channels/consumer.js deleted file mode 100644 index 8ec3aad3..00000000 --- a/app/javascript/channels/consumer.js +++ /dev/null @@ -1,6 +0,0 @@ -// Action Cable provides the framework to deal with WebSockets in Rails. -// You can generate new channels where WebSocket features live using the `bin/rails generate channel` command. - -import { createConsumer } from "@rails/actioncable" - -export default createConsumer() diff --git a/app/javascript/channels/index.js b/app/javascript/channels/index.js deleted file mode 100644 index 0cfcf749..00000000 --- a/app/javascript/channels/index.js +++ /dev/null @@ -1,5 +0,0 @@ -// Load all the channels within this directory and all subdirectories. -// Channel files must be named *_channel.js. - -const channels = require.context('.', true, /_channel\.js$/) -channels.keys().forEach(channels) diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js new file mode 100644 index 00000000..a538cbe0 --- /dev/null +++ b/app/javascript/controllers/index.js @@ -0,0 +1,6 @@ +import { application } from "./application" +import controllers from './**/*_controller.js' +controllers.forEach((controller) => { + application.register(controller.name, controller.module.default) +}) + diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js deleted file mode 100644 index f710851a..00000000 --- a/app/javascript/packs/application.js +++ /dev/null @@ -1,13 +0,0 @@ -// This file is automatically compiled by Webpack, along with any other files -// present in this directory. You're encouraged to place your actual application logic in -// a relevant structure within app/javascript and only use these pack files to reference -// that code so it'll be compiled. - -import Rails from "@rails/ujs" -import Turbolinks from "turbolinks" -import * as ActiveStorage from "@rails/activestorage" -import "channels" - -Rails.start() -Turbolinks.start() -ActiveStorage.start() diff --git a/app/models/announcement.rb b/app/models/announcement.rb index f70f4bee..dbeeea2d 100644 --- a/app/models/announcement.rb +++ b/app/models/announcement.rb @@ -1,14 +1,13 @@ -# == Schema Information -# -# Table name: announcements -# -# id :bigint not null, primary key -# announcement_type :string -# description :text -# name :string -# published_at :datetime -# created_at :datetime not null -# updated_at :datetime not null -# class Announcement < ApplicationRecord + TYPES = %w{ new fix update } + + after_initialize :set_defaults + + validates :announcement_type, :description, :name, :published_at, presence: true + validates :announcement_type, inclusion: { in: TYPES } + + def set_defaults + self.published_at ||= Time.zone.now + self.announcement_type ||= TYPES.first + end end diff --git a/app/models/cluster.rb b/app/models/cluster.rb deleted file mode 100644 index a2848cbc..00000000 --- a/app/models/cluster.rb +++ /dev/null @@ -1,21 +0,0 @@ -# == Schema Information -# -# Table name: clusters -# -# id :bigint not null, primary key -# kubeconfig :jsonb not null -# name :string not null -# created_at :datetime not null -# updated_at :datetime not null -# user_id :bigint not null -# -# Indexes -# -# index_clusters_on_user_id (user_id) -# -# Foreign Keys -# -# fk_rails_... (user_id => users.id) -# -class Cluster < ApplicationRecord -end diff --git a/app/models/service.rb b/app/models/service.rb index 2386c3e3..fd5f8c5f 100644 --- a/app/models/service.rb +++ b/app/models/service.rb @@ -1,27 +1,32 @@ -# == Schema Information -# -# Table name: services -# -# id :bigint not null, primary key -# access_token :string -# access_token_secret :string -# auth :text -# expires_at :datetime -# provider :string -# refresh_token :string -# uid :string -# created_at :datetime not null -# updated_at :datetime not null -# user_id :bigint not null -# -# Indexes -# -# index_services_on_user_id (user_id) -# -# Foreign Keys -# -# fk_rails_... (user_id => users.id) -# -class Service < ApplicationRecord - belongs_to :user -end +class Service < ApplicationRecord + belongs_to :user + + Devise.omniauth_configs.keys.each do |provider| + scope provider, ->{ where(provider: provider) } + end + + def client + send("#{provider}_client") + end + + def expired? + expires_at? && expires_at <= Time.zone.now + end + + def access_token + send("#{provider}_refresh_token!", super) if expired? + super + end + + + def twitter_client + Twitter::REST::Client.new do |config| + config.consumer_key = Rails.application.secrets.twitter_app_id + config.consumer_secret = Rails.application.secrets.twitter_app_secret + config.access_token = access_token + config.access_token_secret = access_token_secret + end + end + + def twitter_refresh_token!(token); end +end diff --git a/app/models/user.rb b/app/models/user.rb index 8c69a840..704f4c54 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,28 +1,12 @@ -# == Schema Information -# -# Table name: users -# -# id :bigint not null, primary key -# admin :boolean default(FALSE) -# announcements_last_read_at :datetime -# email :string default(""), not null -# encrypted_password :string default(""), not null -# first_name :string -# last_name :string -# remember_created_at :datetime -# reset_password_sent_at :datetime -# reset_password_token :string -# created_at :datetime not null -# updated_at :datetime not null -# -# Indexes -# -# index_users_on_email (email) UNIQUE -# index_users_on_reset_password_token (reset_password_token) UNIQUE -# class User < ApplicationRecord # Include default devise modules. Others available are: - # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable - devise :omniauthable, :database_authenticatable, :registerable, - :recoverable, :rememberable, :validatable + # :confirmable, :lockable, :timeoutable and :omniauthable + devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, :omniauthable + + has_one_attached :avatar + has_person_name + + has_many :notifications, as: :recipient, dependent: :destroy, class_name: "Noticed::Notification" + has_many :notification_mentions, as: :record, dependent: :destroy, class_name: "Noticed::Event" + has_many :services end diff --git a/app/views/announcements/index.html.erb b/app/views/announcements/index.html.erb new file mode 100644 index 00000000..175ccf35 --- /dev/null +++ b/app/views/announcements/index.html.erb @@ -0,0 +1,28 @@ +

What's New

+ +
+
+ <% @announcements.each_with_index do |announcement, index| %> + <% if index != 0 %> +

+ <% end %> + +
+
+ <%= link_to announcements_path(anchor: dom_id(announcement)) do %> + <%= announcement.published_at.strftime("%b %d") %> + <% end %> +
+
+ <%= announcement.announcement_type.titleize %>: + <%= announcement.name %> + <%= simple_format announcement.description %> +
+
+ <% end %> + + <% if @announcements.empty? %> +
Exciting stuff coming very soon!
+ <% end %> +
+
diff --git a/app/views/devise/confirmations/new.html.erb b/app/views/devise/confirmations/new.html.erb new file mode 100644 index 00000000..6575189a --- /dev/null +++ b/app/views/devise/confirmations/new.html.erb @@ -0,0 +1,22 @@ +
+
+

Resend confirmation instructions

+ + <%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> + +
+ <%= f.label :email, class: 'form-label' %>
+ <%= f.email_field :email, autofocus: true, class: 'form-control', value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %> +
+ +
+ <%= f.submit "Resend confirmation instructions", class: 'btn btn-primary btn-lg' %> +
+ <% end %> + +
+ <%= render "devise/shared/links" %> +
+
+
diff --git a/app/views/devise/mailer/confirmation_instructions.html.erb b/app/views/devise/mailer/confirmation_instructions.html.erb new file mode 100644 index 00000000..dc55f64f --- /dev/null +++ b/app/views/devise/mailer/confirmation_instructions.html.erb @@ -0,0 +1,5 @@ +

Welcome <%= @email %>!

+ +

You can confirm your account email through the link below:

+ +

<%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>

diff --git a/app/views/devise/mailer/email_changed.html.erb b/app/views/devise/mailer/email_changed.html.erb new file mode 100644 index 00000000..c9da7af4 --- /dev/null +++ b/app/views/devise/mailer/email_changed.html.erb @@ -0,0 +1,7 @@ +

Hello <%= @email %>!

+ +<% if @resource.try(:unconfirmed_email?) %> +

We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.

+<% else %> +

We're contacting you to notify you that your email has been changed to <%= @resource.email %>.

+<% end %> diff --git a/app/views/devise/mailer/password_change.html.erb b/app/views/devise/mailer/password_change.html.erb new file mode 100644 index 00000000..b41daf47 --- /dev/null +++ b/app/views/devise/mailer/password_change.html.erb @@ -0,0 +1,3 @@ +

Hello <%= @resource.email %>!

+ +

We're contacting you to notify you that your password has been changed.

diff --git a/app/views/devise/mailer/reset_password_instructions.html.erb b/app/views/devise/mailer/reset_password_instructions.html.erb new file mode 100644 index 00000000..f667dc12 --- /dev/null +++ b/app/views/devise/mailer/reset_password_instructions.html.erb @@ -0,0 +1,8 @@ +

Hello <%= @resource.email %>!

+ +

Someone has requested a link to change your password. You can do this through the link below.

+ +

<%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %>

+ +

If you didn't request this, please ignore this email.

+

Your password won't change until you access the link above and create a new one.

diff --git a/app/views/devise/mailer/unlock_instructions.html.erb b/app/views/devise/mailer/unlock_instructions.html.erb new file mode 100644 index 00000000..41e148bf --- /dev/null +++ b/app/views/devise/mailer/unlock_instructions.html.erb @@ -0,0 +1,7 @@ +

Hello <%= @resource.email %>!

+ +

Your account has been locked due to an excessive number of unsuccessful sign in attempts.

+ +

Click the link below to unlock your account:

+ +

<%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>

diff --git a/app/views/devise/passwords/edit.html.erb b/app/views/devise/passwords/edit.html.erb new file mode 100644 index 00000000..60ee31db --- /dev/null +++ b/app/views/devise/passwords/edit.html.erb @@ -0,0 +1,29 @@ +
+
+

Change your password

+ + <%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> + <%= f.hidden_field :reset_password_token %> + +
+ <%= f.password_field :password, autofocus: true, autocomplete: "off", class: 'form-control', placeholder: "Password" %> + <% if @minimum_password_length %> +

<%= @minimum_password_length %> characters minimum

+ <% end %> +
+ +
+ <%= f.password_field :password_confirmation, autocomplete: "off", class: 'form-control', placeholder: "Confirm Password" %> +
+ +
+ <%= f.submit "Change my password", class: 'btn btn-primary btn-lg' %> +
+ <% end %> + +
+ <%= render "devise/shared/links" %> +
+
+
diff --git a/app/views/devise/passwords/new.html.erb b/app/views/devise/passwords/new.html.erb new file mode 100644 index 00000000..e61d4707 --- /dev/null +++ b/app/views/devise/passwords/new.html.erb @@ -0,0 +1,20 @@ +
+
+

Reset your password

+ <%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> +

Enter your email address below and we will send you a link to reset your password.

+ +
+ <%= f.email_field :email, autofocus: true, placeholder: 'Email address', class: 'form-control' %> +
+ +
+ <%= f.submit "Send password reset email", class: 'btn btn-primary btn-lg' %> +
+ <% end %> +
+ <%= render "devise/shared/links" %> +
+
+
diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb new file mode 100644 index 00000000..cce3da8d --- /dev/null +++ b/app/views/devise/registrations/edit.html.erb @@ -0,0 +1,49 @@ +
+
+

Account

+ + <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> + +
+ <%= f.text_field :name, autofocus: false, class: 'form-control', placeholder: "Full name" %> +
+ +
+ <%= f.email_field :email, class: 'form-control', placeholder: 'Email Address' %> +
+ +
+ <%= f.label :avatar, class: "form-label" %> + <%= f.file_field :avatar, accept:'image/*' %> +
+ + <%= image_tag avatar_path(f.object), class: "rounded border shadow-sm d-block mx-auto my-3" %> + + <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %> +
Currently waiting confirmation for: <%= resource.unconfirmed_email %>
+ <% end %> + +
+ <%= f.password_field :password, autocomplete: "off", class: 'form-control', placeholder: 'Password' %> +

Leave password blank if you don't want to change it

+
+ +
+ <%= f.password_field :password_confirmation, autocomplete: "off", class: 'form-control', placeholder: 'Confirm Password' %> +
+ +
+ <%= f.password_field :current_password, autocomplete: "off", class: 'form-control', placeholder: 'Current Password' %> +

We need your current password to confirm your changes

+
+ +
+ <%= f.submit "Save Changes", class: 'btn btn-lg btn-primary' %> +
+ <% end %> +
+ +

<%= link_to "Deactivate my account", registration_path(resource_name), data: { confirm: "Are you sure? You cannot undo this." }, method: :delete %>

+
+
diff --git a/app/views/devise/registrations/new.html.erb b/app/views/devise/registrations/new.html.erb new file mode 100644 index 00000000..221762a3 --- /dev/null +++ b/app/views/devise/registrations/new.html.erb @@ -0,0 +1,33 @@ +
+
+

Sign Up

+ + <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> + +
+ <%= f.text_field :name, autofocus: false, class: 'form-control', placeholder: "Full name" %> +
+ +
+ <%= f.email_field :email, autofocus: false, class: 'form-control', placeholder: "Email Address" %> +
+ +
+ <%= f.password_field :password, autocomplete: "off", class: 'form-control', placeholder: 'Password' %> +
+ +
+ <%= f.password_field :password_confirmation, autocomplete: "off", class: 'form-control', placeholder: 'Confirm Password' %> +
+ +
+ <%= f.submit "Sign up", class: "btn btn-primary btn-lg" %> +
+ <% end %> + +
+ <%= render "devise/shared/links" %> +
+
+
diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb new file mode 100644 index 00000000..cb089411 --- /dev/null +++ b/app/views/devise/sessions/new.html.erb @@ -0,0 +1,32 @@ +
+
+

Log in

+ + <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %> +
+ <%= f.email_field :email, autofocus: true, placeholder: 'Email Address', class: 'form-control' %> +
+ +
+ <%= f.password_field :password, autocomplete: "off", placeholder: 'Password', class: 'form-control' %> +
+ + <% if devise_mapping.rememberable? -%> +
+ +
+ <% end -%> + +
+ <%= f.submit "Log in", class: "btn btn-primary btn-lg" %> +
+ <% end %> + +
+ <%= render "devise/shared/links" %> +
+
+
diff --git a/app/views/devise/shared/_error_messages.html.erb b/app/views/devise/shared/_error_messages.html.erb new file mode 100644 index 00000000..cc741938 --- /dev/null +++ b/app/views/devise/shared/_error_messages.html.erb @@ -0,0 +1,15 @@ +<% if resource.errors.any? %> +
+
+ <%= I18n.t("errors.messages.not_saved", + count: resource.errors.count, + resource: resource.class.model_name.human.downcase) + %> +
+
    + <% resource.errors.full_messages.each do |message| %> +
  • <%= message %>
  • + <% end %> +
+
+<% end %> diff --git a/app/views/devise/shared/_links.html.erb b/app/views/devise/shared/_links.html.erb new file mode 100644 index 00000000..96a94124 --- /dev/null +++ b/app/views/devise/shared/_links.html.erb @@ -0,0 +1,25 @@ +<%- if controller_name != 'sessions' %> + <%= link_to "Log in", new_session_path(resource_name) %>
+<% end %> + +<%- if devise_mapping.registerable? && controller_name != 'registrations' %> + <%= link_to "Sign up", new_registration_path(resource_name) %>
+<% end %> + +<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %> + <%= link_to "Forgot your password?", new_password_path(resource_name) %>
+<% end %> + +<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %> + <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %>
+<% end %> + +<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %> + <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %>
+<% end %> + +<%- if devise_mapping.omniauthable? %> + <%- resource_class.omniauth_providers.each do |provider| %> + <%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), method: :post %>
+ <% end %> +<% end %> diff --git a/app/views/devise/unlocks/new.html.erb b/app/views/devise/unlocks/new.html.erb new file mode 100644 index 00000000..33a4fa72 --- /dev/null +++ b/app/views/devise/unlocks/new.html.erb @@ -0,0 +1,20 @@ +
+
+

Resend unlock instructions

+ + <%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %> + <%= render "devise/shared/error_messages", resource: resource %> + +
+ <%= f.label :email, class: "form-label" %> + <%= f.email_field :email, autofocus: true, autocomplete: "email", class: "form-control" %> +
+ +
+ <%= f.submit "Resend unlock instructions", class: "btn btn-lg btn-primary" %> +
+ <% end %> + + <%= render "devise/shared/links" %> +
+
diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb new file mode 100644 index 00000000..b4b4788d --- /dev/null +++ b/app/views/home/index.html.erb @@ -0,0 +1,2 @@ +

Welcome to Jumpstart!

+

Use this document as a way to quickly start any new project.
All you get is this text and a mostly barebones HTML document.

diff --git a/app/views/home/privacy.html.erb b/app/views/home/privacy.html.erb new file mode 100644 index 00000000..a3ee85b6 --- /dev/null +++ b/app/views/home/privacy.html.erb @@ -0,0 +1,2 @@ +

Privacy Policy

+

Use this for your Privacy Policy

diff --git a/app/views/home/terms.html.erb b/app/views/home/terms.html.erb new file mode 100644 index 00000000..234d2356 --- /dev/null +++ b/app/views/home/terms.html.erb @@ -0,0 +1,2 @@ +

Terms of Service

+

Use this for your Terms of Service

diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index e62b8000..9be6b640 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -1,16 +1,19 @@ - + - Myapp - - <%= csrf_meta_tags %> - <%= csp_meta_tag %> - - <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> - <%= javascript_include_tag "application", "data-turbo-track": "reload", type: "module" %> + <%= render 'shared/head' %> - - <%= yield %> + +
+ <%= render 'shared/navbar' %> + <%= render 'shared/notices' %> + +
+ <%= yield %> +
+
+ + <%= render 'shared/footer' %> diff --git a/app/views/notifications/index.html.erb b/app/views/notifications/index.html.erb new file mode 100644 index 00000000..d8069d16 --- /dev/null +++ b/app/views/notifications/index.html.erb @@ -0,0 +1,10 @@ +

Notifications

+ + diff --git a/app/views/pwa/manifest.json.erb b/app/views/pwa/manifest.json.erb new file mode 100644 index 00000000..47a2f931 --- /dev/null +++ b/app/views/pwa/manifest.json.erb @@ -0,0 +1,22 @@ +{ + "name": "Canine", + "icons": [ + { + "src": "/icon.png", + "type": "image/png", + "sizes": "512x512" + }, + { + "src": "/icon.png", + "type": "image/png", + "sizes": "512x512", + "purpose": "maskable" + } + ], + "start_url": "/", + "display": "standalone", + "scope": "/", + "description": "Canine.", + "theme_color": "red", + "background_color": "red" +} diff --git a/app/views/pwa/service-worker.js b/app/views/pwa/service-worker.js new file mode 100644 index 00000000..b3a13fb7 --- /dev/null +++ b/app/views/pwa/service-worker.js @@ -0,0 +1,26 @@ +// Add a service worker for processing Web Push notifications: +// +// self.addEventListener("push", async (event) => { +// const { title, options } = await event.data.json() +// event.waitUntil(self.registration.showNotification(title, options)) +// }) +// +// self.addEventListener("notificationclick", function(event) { +// event.notification.close() +// event.waitUntil( +// clients.matchAll({ type: "window" }).then((clientList) => { +// for (let i = 0; i < clientList.length; i++) { +// let client = clientList[i] +// let clientPath = (new URL(client.url)).pathname +// +// if (clientPath == event.notification.data.path && "focus" in client) { +// return client.focus() +// } +// } +// +// if (clients.openWindow) { +// return clients.openWindow(event.notification.data.path) +// } +// }) +// ) +// }) diff --git a/app/views/shared/_footer.html.erb b/app/views/shared/_footer.html.erb new file mode 100644 index 00000000..38604308 --- /dev/null +++ b/app/views/shared/_footer.html.erb @@ -0,0 +1,10 @@ +
+
+ © <%= Date.today.year %> Your Company +
    +
  • <%= link_to "Terms", terms_path %>
  • +
  • <%= link_to "Privacy", privacy_path %>
  • +
+
+
+ diff --git a/app/views/shared/_head.html.erb b/app/views/shared/_head.html.erb new file mode 100644 index 00000000..1bc68f44 --- /dev/null +++ b/app/views/shared/_head.html.erb @@ -0,0 +1,10 @@ +<%= Rails.configuration.application_name %> + + + +<%= csrf_meta_tags %> +<%= csp_meta_tag %> + + +<%= stylesheet_link_tag "application", media: "all", "data-turbo-track": "reload" %> +<%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %> diff --git a/app/views/shared/_navbar.html.erb b/app/views/shared/_navbar.html.erb new file mode 100644 index 00000000..bd02fa1b --- /dev/null +++ b/app/views/shared/_navbar.html.erb @@ -0,0 +1,52 @@ +<% if current_user != true_user %> +
+ You're logged in as <%= current_user.name %> (<%= current_user.email %>) + <%= link_to stop_impersonating_madmin_impersonates_path, method: :post do %><%= icon("fas", "times") %> Logout <% end %> +
+<% end %> + + diff --git a/app/views/shared/_notices.html.erb b/app/views/shared/_notices.html.erb new file mode 100644 index 00000000..fca73855 --- /dev/null +++ b/app/views/shared/_notices.html.erb @@ -0,0 +1,8 @@ +<% flash.each do |msg_type, message| %> +
+ +
+<% end %> diff --git a/bin/brakeman b/bin/brakeman new file mode 100755 index 00000000..ace1c9ba --- /dev/null +++ b/bin/brakeman @@ -0,0 +1,7 @@ +#!/usr/bin/env ruby +require "rubygems" +require "bundler/setup" + +ARGV.unshift("--ensure-latest") + +load Gem.bin_path("brakeman", "brakeman") diff --git a/bin/docker-entrypoint b/bin/docker-entrypoint index 67ef4931..840d093a 100755 --- a/bin/docker-entrypoint +++ b/bin/docker-entrypoint @@ -1,5 +1,10 @@ #!/bin/bash -e +# Enable jemalloc for reduced memory usage and latency. +if [ -z "${LD_PRELOAD+x}" ] && [ -f /usr/lib/*/libjemalloc.so.2 ]; then + export LD_PRELOAD="$(echo /usr/lib/*/libjemalloc.so.2)" +fi + # If running the rails server then create or migrate existing database if [ "${1}" == "./bin/rails" ] && [ "${2}" == "server" ]; then ./bin/rails db:prepare diff --git a/bin/jobs b/bin/jobs deleted file mode 100755 index dcf59f30..00000000 --- a/bin/jobs +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env ruby - -require_relative "../config/environment" -require "solid_queue/cli" - -SolidQueue::Cli.start(ARGV) diff --git a/bin/rubocop b/bin/rubocop new file mode 100755 index 00000000..40330c0f --- /dev/null +++ b/bin/rubocop @@ -0,0 +1,8 @@ +#!/usr/bin/env ruby +require "rubygems" +require "bundler/setup" + +# explicit rubocop config increases performance slightly while avoiding config confusion. +ARGV.unshift("--config", File.expand_path("../.rubocop.yml", __dir__)) + +load Gem.bin_path("rubocop", "rubocop") diff --git a/bin/setup b/bin/setup index 3cd5a9d7..8048181f 100755 --- a/bin/setup +++ b/bin/setup @@ -1,8 +1,8 @@ #!/usr/bin/env ruby require "fileutils" -# path to your application root. APP_ROOT = File.expand_path("..", __dir__) +APP_NAME = "canine" def system!(*args) system(*args, exception: true) @@ -30,4 +30,8 @@ FileUtils.chdir APP_ROOT do puts "\n== Restarting application server ==" system! "bin/rails restart" + + # puts "\n== Configuring puma-dev ==" + # system "ln -nfs #{APP_ROOT} ~/.puma-dev/#{APP_NAME}" + # system "curl -Is https://#{APP_NAME}.test/up | head -n 1" end diff --git a/bin/spring b/bin/spring deleted file mode 100755 index b4147e84..00000000 --- a/bin/spring +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env ruby -if !defined?(Spring) && [nil, "development", "test"].include?(ENV["RAILS_ENV"]) - gem "bundler" - require "bundler" - - # Load Spring without loading other gems in the Gemfile, for speed. - Bundler.locked_gems&.specs&.find { |spec| spec.name == "spring" }&.tap do |spring| - Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path - gem "spring", spring.version - require "spring/binstub" - rescue Gem::LoadError - # Ignore when Spring is not installed. - end -end diff --git a/bin/yarn b/bin/yarn deleted file mode 100755 index 9fab2c35..00000000 --- a/bin/yarn +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env ruby -APP_ROOT = File.expand_path('..', __dir__) -Dir.chdir(APP_ROOT) do - yarn = ENV["PATH"].split(File::PATH_SEPARATOR). - select { |dir| File.expand_path(dir) != __dir__ }. - product(["yarn", "yarn.cmd", "yarn.ps1"]). - map { |dir, file| File.expand_path(file, dir) }. - find { |file| File.executable?(file) } - - if yarn - exec yarn, *ARGV - else - $stderr.puts "Yarn executable was not detected in the system." - $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" - exit 1 - end -end diff --git a/config/application.rb b/config/application.rb index 01b65036..7fcd6993 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,17 +1,17 @@ -require_relative 'boot' +require_relative "boot" -require 'rails/all' +require "rails/all" # Require the gems listed in Gemfile, including any gems # you've limited to :test, :development, or :production. Bundler.require(*Rails.groups) -module Myapp +module Canine class Application < Rails::Application - config.active_job.queue_adapter = :solid_queue + config.active_job.queue_adapter = :sidekiq config.application_name = Rails.application.class.module_parent_name # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 7.1 + config.load_defaults 7.2 # Please, add to the `ignore` list any other `lib` subdirectories that do # not contain `.rb` files, or that should not be reloaded or eager loaded. diff --git a/config/cable.yml b/config/cable.yml index d7187d2e..02c3701c 100644 --- a/config/cable.yml +++ b/config/cable.yml @@ -1,10 +1,13 @@ development: - adapter: async + adapter: redis + url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> + channel_prefix: streaming_logs_dev test: - adapter: test + adapter: async production: adapter: redis url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> - channel_prefix: myapp_production + channel_prefix: streaming_logs_production + diff --git a/config/credentials.yml.enc b/config/credentials.yml.enc index b14d4e55..ffe36a56 100644 --- a/config/credentials.yml.enc +++ b/config/credentials.yml.enc @@ -1 +1 @@ -PEzPdJUKmNRCTqH7uOwK+h7Ko4LqYTmd3gX/GHfnFcn78wPYjtxWnZv+H1r3HDgT//f9k2JbbPuVl92E4GVWKC18yg9HXRl+zIi7rCevzddV0oOMwAFcVe2xCjQS3LG2DklsgnIGYGtU2ow4nUamRB9pLcRKobPRgynNTfjeO2GlNp5Bq4pPvm2W8Em0xeDikyYan6AcymVF+kTsT3QkkeKF1t9tyqQXnQj+nKualN4C7OIK1XQ3ZZlQBcXF6g0AmybLgHitZ/wf85rnfl1jGINKjUImiNzhLEsPMNgcO30wXxk/ez9rBuqlgXZ2nX6eS3ob3DtXHqZS/jq/3TlfuSfsTbxTD1hpDQp9PFU4Su0TOxwSP6d/zm8qqKbZPJzLnSo7muX0/5/0CUHcOhYNql+qgC/I9lAbNuSm--27b3pgOwA2/LYVK7--7IW2AxrQub9OzeJ2nEUUkQ== \ No newline at end of file +2GDotYiS+i/6O3YBAAhdxq+Vwog5saS6ESDpLsWP02I79aLa+dRsjU8WAG+tKHE2PCB5kJpSbBfRRoZs8pqmq9S/fyzo4wTM7EPzHKnyvslM+57d6zFt1zk5E1OMsGyWFV6SK0zRTEDVb5oB7m7nklrU9u0SMR0QVC2YgL2gQ6qEthI7kP4qZBs78Zu9CAZEsVUWqZJgT1N/Kt3Wvz7XA39oElkjLn8n024prV4HrPjJJDQRtXa4+TsDnyz+e21yDpHgMnaGbFCWIpqNU54XQjLBbfw+/Q/O2R50Ruxkx5/RrlExrXo3C6Re2maoSwxDRdq5Ll/ai8CzxaPCWOTUO16dMJ9eBd9L9j+Tgv5HJN9w2adAhRWWQBbQJ9nABaswyD58mi7YkOmmiVdH2gq+4W+0TRKg--ZzU43VlUkcayEFNt--oZ59MtodBAD20i6fm+cpXA== \ No newline at end of file diff --git a/config/database.yml b/config/database.yml index 932f9486..d406a582 100644 --- a/config/database.yml +++ b/config/database.yml @@ -19,15 +19,16 @@ default: &default # https://guides.rubyonrails.org/configuring.html#database-pooling pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> + development: <<: *default - database: myapp_development + database: canine_development # The specified database role being used to connect to PostgreSQL. # To create additional roles in PostgreSQL see `$ createuser --help`. # When left blank, PostgreSQL will use the default role. This is # the same name as the operating system user running Rails. - #username: myapp + #username: canine # The password associated with the PostgreSQL role (username). #password: @@ -55,7 +56,7 @@ development: # Do not set this db to the same as development or production. test: <<: *default - database: myapp_test + database: canine_test # As with config/credentials.yml, you never want to store sensitive information, # like your database password, in your source code. If your source code is @@ -79,6 +80,6 @@ test: # production: <<: *default - database: myapp_production - username: myapp - password: <%= ENV["MYAPP_DATABASE_PASSWORD"] %> + database: canine_production + username: canine + password: <%= ENV["CANINE_DATABASE_PASSWORD"] %> diff --git a/config/environments/development.rb b/config/environments/development.rb index 67144cdd..ba0f4ec1 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -1,8 +1,7 @@ -require 'active_support/core_ext/integer/time' +require "active_support/core_ext/integer/time" Rails.application.configure do - config.hosts << /.*\.github\.dev/ - config.action_controller.allow_forgery_protection = false + config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } # Settings specified here will take precedence over those in config/application.rb. # In the development environment your application's code is reloaded any time @@ -16,19 +15,17 @@ Rails.application.configure do # Show full error reports. config.consider_all_requests_local = true - # Enable server timing + # Enable server timing. config.server_timing = true # Enable/disable caching. By default caching is disabled. # Run rails dev:cache to toggle caching. - if Rails.root.join('tmp/caching-dev.txt').exist? + if Rails.root.join("tmp/caching-dev.txt").exist? config.action_controller.perform_caching = true config.action_controller.enable_fragment_cache_logging = true config.cache_store = :memory_store - config.public_file_server.headers = { - 'Cache-Control' => "public, max-age=#{2.days.to_i}" - } + config.public_file_server.headers = { "Cache-Control" => "public, max-age=#{2.days.to_i}" } else config.action_controller.perform_caching = false @@ -41,8 +38,12 @@ Rails.application.configure do # Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = false + # Disable caching for Action Mailer templates even if Action Controller + # caching is enabled. config.action_mailer.perform_caching = false + config.action_mailer.default_url_options = { host: "localhost", port: 3000 } + # Print deprecation notices to the Rails logger. config.active_support.deprecation = :log @@ -68,11 +69,14 @@ Rails.application.configure do # config.i18n.raise_on_missing_translations = true # Annotate rendered view with file names. - # config.action_view.annotate_rendered_view_with_filenames = true + config.action_view.annotate_rendered_view_with_filenames = true # Uncomment if you wish to allow Action Cable access from any origin. # config.action_cable.disable_request_forgery_protection = true - # Raise error when a before_action's only/except options reference missing actions + # Raise error when a before_action's only/except options reference missing actions. config.action_controller.raise_on_missing_callback_actions = true + + # Apply autocorrection by RuboCop to files generated by `bin/rails generate`. + # config.generators.apply_rubocop_autocorrect_after_generate! end diff --git a/config/environments/production.rb b/config/environments/production.rb index af53f4b3..7d2271bb 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -51,6 +51,9 @@ Rails.application.configure do # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. config.force_ssl = true + # Skip http-to-https redirect for the default health check endpoint. + # config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } } + # Log to STDOUT by default config.logger = ActiveSupport::Logger.new(STDOUT) .tap { |logger| logger.formatter = ::Logger::Formatter.new } @@ -68,11 +71,11 @@ Rails.application.configure do # config.cache_store = :mem_cache_store # Use a real queuing backend for Active Job (and separate queues per environment). - config.active_job.queue_adapter = :solid_queue - config.solid_queue.connects_to = { database: { writing: :queue } } - - # config.active_job.queue_name_prefix = "myapp_production" + # config.active_job.queue_adapter = :resque + # config.active_job.queue_name_prefix = "canine_production" + # Disable caching for Action Mailer templates even if Action Controller + # caching is enabled. config.action_mailer.perform_caching = false # Ignore bad email addresses and do not raise email delivery errors. diff --git a/config/environments/test.rb b/config/environments/test.rb index adbb4a6f..0c616a1b 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -18,10 +18,7 @@ Rails.application.configure do config.eager_load = ENV["CI"].present? # Configure public file server for tests with Cache-Control for performance. - config.public_file_server.enabled = true - config.public_file_server.headers = { - "Cache-Control" => "public, max-age=#{1.hour.to_i}" - } + config.public_file_server.headers = { "Cache-Control" => "public, max-age=#{1.hour.to_i}" } # Show full error reports and disable caching. config.consider_all_requests_local = true @@ -37,6 +34,8 @@ Rails.application.configure do # Store uploaded files on the local file system in a temporary directory. config.active_storage.service = :test + # Disable caching for Action Mailer templates even if Action Controller + # caching is enabled. config.action_mailer.perform_caching = false # Tell Action Mailer not to deliver emails to the real world. @@ -44,6 +43,10 @@ Rails.application.configure do # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test + # Unlike controllers, the mailer instance doesn't have any context about the + # incoming request so you'll need to provide the :host parameter yourself. + config.action_mailer.default_url_options = { host: "www.example.com" } + # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr @@ -59,6 +62,6 @@ Rails.application.configure do # Annotate rendered view with file names. # config.action_view.annotate_rendered_view_with_filenames = true - # Raise error when a before_action's only/except options reference missing actions + # Raise error when a before_action's only/except options reference missing actions. config.action_controller.raise_on_missing_callback_actions = true end diff --git a/config/initializers/application_controller_renderer.rb b/config/initializers/application_controller_renderer.rb deleted file mode 100644 index 89d2efab..00000000 --- a/config/initializers/application_controller_renderer.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# ActiveSupport::Reloader.to_prepare do -# ApplicationController.renderer.defaults.merge!( -# http_host: 'example.org', -# https: false -# ) -# end diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index 58275b40..d4b0b6b0 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -10,4 +10,4 @@ Rails.application.config.assets.paths << Rails.root.join("node_modules/bootstrap # Precompile additional assets. # application.js, application.css, and all non-JS/CSS in the app/assets # folder are already added. -# Rails.application.config.assets.precompile += %w( admin.js admin.css ) +# Rails.application.config.assets.precompile += %w[ admin.js admin.css ] diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb deleted file mode 100644 index 33699c30..00000000 --- a/config/initializers/backtrace_silencers.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. -# Rails.backtrace_cleaner.add_silencer { |line| /my_noisy_library/.match?(line) } - -# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code -# by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'". -Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"] diff --git a/config/initializers/cookies_serializer.rb b/config/initializers/cookies_serializer.rb deleted file mode 100644 index 5a6a32d3..00000000 --- a/config/initializers/cookies_serializer.rb +++ /dev/null @@ -1,5 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Specify a serializer for the signed and encrypted cookie jars. -# Valid options are :json, :marshal, and :hybrid. -Rails.application.config.action_dispatch.cookies_serializer = :json diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index cf03680b..2ccfc37e 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -126,7 +126,7 @@ Devise.setup do |config| config.stretches = Rails.env.test? ? 1 : 12 # Set up a pepper to generate the hashed password. - # config.pepper = '7ca924439345cb08813468fffcb208affed90964f9fa0df53c6745e16481b84c7f26fcc1253183f00c4ec36fdc37a2c9c8f99e3d64dd7e091b0cfc5d0b516ead' + # config.pepper = 'b19829491f2f6aa8de30412efc6aeb2288b4fc5029c1aca7c993a053476184cf3df1417b645cb22124d5901ea3cb99aa910d3ad4d5d145a4176a275f15155b16' # Send a notification to the original email when the user's email is changed. # config.send_email_changed_notification = false @@ -273,14 +273,12 @@ Devise.setup do |config| # up on your models and hooks. # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' - env_creds = Rails.application.credentials[Rails.env.to_sym] || {} %i{ facebook twitter github }.each do |provider| if options = env_creds[provider] config.omniauth provider, options[:app_id], options[:app_secret], options.fetch(:options, {}) end end - # ==> Warden configuration # If you want to use other strategies, that are not supported by Devise, or diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb index c2d89e28..c010b83d 100644 --- a/config/initializers/filter_parameter_logging.rb +++ b/config/initializers/filter_parameter_logging.rb @@ -4,5 +4,5 @@ # Use this to limit dissemination of sensitive information. # See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. Rails.application.config.filter_parameters += [ - :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn + :passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn ] diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb deleted file mode 100644 index dc189968..00000000 --- a/config/initializers/mime_types.rb +++ /dev/null @@ -1,4 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Add new mime types for use in respond_to blocks: -# Mime::Type.register "text/richtext", :rtf diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb deleted file mode 100644 index bbfc3961..00000000 --- a/config/initializers/wrap_parameters.rb +++ /dev/null @@ -1,14 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# This file contains settings for ActionController::ParamsWrapper which -# is enabled by default. - -# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. -ActiveSupport.on_load(:action_controller) do - wrap_parameters format: [:json] -end - -# To enable root element in JSON for ActiveRecord objects. -# ActiveSupport.on_load(:active_record) do -# self.include_root_in_json = true -# end diff --git a/config/puma.rb b/config/puma.rb index 7a709d7b..03c166f4 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -2,43 +2,33 @@ # are invoked here are part of Puma's configuration DSL. For more information # about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html. -# Puma can serve each request in a thread from an internal thread pool. -# The `threads` method setting takes two numbers: a minimum and maximum. -# Any libraries that use thread pools should be configured to match -# the maximum value specified for Puma. Default is set to 5 threads for minimum -# and maximum; this matches the default thread size of Active Record. -max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } -min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } -threads min_threads_count, max_threads_count - -rails_env = ENV.fetch("RAILS_ENV") { "development" } - -if rails_env == "production" - # If you are running more than 1 thread per process, the workers count - # should be equal to the number of processors (CPU cores) in production. - # - # It defaults to 1 because it's impossible to reliably detect how many - # CPU cores are available. Make sure to set the `WEB_CONCURRENCY` environment - # variable to match the number of processors. - worker_count = Integer(ENV.fetch("WEB_CONCURRENCY") { 1 }) - if worker_count > 1 - workers worker_count - else - preload_app! - end -end -# Specifies the `worker_timeout` threshold that Puma will use to wait before -# terminating a worker in development environments. -worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development" +# Puma starts a configurable number of processes (workers) and each process +# serves each request in a thread from an internal thread pool. +# +# The ideal number of threads per worker depends both on how much time the +# application spends waiting for IO operations and on how much you wish to +# to prioritize throughput over latency. +# +# As a rule of thumb, increasing the number of threads will increase how much +# traffic a given process can handle (throughput), but due to CRuby's +# Global VM Lock (GVL) it has diminishing returns and will degrade the +# response time (latency) of the application. +# +# The default is set to 3 threads as it's deemed a decent compromise between +# throughput and latency for the average Rails application. +# +# Any libraries that use a connection pool or another resource pool should +# be configured to provide at least as many connections as the number of +# threads. This includes Active Record's `pool` parameter in `database.yml`. +threads_count = ENV.fetch("RAILS_MAX_THREADS", 3) +threads threads_count, threads_count # Specifies the `port` that Puma will listen on to receive requests; default is 3000. -port ENV.fetch("PORT") { 3000 } - -# Specifies the `environment` that Puma will run in. -environment rails_env - -# Specifies the `pidfile` that Puma will use. -pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" } +port ENV.fetch("PORT", 3000) # Allow puma to be restarted by `bin/rails restart` command. plugin :tmp_restart + +# Specify the PID file. Defaults to tmp/pids/server.pid in development. +# In other environments, only set the PID file if requested. +pidfile ENV["PIDFILE"] if ENV["PIDFILE"] diff --git a/config/queue.yml b/config/queue.yml deleted file mode 100644 index 9eace59c..00000000 --- a/config/queue.yml +++ /dev/null @@ -1,18 +0,0 @@ -default: &default - dispatchers: - - polling_interval: 1 - batch_size: 500 - workers: - - queues: "*" - threads: 3 - processes: <%= ENV.fetch("JOB_CONCURRENCY", 1) %> - polling_interval: 0.1 - -development: - <<: *default - -test: - <<: *default - -production: - <<: *default diff --git a/config/recurring.yml b/config/recurring.yml deleted file mode 100644 index 2f919f0d..00000000 --- a/config/recurring.yml +++ /dev/null @@ -1,9 +0,0 @@ -# periodic_cleanup: -# class: CleanSoftDeletedRecordsJob -# queue: background -# args: [ 1000, { batch_size: 500 } ] -# schedule: every hour -# periodic_command: -# command: "SoftDeletedRecord.due.delete_all" -# priority: 2 -# schedule: at 5am every day diff --git a/config/routes.rb b/config/routes.rb index 0e5ed4ab..9ef1eddf 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,22 +1,32 @@ +require 'sidekiq/web' + Rails.application.routes.draw do - authenticate :user, ->(u) { u.admin? } do - namespace :madmin do - resources :impersonates do - post :impersonate, on: :member - post :stop_impersonating, on: :collection - end + get '/privacy', to: 'home#privacy' + get '/terms', to: 'home#terms' +authenticate :user, lambda { |u| u.admin? } do + mount Sidekiq::Web => '/sidekiq' + + namespace :madmin do + resources :impersonates do + post :impersonate, on: :member + post :stop_impersonating, on: :collection end end +end resources :notifications, only: [:index] resources :announcements, only: [:index] - devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' } + devise_for :users, controllers: { omniauth_callbacks: "users/omniauth_callbacks" } root to: 'home#index' # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. # Can be used by load balancers and uptime monitors to verify that the app is live. - get 'up' => 'rails/health#show', as: :rails_health_check + get "up" => "rails/health#show", as: :rails_health_check + + # Render dynamic PWA files from app/views/pwa/* + get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker + get "manifest" => "rails/pwa#manifest", as: :pwa_manifest # Defines the root path route ("/") # root "posts#index" diff --git a/config/solid_queue.yml b/config/solid_queue.yml deleted file mode 100644 index 2d8d922f..00000000 --- a/config/solid_queue.yml +++ /dev/null @@ -1,18 +0,0 @@ -# default: &default -# dispatchers: -# - polling_interval: 1 -# batch_size: 500 -# workers: -# - queues: "*" -# threads: 3 -# processes: 1 -# polling_interval: 0.1 -# -# development: -# <<: *default -# -# test: -# <<: *default -# -# production: -# <<: *default diff --git a/config/spring.rb b/config/spring.rb deleted file mode 100644 index db5bf130..00000000 --- a/config/spring.rb +++ /dev/null @@ -1,6 +0,0 @@ -Spring.watch( - ".ruby-version", - ".rbenv-vars", - "tmp/restart.txt", - "tmp/caching-dev.txt" -) diff --git a/db/migrate/20240925185426_create_clusters.rb b/db/migrate/20240925185426_create_clusters.rb deleted file mode 100644 index 75e0840e..00000000 --- a/db/migrate/20240925185426_create_clusters.rb +++ /dev/null @@ -1,11 +0,0 @@ -class CreateClusters < ActiveRecord::Migration[7.1] - def change - create_table :clusters do |t| - t.string :name, null: false - t.jsonb :kubeconfig, null: false, default: {} - t.references :user, null: false, foreign_key: true - - t.timestamps - end - end -end diff --git a/db/migrate/20240925184128_devise_create_users.rb b/db/migrate/20240925205144_devise_create_users.rb similarity index 96% rename from db/migrate/20240925184128_devise_create_users.rb rename to db/migrate/20240925205144_devise_create_users.rb index 3ae93e2f..e16b56fe 100644 --- a/db/migrate/20240925184128_devise_create_users.rb +++ b/db/migrate/20240925205144_devise_create_users.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class DeviseCreateUsers < ActiveRecord::Migration[7.1] +class DeviseCreateUsers < ActiveRecord::Migration[7.2] def change create_table :users do |t| ## Database authenticatable diff --git a/db/migrate/20240925184133_create_announcements.rb b/db/migrate/20240925205147_create_announcements.rb similarity index 77% rename from db/migrate/20240925184133_create_announcements.rb rename to db/migrate/20240925205147_create_announcements.rb index 17b434bc..a81cd076 100644 --- a/db/migrate/20240925184133_create_announcements.rb +++ b/db/migrate/20240925205147_create_announcements.rb @@ -1,4 +1,4 @@ -class CreateAnnouncements < ActiveRecord::Migration[7.1] +class CreateAnnouncements < ActiveRecord::Migration[7.2] def change create_table :announcements do |t| t.datetime :published_at diff --git a/db/migrate/20240925184134_create_noticed_tables.noticed.rb b/db/migrate/20240925205148_create_noticed_tables.noticed.rb similarity index 100% rename from db/migrate/20240925184134_create_noticed_tables.noticed.rb rename to db/migrate/20240925205148_create_noticed_tables.noticed.rb diff --git a/db/migrate/20240925184135_add_notifications_count_to_noticed_event.noticed.rb b/db/migrate/20240925205149_add_notifications_count_to_noticed_event.noticed.rb similarity index 100% rename from db/migrate/20240925184135_add_notifications_count_to_noticed_event.noticed.rb rename to db/migrate/20240925205149_add_notifications_count_to_noticed_event.noticed.rb diff --git a/db/migrate/20240925184136_create_services.rb b/db/migrate/20240925205150_create_services.rb similarity index 86% rename from db/migrate/20240925184136_create_services.rb rename to db/migrate/20240925205150_create_services.rb index af05d925..a9f7ec43 100644 --- a/db/migrate/20240925184136_create_services.rb +++ b/db/migrate/20240925205150_create_services.rb @@ -1,4 +1,4 @@ -class CreateServices < ActiveRecord::Migration[7.1] +class CreateServices < ActiveRecord::Migration[7.2] def change create_table :services do |t| t.references :user, null: false, foreign_key: true diff --git a/db/migrate/20240925184137_create_friendly_id_slugs.rb b/db/migrate/20240925205151_create_friendly_id_slugs.rb similarity index 100% rename from db/migrate/20240925184137_create_friendly_id_slugs.rb rename to db/migrate/20240925205151_create_friendly_id_slugs.rb diff --git a/db/migrate/20240925184150_create_active_storage_tables.active_storage.rb b/db/migrate/20240925205204_create_active_storage_tables.active_storage.rb similarity index 97% rename from db/migrate/20240925184150_create_active_storage_tables.active_storage.rb rename to db/migrate/20240925205204_create_active_storage_tables.active_storage.rb index e4706aa2..6bd8bd08 100644 --- a/db/migrate/20240925184150_create_active_storage_tables.active_storage.rb +++ b/db/migrate/20240925205204_create_active_storage_tables.active_storage.rb @@ -52,6 +52,6 @@ class CreateActiveStorageTables < ActiveRecord::Migration[7.0] setting = config.options[config.orm][:primary_key_type] primary_key_type = setting || :primary_key foreign_key_type = setting || :bigint - [primary_key_type, foreign_key_type] + [ primary_key_type, foreign_key_type ] end end diff --git a/db/queue_schema.rb b/db/queue_schema.rb deleted file mode 100644 index 4b49a12a..00000000 --- a/db/queue_schema.rb +++ /dev/null @@ -1,129 +0,0 @@ -ActiveRecord::Schema[7.1].define(version: 2024_09_04_193154) do - create_table "solid_queue_blocked_executions", force: :cascade do |t| - t.bigint "job_id", null: false - t.string "queue_name", null: false - t.integer "priority", default: 0, null: false - t.string "concurrency_key", null: false - t.datetime "expires_at", null: false - t.datetime "created_at", null: false - t.index [ "concurrency_key", "priority", "job_id" ], name: "index_solid_queue_blocked_executions_for_release" - t.index [ "expires_at", "concurrency_key" ], name: "index_solid_queue_blocked_executions_for_maintenance" - t.index [ "job_id" ], name: "index_solid_queue_blocked_executions_on_job_id", unique: true - end - - create_table "solid_queue_claimed_executions", force: :cascade do |t| - t.bigint "job_id", null: false - t.bigint "process_id" - t.datetime "created_at", null: false - t.index [ "job_id" ], name: "index_solid_queue_claimed_executions_on_job_id", unique: true - t.index [ "process_id", "job_id" ], name: "index_solid_queue_claimed_executions_on_process_id_and_job_id" - end - - create_table "solid_queue_failed_executions", force: :cascade do |t| - t.bigint "job_id", null: false - t.text "error" - t.datetime "created_at", null: false - t.index [ "job_id" ], name: "index_solid_queue_failed_executions_on_job_id", unique: true - end - - create_table "solid_queue_jobs", force: :cascade do |t| - t.string "queue_name", null: false - t.string "class_name", null: false - t.text "arguments" - t.integer "priority", default: 0, null: false - t.string "active_job_id" - t.datetime "scheduled_at" - t.datetime "finished_at" - t.string "concurrency_key" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index [ "active_job_id" ], name: "index_solid_queue_jobs_on_active_job_id" - t.index [ "class_name" ], name: "index_solid_queue_jobs_on_class_name" - t.index [ "finished_at" ], name: "index_solid_queue_jobs_on_finished_at" - t.index [ "queue_name", "finished_at" ], name: "index_solid_queue_jobs_for_filtering" - t.index [ "scheduled_at", "finished_at" ], name: "index_solid_queue_jobs_for_alerting" - end - - create_table "solid_queue_pauses", force: :cascade do |t| - t.string "queue_name", null: false - t.datetime "created_at", null: false - t.index [ "queue_name" ], name: "index_solid_queue_pauses_on_queue_name", unique: true - end - - create_table "solid_queue_processes", force: :cascade do |t| - t.string "kind", null: false - t.datetime "last_heartbeat_at", null: false - t.bigint "supervisor_id" - t.integer "pid", null: false - t.string "hostname" - t.text "metadata" - t.datetime "created_at", null: false - t.string "name", null: false - t.index [ "last_heartbeat_at" ], name: "index_solid_queue_processes_on_last_heartbeat_at" - t.index [ "name", "supervisor_id" ], name: "index_solid_queue_processes_on_name_and_supervisor_id", unique: true - t.index [ "supervisor_id" ], name: "index_solid_queue_processes_on_supervisor_id" - end - - create_table "solid_queue_ready_executions", force: :cascade do |t| - t.bigint "job_id", null: false - t.string "queue_name", null: false - t.integer "priority", default: 0, null: false - t.datetime "created_at", null: false - t.index [ "job_id" ], name: "index_solid_queue_ready_executions_on_job_id", unique: true - t.index [ "priority", "job_id" ], name: "index_solid_queue_poll_all" - t.index [ "queue_name", "priority", "job_id" ], name: "index_solid_queue_poll_by_queue" - end - - create_table "solid_queue_recurring_executions", force: :cascade do |t| - t.bigint "job_id", null: false - t.string "task_key", null: false - t.datetime "run_at", null: false - t.datetime "created_at", null: false - t.index [ "job_id" ], name: "index_solid_queue_recurring_executions_on_job_id", unique: true - t.index [ "task_key", "run_at" ], name: "index_solid_queue_recurring_executions_on_task_key_and_run_at", unique: true - end - - create_table "solid_queue_recurring_tasks", force: :cascade do |t| - t.string "key", null: false - t.string "schedule", null: false - t.string "command", limit: 2048 - t.string "class_name" - t.text "arguments" - t.string "queue_name" - t.integer "priority", default: 0 - t.boolean "static", default: true, null: false - t.text "description" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index [ "key" ], name: "index_solid_queue_recurring_tasks_on_key", unique: true - t.index [ "static" ], name: "index_solid_queue_recurring_tasks_on_static" - end - - create_table "solid_queue_scheduled_executions", force: :cascade do |t| - t.bigint "job_id", null: false - t.string "queue_name", null: false - t.integer "priority", default: 0, null: false - t.datetime "scheduled_at", null: false - t.datetime "created_at", null: false - t.index [ "job_id" ], name: "index_solid_queue_scheduled_executions_on_job_id", unique: true - t.index [ "scheduled_at", "priority", "job_id" ], name: "index_solid_queue_dispatch_all" - end - - create_table "solid_queue_semaphores", force: :cascade do |t| - t.string "key", null: false - t.integer "value", default: 1, null: false - t.datetime "expires_at", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index [ "expires_at" ], name: "index_solid_queue_semaphores_on_expires_at" - t.index [ "key", "value" ], name: "index_solid_queue_semaphores_on_key_and_value" - t.index [ "key" ], name: "index_solid_queue_semaphores_on_key", unique: true - end - - add_foreign_key "solid_queue_blocked_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade - add_foreign_key "solid_queue_claimed_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade - add_foreign_key "solid_queue_failed_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade - add_foreign_key "solid_queue_ready_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade - add_foreign_key "solid_queue_recurring_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade - add_foreign_key "solid_queue_scheduled_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade -end diff --git a/db/schema.rb b/db/schema.rb deleted file mode 100644 index 8d1d33b4..00000000 --- a/db/schema.rb +++ /dev/null @@ -1,132 +0,0 @@ -# This file is auto-generated from the current state of the database. Instead -# of editing this file, please use the migrations feature of Active Record to -# incrementally modify your database, and then regenerate this schema definition. -# -# This file is the source Rails uses to define your schema when running `bin/rails -# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to -# be faster and is potentially less error prone than running all of your -# migrations from scratch. Old migrations may fail to apply correctly if those -# migrations use external dependencies or application code. -# -# It's strongly recommended that you check this file into your version control system. - -ActiveRecord::Schema[7.1].define(version: 2024_09_25_185426) do - # These are extensions that must be enabled in order to support this database - enable_extension "plpgsql" - - create_table "active_storage_attachments", force: :cascade do |t| - t.string "name", null: false - t.string "record_type", null: false - t.bigint "record_id", null: false - t.bigint "blob_id", null: false - t.datetime "created_at", null: false - t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id" - t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true - end - - create_table "active_storage_blobs", force: :cascade do |t| - t.string "key", null: false - t.string "filename", null: false - t.string "content_type" - t.text "metadata" - t.string "service_name", null: false - t.bigint "byte_size", null: false - t.string "checksum" - t.datetime "created_at", null: false - t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true - end - - create_table "active_storage_variant_records", force: :cascade do |t| - t.bigint "blob_id", null: false - t.string "variation_digest", null: false - t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true - end - - create_table "announcements", force: :cascade do |t| - t.datetime "published_at" - t.string "announcement_type" - t.string "name" - t.text "description" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - - create_table "clusters", force: :cascade do |t| - t.string "name", null: false - t.jsonb "kubeconfig", default: {}, null: false - t.bigint "user_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["user_id"], name: "index_clusters_on_user_id" - end - - create_table "friendly_id_slugs", force: :cascade do |t| - t.string "slug", null: false - t.integer "sluggable_id", null: false - t.string "sluggable_type", limit: 50 - t.string "scope" - t.datetime "created_at" - t.index ["slug", "sluggable_type", "scope"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type_and_scope", unique: true - t.index ["slug", "sluggable_type"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type" - t.index ["sluggable_type", "sluggable_id"], name: "index_friendly_id_slugs_on_sluggable_type_and_sluggable_id" - end - - create_table "noticed_events", force: :cascade do |t| - t.string "type" - t.string "record_type" - t.bigint "record_id" - t.jsonb "params" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "notifications_count" - t.index ["record_type", "record_id"], name: "index_noticed_events_on_record" - end - - create_table "noticed_notifications", force: :cascade do |t| - t.string "type" - t.bigint "event_id", null: false - t.string "recipient_type", null: false - t.bigint "recipient_id", null: false - t.datetime "read_at", precision: nil - t.datetime "seen_at", precision: nil - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["event_id"], name: "index_noticed_notifications_on_event_id" - t.index ["recipient_type", "recipient_id"], name: "index_noticed_notifications_on_recipient" - end - - create_table "services", force: :cascade do |t| - t.bigint "user_id", null: false - t.string "provider" - t.string "uid" - t.string "access_token" - t.string "access_token_secret" - t.string "refresh_token" - t.datetime "expires_at" - t.text "auth" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["user_id"], name: "index_services_on_user_id" - end - - create_table "users", force: :cascade do |t| - t.string "email", default: "", null: false - t.string "encrypted_password", default: "", null: false - t.string "reset_password_token" - t.datetime "reset_password_sent_at" - t.datetime "remember_created_at" - t.string "first_name" - t.string "last_name" - t.datetime "announcements_last_read_at" - t.boolean "admin", default: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["email"], name: "index_users_on_email", unique: true - t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true - end - - add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" - add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" - add_foreign_key "clusters", "users" - add_foreign_key "services", "users" -end diff --git a/esbuild.config.mjs b/esbuild.config.mjs new file mode 100644 index 00000000..2fe760ba --- /dev/null +++ b/esbuild.config.mjs @@ -0,0 +1,96 @@ +#!/usr/bin/env node + +// Esbuild is configured with 3 modes: +// +// `yarn build` - Build JavaScript and exit +// `yarn build --watch` - Rebuild JavaScript on change +// `yarn build --reload` - Reloads page when views, JavaScript, or stylesheets change +// +// Minify is enabled when "RAILS_ENV=production" +// Sourcemaps are enabled in non-production environments + +import * as esbuild from "esbuild" +import path from "path" +import rails from "esbuild-rails" +import chokidar from "chokidar" +import http from "http" +import { setTimeout } from "timers/promises" + +const clients = [] +const entryPoints = [ + "application.js" +] +const watchDirectories = [ + "./app/javascript/**/*.js", + "./app/views/**/*.erb", + "./app/assets/builds/**/*.css", // Wait for cssbundling changes +] +const config = { + absWorkingDir: path.join(process.cwd(), "app/javascript"), + bundle: true, + entryPoints: entryPoints, + minify: process.env.RAILS_ENV == "production", + outdir: path.join(process.cwd(), "app/assets/builds"), + plugins: [rails()], + sourcemap: process.env.RAILS_ENV != "production" +} + +async function buildAndReload() { + // Foreman & Overmind assign a separate PORT for each process + const port = parseInt(process.env.PORT) + const context = await esbuild.context({ + ...config, + banner: { + js: ` (() => new EventSource("http://localhost:${port}").onmessage = () => location.reload())();`, + } + }) + + // Reload uses an HTTP server as an even stream to reload the browser + http + .createServer((req, res) => { + return clients.push( + res.writeHead(200, { + "Content-Type": "text/event-stream", + "Cache-Control": "no-cache", + "Access-Control-Allow-Origin": "*", + Connection: "keep-alive", + }) + ) + }) + .listen(port) + + await context.rebuild() + console.log("[reload] initial build succeeded") + + let ready = false + chokidar + .watch(watchDirectories) + .on("ready", () => { + console.log("[reload] ready") + ready = true + }) + .on("all", async (event, path) => { + if (ready === false) return + + if (path.includes("javascript")) { + try { + await setTimeout(20) + await context.rebuild() + console.log("[reload] build succeeded") + } catch (error) { + console.error("[reload] build failed", error) + } + } + clients.forEach((res) => res.write("data: update\n\n")) + clients.length = 0 + }) +} + +if (process.argv.includes("--reload")) { + buildAndReload() +} else if (process.argv.includes("--watch")) { + let context = await esbuild.context({...config, logLevel: 'info'}) + context.watch() +} else { + esbuild.build(config) +} diff --git a/lib/tasks/auto_annotate_models.rake b/lib/tasks/auto_annotate_models.rake deleted file mode 100644 index e96283ea..00000000 --- a/lib/tasks/auto_annotate_models.rake +++ /dev/null @@ -1,59 +0,0 @@ -# NOTE: only doing this in development as some production environments (Heroku) -# NOTE: are sensitive to local FS writes, and besides -- it's just not proper -# NOTE: to have a dev-mode tool do its thing in production. -if Rails.env.development? - require 'annotate' - task :set_annotation_options do - # You can override any of these by setting an environment variable of the - # same name. - Annotate.set_defaults( - 'active_admin' => 'false', - 'additional_file_patterns' => [], - 'routes' => 'false', - 'models' => 'true', - 'position_in_routes' => 'before', - 'position_in_class' => 'before', - 'position_in_test' => 'before', - 'position_in_fixture' => 'before', - 'position_in_factory' => 'before', - 'position_in_serializer' => 'before', - 'show_foreign_keys' => 'true', - 'show_complete_foreign_keys' => 'false', - 'show_indexes' => 'true', - 'simple_indexes' => 'false', - 'model_dir' => 'app/models', - 'root_dir' => '', - 'include_version' => 'false', - 'require' => '', - 'exclude_tests' => 'false', - 'exclude_fixtures' => 'false', - 'exclude_factories' => 'false', - 'exclude_serializers' => 'false', - 'exclude_scaffolds' => 'true', - 'exclude_controllers' => 'true', - 'exclude_helpers' => 'true', - 'exclude_sti_subclasses' => 'false', - 'ignore_model_sub_dir' => 'false', - 'ignore_columns' => nil, - 'ignore_routes' => nil, - 'ignore_unknown_models' => 'false', - 'hide_limit_column_types' => 'integer,bigint,boolean', - 'hide_default_column_types' => 'json,jsonb,hstore', - 'skip_on_db_migrate' => 'false', - 'format_bare' => 'true', - 'format_rdoc' => 'false', - 'format_yard' => 'false', - 'format_markdown' => 'false', - 'sort' => 'false', - 'force' => 'false', - 'frozen' => 'false', - 'classified_sort' => 'true', - 'trace' => 'false', - 'wrapper_open' => nil, - 'wrapper_close' => nil, - 'with_comment' => 'true' - ) - end - - Annotate.load_tasks -end diff --git a/lib/templates/erb/scaffold/_form.html.erb b/lib/templates/erb/scaffold/_form.html.erb new file mode 100644 index 00000000..dd385640 --- /dev/null +++ b/lib/templates/erb/scaffold/_form.html.erb @@ -0,0 +1,50 @@ +<%%= form_with(model: <%= model_resource_name %>) do |form| %> + <%% if <%= singular_table_name %>.errors.any? %> +
+

<%%= pluralize(<%= singular_table_name %>.errors.count, "error") %> prohibited this <%= singular_table_name %> from being saved:

+ +
    + <%% <%= singular_table_name %>.errors.full_messages.each do |message| %> +
  • <%%= message %>
  • + <%% end %> +
+
+ <%% end %> + +<% attributes.each do |attribute| -%> +
+<% if attribute.password_digest? -%> + <%%= form.label :password, class: 'form-label' %> + <%%= form.password_field :password, class: 'form-control' %> +
+ +
+ <%%= form.label :password_confirmation, class: 'form-label' %> + <%%= form.password_field :password_confirmation, class: 'form-control' %> +<% else -%> + <%%= form.label :<%= attribute.column_name %>, class: 'form-label' %> + <% if attribute.field_type == "checkbox" -%> + <%%= form.<%= attribute.field_type %> :<%= attribute.column_name %> %> + <% else -%> + <%%= form.<%= attribute.field_type %> :<%= attribute.column_name %>, class: 'form-control' %> + <% end -%> +<% end -%> +
+ +<% end -%> +
+ <%% if <%= model_resource_name %>.persisted? %> +
+ <%%= link_to 'Destroy', <%= model_resource_name %>, method: :delete, class: "text-danger", data: { confirm: 'Are you sure?' } %> +
+ <%% end %> + + <%%= form.submit class: 'btn btn-primary' %> + + <%% if <%= model_resource_name %>.persisted? %> + <%%= link_to "Cancel", <%= model_resource_name %>, class: "btn btn-link" %> + <%% else %> + <%%= link_to "Cancel", <%= index_helper %>_path, class: "btn btn-link" %> + <%% end %> +
+<%% end %> diff --git a/lib/templates/erb/scaffold/edit.html.erb b/lib/templates/erb/scaffold/edit.html.erb new file mode 100644 index 00000000..50fe8dc5 --- /dev/null +++ b/lib/templates/erb/scaffold/edit.html.erb @@ -0,0 +1,3 @@ +

Edit <%= singular_table_name.capitalize %>

+ +<%%= render 'form', <%= singular_table_name %>: @<%= singular_table_name %> %> diff --git a/lib/templates/erb/scaffold/index.html.erb b/lib/templates/erb/scaffold/index.html.erb new file mode 100644 index 00000000..6c692d0b --- /dev/null +++ b/lib/templates/erb/scaffold/index.html.erb @@ -0,0 +1,51 @@ +<% name_attribute = attributes.find{ |a| a.name == "name" } %> +<% has_name = !!name_attribute %> + +
+
+

<%= plural_table_name.capitalize %>

+
+ +
+ <%%= link_to new_<%= singular_table_name %>_path, class: 'btn btn-primary' do %> + Add New <%= human_name %> + <%% end %> +
+
+ +
+ + + + <% if has_name %> + + <% end %> + + <% attributes.without(name_attribute).each do |attribute| -%> + + <% end -%> + <% unless has_name %> + + <% end %> + + + + + <%% @<%= plural_table_name%>.each do |<%= singular_table_name %>| %> + <%%= content_tag :tr, id: dom_id(<%= singular_table_name %>), class: dom_class(<%= singular_table_name %>) do %> + <% if has_name %> + + <% end %> + + <% attributes.without(name_attribute).each do |attribute| -%> + + <% end -%> + + <% unless has_name %> + + <% end %> + <%% end %> + <%% end %> + +
Name<%= attribute.human_name %>
<%%= link_to <%= singular_table_name %>.name, <%= singular_table_name %> %><%%= <%= singular_table_name %>.<%= attribute.name %> %><%%= link_to 'Show', <%= singular_table_name %> %>
+
diff --git a/lib/templates/erb/scaffold/new.html.erb b/lib/templates/erb/scaffold/new.html.erb new file mode 100644 index 00000000..fb7c45f4 --- /dev/null +++ b/lib/templates/erb/scaffold/new.html.erb @@ -0,0 +1,3 @@ +

New <%= singular_table_name %>

+ +<%%= render 'form', <%= singular_table_name %>: @<%= singular_table_name %> %> diff --git a/lib/templates/erb/scaffold/show.html.erb b/lib/templates/erb/scaffold/show.html.erb new file mode 100644 index 00000000..0b4616db --- /dev/null +++ b/lib/templates/erb/scaffold/show.html.erb @@ -0,0 +1,16 @@ + + +
+ <%- attributes.each do |attribute| -%> +
<%= attribute.human_name %>:
+
<%%= @<%= singular_table_name %>.<%= attribute.name %> %>
+ <%- end -%> +
diff --git a/package.json b/package.json index 99bc2993..f48ebcc6 100644 --- a/package.json +++ b/package.json @@ -1,28 +1,36 @@ { - "name": "myapp", + "name": "app", "private": true, - "dependencies": { - "@hotwired/stimulus": "^3.2.2", - "@hotwired/turbo-rails": "^8.0.10", - "@rails/actioncable": "^6.0.0", - "@rails/activestorage": "^7.2.100", - "@rails/request.js": "^0.0.11", - "@rails/ujs": "^7.1.3-4", - "chokidar": "^4.0.1", - "esbuild-rails": "^1.0.7", - "local-time": "^3.0.2", - "trix": "^2.1.5", - "turbolinks": "^5.2.0" + "devDependencies": { + "esbuild": "^0.24.0" }, - "version": "0.1.0", "scripts": { - "build": "esbuild app/javascript/*.* --bundle --sourcemap --format=esm --outdir=app/assets/builds --public-path=/assets", + "build": "node esbuild.config.mjs", "build:css:compile": "sass ./app/assets/stylesheets/application.bootstrap.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules", "build:css:prefix": "postcss ./app/assets/builds/application.css --use=autoprefixer --output=./app/assets/builds/application.css", "build:css": "yarn build:css:compile && yarn build:css:prefix", "watch:css": "nodemon --watch ./app/assets/stylesheets/ --ext scss --exec \"yarn build:css\"" }, + "dependencies": { + "@hotwired/stimulus": "^3.2.2", + "@hotwired/turbo-rails": "^8.0.10", + "@popperjs/core": "^2.11.8", + "@rails/activestorage": "^7.2.100", + "@rails/request.js": "^0.0.11", + "@rails/ujs": "^7.1.3-4", + "autoprefixer": "^10.4.20", + "bootstrap": "^5.3.3", + "bootstrap-icons": "^1.11.3", + "chokidar": "^4.0.1", + "esbuild-rails": "^1.0.7", + "local-time": "^3.0.2", + "nodemon": "^3.1.7", + "postcss": "^8.4.47", + "postcss-cli": "^11.0.0", + "sass": "^1.79.3", + "trix": "^2.1.5" + }, "browserslist": [ "defaults" ] -} \ No newline at end of file +} diff --git a/public/406-unsupported-browser.html b/public/406-unsupported-browser.html new file mode 100644 index 00000000..7cf1e168 --- /dev/null +++ b/public/406-unsupported-browser.html @@ -0,0 +1,66 @@ + + + + Your browser is not supported (406) + + + + + + +
+
+

Your browser is not supported.

+

Please upgrade your browser to continue.

+
+
+ + diff --git a/public/apple-touch-icon-precomposed.png b/public/apple-touch-icon-precomposed.png deleted file mode 100644 index e69de29b..00000000 diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png deleted file mode 100644 index e69de29b..00000000 diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index e69de29b..00000000 diff --git a/public/icon.png b/public/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f3b5abcbde91cf6d7a6a26e514eb7e30f476f950 GIT binary patch literal 5599 zcmeHL-D}fO6hCR_taXJlzs3}~RuB=Iujyo=i*=1|1FN%E=zNfMTjru|Q<6v{J{U!C zBEE}?j6I3sz>fzN!6}L_BKjcuASk~1;Dg|U_@d{g?V8mM`~#9U+>>*Ezw>c(PjYWA z4(;!cgge6k5E&d$G5`S-0}!Ik>CV(0Y#1}s-v_gAHhja2=W1?nBAte9D2HG<(+)uj z!5=W4u*{VKMw#{V@^NNs4TClr!FAA%ID-*gc{R%CFKEzG<6gm*9s_uy)oMGW*=nJf zw{(Mau|2FHfXIv6C0@Wk5k)F=3jo1srV-C{pl&k&)4_&JjYrnbJiul}d0^NCSh(#7h=F;3{|>EU>h z6U8_p;^wK6mAB(1b92>5-HxJ~V}@3?G`&Qq-TbJ2(&~-HsH6F#8mFaAG(45eT3VPO zM|(Jd<+;UZs;w>0Qw}0>D%{~r{uo_Fl5_Bo3ABWi zWo^j^_T3dxG6J6fH8X)$a^%TJ#PU!=LxF=#Fd9EvKx_x>q<(KY%+y-08?kN9dXjXK z**Q=yt-FTU*13ouhCdqq-0&;Ke{T3sQU9IdzhV9LhQIpq*P{N)+}|Mh+a-VV=x?R} c>%+pvTcMWshj-umO}|qP?%A)*_KlqT3uEqhU;qFB literal 0 HcmV?d00001 diff --git a/public/icon.svg b/public/icon.svg new file mode 100644 index 00000000..78307ccd --- /dev/null +++ b/public/icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/test/application_system_test_case.rb b/test/application_system_test_case.rb index d19212ab..cee29fd2 100644 --- a/test/application_system_test_case.rb +++ b/test/application_system_test_case.rb @@ -1,5 +1,5 @@ require "test_helper" class ApplicationSystemTestCase < ActionDispatch::SystemTestCase - driven_by :selenium, using: :chrome, screen_size: [1400, 1400] + driven_by :selenium, using: :headless_chrome, screen_size: [ 1400, 1400 ] end diff --git a/test/fixtures/announcements.yml b/test/fixtures/announcements.yml index 43e91459..5e0f8bf0 100644 --- a/test/fixtures/announcements.yml +++ b/test/fixtures/announcements.yml @@ -1,24 +1,13 @@ -# == Schema Information -# -# Table name: announcements -# -# id :bigint not null, primary key -# announcement_type :string -# description :text -# name :string -# published_at :datetime -# created_at :datetime not null -# updated_at :datetime not null -# +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html one: - published_at: 2024-09-25 11:41:33 + published_at: 2024-09-25 13:51:47 announcement_type: MyString name: MyString description: MyText two: - published_at: 2024-09-25 11:41:33 + published_at: 2024-09-25 13:51:47 announcement_type: MyString name: MyString description: MyText diff --git a/test/fixtures/clusters.yml b/test/fixtures/clusters.yml deleted file mode 100644 index 84ad28a5..00000000 --- a/test/fixtures/clusters.yml +++ /dev/null @@ -1,29 +0,0 @@ -# == Schema Information -# -# Table name: clusters -# -# id :bigint not null, primary key -# kubeconfig :jsonb not null -# name :string not null -# created_at :datetime not null -# updated_at :datetime not null -# user_id :bigint not null -# -# Indexes -# -# index_clusters_on_user_id (user_id) -# -# Foreign Keys -# -# fk_rails_... (user_id => users.id) -# - -# This model initially had no columns defined. If you add columns to the -# model remove the "{}" from the fixture names and add the columns immediately -# below each fixture, per the syntax in the comments below -# -one: {} -# column: value -# -two: {} -# column: value diff --git a/test/fixtures/services.yml b/test/fixtures/services.yml index c905ba9e..6e01e06e 100644 --- a/test/fixtures/services.yml +++ b/test/fixtures/services.yml @@ -1,27 +1,4 @@ -# == Schema Information -# -# Table name: services -# -# id :bigint not null, primary key -# access_token :string -# access_token_secret :string -# auth :text -# expires_at :datetime -# provider :string -# refresh_token :string -# uid :string -# created_at :datetime not null -# updated_at :datetime not null -# user_id :bigint not null -# -# Indexes -# -# index_services_on_user_id (user_id) -# -# Foreign Keys -# -# fk_rails_... (user_id => users.id) -# +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html one: user: one @@ -30,7 +7,7 @@ one: access_token: MyString access_token_secret: MyString refresh_token: MyString - expires_at: 2024-09-25 11:41:35 + expires_at: 2024-09-25 13:51:49 auth: MyText two: @@ -40,5 +17,5 @@ two: access_token: MyString access_token_secret: MyString refresh_token: MyString - expires_at: 2024-09-25 11:41:35 + expires_at: 2024-09-25 13:51:49 auth: MyText diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml index 51c55cc1..d7a33292 100644 --- a/test/fixtures/users.yml +++ b/test/fixtures/users.yml @@ -1,25 +1,4 @@ -# == Schema Information -# -# Table name: users -# -# id :bigint not null, primary key -# admin :boolean default(FALSE) -# announcements_last_read_at :datetime -# email :string default(""), not null -# encrypted_password :string default(""), not null -# first_name :string -# last_name :string -# remember_created_at :datetime -# reset_password_sent_at :datetime -# reset_password_token :string -# created_at :datetime not null -# updated_at :datetime not null -# -# Indexes -# -# index_users_on_email (email) UNIQUE -# index_users_on_reset_password_token (reset_password_token) UNIQUE -# +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html # This model initially had no columns defined. If you add columns to the # model remove the "{}" from the fixture names and add the columns immediately diff --git a/test/models/announcement_test.rb b/test/models/announcement_test.rb index 8b1117ee..7f920199 100644 --- a/test/models/announcement_test.rb +++ b/test/models/announcement_test.rb @@ -1,15 +1,3 @@ -# == Schema Information -# -# Table name: announcements -# -# id :bigint not null, primary key -# announcement_type :string -# description :text -# name :string -# published_at :datetime -# created_at :datetime not null -# updated_at :datetime not null -# require "test_helper" class AnnouncementTest < ActiveSupport::TestCase diff --git a/test/models/cluster_test.rb b/test/models/cluster_test.rb deleted file mode 100644 index 0bf77f62..00000000 --- a/test/models/cluster_test.rb +++ /dev/null @@ -1,26 +0,0 @@ -# == Schema Information -# -# Table name: clusters -# -# id :bigint not null, primary key -# kubeconfig :jsonb not null -# name :string not null -# created_at :datetime not null -# updated_at :datetime not null -# user_id :bigint not null -# -# Indexes -# -# index_clusters_on_user_id (user_id) -# -# Foreign Keys -# -# fk_rails_... (user_id => users.id) -# -require "test_helper" - -class ClusterTest < ActiveSupport::TestCase - # test "the truth" do - # assert true - # end -end diff --git a/test/models/service_test.rb b/test/models/service_test.rb index 903b604a..1bdfc62d 100644 --- a/test/models/service_test.rb +++ b/test/models/service_test.rb @@ -1,27 +1,3 @@ -# == Schema Information -# -# Table name: services -# -# id :bigint not null, primary key -# access_token :string -# access_token_secret :string -# auth :text -# expires_at :datetime -# provider :string -# refresh_token :string -# uid :string -# created_at :datetime not null -# updated_at :datetime not null -# user_id :bigint not null -# -# Indexes -# -# index_services_on_user_id (user_id) -# -# Foreign Keys -# -# fk_rails_... (user_id => users.id) -# require "test_helper" class ServiceTest < ActiveSupport::TestCase diff --git a/test/models/user_test.rb b/test/models/user_test.rb index a6163125..5c07f490 100644 --- a/test/models/user_test.rb +++ b/test/models/user_test.rb @@ -1,25 +1,3 @@ -# == Schema Information -# -# Table name: users -# -# id :bigint not null, primary key -# admin :boolean default(FALSE) -# announcements_last_read_at :datetime -# email :string default(""), not null -# encrypted_password :string default(""), not null -# first_name :string -# last_name :string -# remember_created_at :datetime -# reset_password_sent_at :datetime -# reset_password_token :string -# created_at :datetime not null -# updated_at :datetime not null -# -# Indexes -# -# index_users_on_email (email) UNIQUE -# index_users_on_reset_password_token (reset_password_token) UNIQUE -# require "test_helper" class UserTest < ActiveSupport::TestCase diff --git a/yarn.lock b/yarn.lock index 9c6f0b93..01698d00 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,126 @@ # yarn lockfile v1 +"@esbuild/aix-ppc64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz#b57697945b50e99007b4c2521507dc613d4a648c" + integrity sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw== + +"@esbuild/android-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz#1add7e0af67acefd556e407f8497e81fddad79c0" + integrity sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w== + +"@esbuild/android-arm@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.24.0.tgz#ab7263045fa8e090833a8e3c393b60d59a789810" + integrity sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew== + +"@esbuild/android-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.24.0.tgz#e8f8b196cfdfdd5aeaebbdb0110983460440e705" + integrity sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ== + +"@esbuild/darwin-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz#2d0d9414f2acbffd2d86e98253914fca603a53dd" + integrity sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw== + +"@esbuild/darwin-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz#33087aab31a1eb64c89daf3d2cf8ce1775656107" + integrity sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA== + +"@esbuild/freebsd-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz#bb76e5ea9e97fa3c753472f19421075d3a33e8a7" + integrity sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA== + +"@esbuild/freebsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz#e0e2ce9249fdf6ee29e5dc3d420c7007fa579b93" + integrity sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ== + +"@esbuild/linux-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz#d1b2aa58085f73ecf45533c07c82d81235388e75" + integrity sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g== + +"@esbuild/linux-arm@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz#8e4915df8ea3e12b690a057e77a47b1d5935ef6d" + integrity sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw== + +"@esbuild/linux-ia32@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz#8200b1110666c39ab316572324b7af63d82013fb" + integrity sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA== + +"@esbuild/linux-loong64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz#6ff0c99cf647504df321d0640f0d32e557da745c" + integrity sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g== + +"@esbuild/linux-mips64el@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz#3f720ccd4d59bfeb4c2ce276a46b77ad380fa1f3" + integrity sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA== + +"@esbuild/linux-ppc64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz#9d6b188b15c25afd2e213474bf5f31e42e3aa09e" + integrity sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ== + +"@esbuild/linux-riscv64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz#f989fdc9752dfda286c9cd87c46248e4dfecbc25" + integrity sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw== + +"@esbuild/linux-s390x@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz#29ebf87e4132ea659c1489fce63cd8509d1c7319" + integrity sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g== + +"@esbuild/linux-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz#4af48c5c0479569b1f359ffbce22d15f261c0cef" + integrity sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA== + +"@esbuild/netbsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz#1ae73d23cc044a0ebd4f198334416fb26c31366c" + integrity sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg== + +"@esbuild/openbsd-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz#5d904a4f5158c89859fd902c427f96d6a9e632e2" + integrity sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg== + +"@esbuild/openbsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz#4c8aa88c49187c601bae2971e71c6dc5e0ad1cdf" + integrity sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q== + +"@esbuild/sunos-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz#8ddc35a0ea38575fa44eda30a5ee01ae2fa54dd4" + integrity sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA== + +"@esbuild/win32-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz#6e79c8543f282c4539db684a207ae0e174a9007b" + integrity sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA== + +"@esbuild/win32-ia32@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz#057af345da256b7192d18b676a02e95d0fa39103" + integrity sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw== + +"@esbuild/win32-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz#168ab1c7e1c318b922637fad8f339d48b01e1244" + integrity sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA== + "@hotwired/stimulus@^3.2.2": version "3.2.2" resolved "https://registry.yarnpkg.com/@hotwired/stimulus/-/stimulus-3.2.2.tgz#071aab59c600fed95b97939e605ff261a4251608" @@ -41,10 +161,10 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@rails/actioncable@^6.0.0": - version "6.1.7" - resolved "https://registry.yarnpkg.com/@rails/actioncable/-/actioncable-6.1.7.tgz#8b4506925d3f7146a70941e4db7ce9dda99f99ae" - integrity sha512-F6S74NGpxhbbDRFsQFGYqefRfZPgYvePNtz9hHKYOqLturrsqrDoG+UcrxEGHsvqDUorMYfx4Wl3K8smmk/u2g== +"@popperjs/core@^2.11.8": + version "2.11.8" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" + integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== "@rails/actioncable@^7.0": version "7.2.100" @@ -68,20 +188,163 @@ resolved "https://registry.yarnpkg.com/@rails/ujs/-/ujs-7.1.3-4.tgz#1dddea99d5c042e8513973ea709b2cb7e840dc2d" integrity sha512-z0ckI5jrAJfImcObjMT1RBz2IxH6I5q6ZTMFex6AfxSQKZuuL8JxAXvg2CvBuodGCxKvybFVolDyMHXlBLeYAA== -braces@^3.0.3: +"@sindresorhus/merge-streams@^2.1.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz#719df7fb41766bc143369eaa0dd56d8dc87c9958" + integrity sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +autoprefixer@^10.4.20: + version "10.4.20" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.20.tgz#5caec14d43976ef42e32dcb4bd62878e96be5b3b" + integrity sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g== + dependencies: + browserslist "^4.23.3" + caniuse-lite "^1.0.30001646" + fraction.js "^4.3.7" + normalize-range "^0.1.2" + picocolors "^1.0.1" + postcss-value-parser "^4.2.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +binary-extensions@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== + +bootstrap-icons@^1.11.3: + version "1.11.3" + resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.11.3.tgz#03f9cb754ec005c52f9ee616e2e84a82cab3084b" + integrity sha512-+3lpHrCw/it2/7lBL15VR0HEumaBss0+f/Lb6ZvHISn1mlK83jjFpooTLsMWbIjJMDjDjOExMsTxnXSIT4k4ww== + +bootstrap@^5.3.3: + version "5.3.3" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.3.tgz#de35e1a765c897ac940021900fcbb831602bac38" + integrity sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.3, braces@~3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: fill-range "^7.1.1" -chokidar@^4.0.1: +browserslist@^4.23.3: + version "4.24.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.0.tgz#a1325fe4bc80b64fda169629fc01b3d6cecd38d4" + integrity sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A== + dependencies: + caniuse-lite "^1.0.30001663" + electron-to-chromium "^1.5.28" + node-releases "^2.0.18" + update-browserslist-db "^1.1.0" + +caniuse-lite@^1.0.30001646, caniuse-lite@^1.0.30001663: + version "1.0.30001663" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001663.tgz#1529a723505e429fdfd49532e9fc42273ba7fed7" + integrity sha512-o9C3X27GLKbLeTYZ6HBOLU1tsAcBZsLis28wrVzddShCS16RujjHp9GDHKZqrB3meE0YjhawvMFsGb/igqiPzA== + +chokidar@^3.3.0, chokidar@^3.5.2: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chokidar@^4.0.0, chokidar@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.1.tgz#4a6dff66798fb0f72a94f616abbd7e1a19f31d41" integrity sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA== dependencies: readdirp "^4.0.1" +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +debug@^4: + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== + dependencies: + ms "^2.1.3" + +dependency-graph@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.11.0.tgz#ac0ce7ed68a54da22165a85e97a01d53f5eb2e27" + integrity sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg== + +electron-to-chromium@^1.5.28: + version "1.5.28" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.28.tgz#aee074e202c6ee8a0030a9c2ef0b3fe9f967d576" + integrity sha512-VufdJl+rzaKZoYVUijN13QcXVF5dWPZANeFTLNy+OSpHdDL5ynXTF35+60RSBbaQYB1ae723lQXHCrf4pyLsMw== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + esbuild-rails@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/esbuild-rails/-/esbuild-rails-1.0.7.tgz#3c8f76dc891d5b2105cb683ace0a15d11c91a973" @@ -89,7 +352,42 @@ esbuild-rails@^1.0.7: dependencies: fast-glob "^3.2.12" -fast-glob@^3.2.12: +esbuild@^0.24.0: + version "0.24.0" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.24.0.tgz#f2d470596885fcb2e91c21eb3da3b3c89c0b55e7" + integrity sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ== + optionalDependencies: + "@esbuild/aix-ppc64" "0.24.0" + "@esbuild/android-arm" "0.24.0" + "@esbuild/android-arm64" "0.24.0" + "@esbuild/android-x64" "0.24.0" + "@esbuild/darwin-arm64" "0.24.0" + "@esbuild/darwin-x64" "0.24.0" + "@esbuild/freebsd-arm64" "0.24.0" + "@esbuild/freebsd-x64" "0.24.0" + "@esbuild/linux-arm" "0.24.0" + "@esbuild/linux-arm64" "0.24.0" + "@esbuild/linux-ia32" "0.24.0" + "@esbuild/linux-loong64" "0.24.0" + "@esbuild/linux-mips64el" "0.24.0" + "@esbuild/linux-ppc64" "0.24.0" + "@esbuild/linux-riscv64" "0.24.0" + "@esbuild/linux-s390x" "0.24.0" + "@esbuild/linux-x64" "0.24.0" + "@esbuild/netbsd-x64" "0.24.0" + "@esbuild/openbsd-arm64" "0.24.0" + "@esbuild/openbsd-x64" "0.24.0" + "@esbuild/sunos-x64" "0.24.0" + "@esbuild/win32-arm64" "0.24.0" + "@esbuild/win32-ia32" "0.24.0" + "@esbuild/win32-x64" "0.24.0" + +escalade@^3.1.1, escalade@^3.1.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== + +fast-glob@^3.2.12, fast-glob@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== @@ -114,19 +412,97 @@ fill-range@^7.1.1: dependencies: to-regex-range "^5.0.1" -glob-parent@^5.1.2: +fraction.js@^4.3.7: + version "4.3.7" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7" + integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew== + +fs-extra@^11.0.0: + version "11.2.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" + integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-stdin@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-9.0.0.tgz#3983ff82e03d56f1b2ea0d3e60325f39d703a575" + integrity sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA== + +glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" +globby@^14.0.0: + version "14.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-14.0.2.tgz#06554a54ccfe9264e5a9ff8eded46aa1e306482f" + integrity sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw== + dependencies: + "@sindresorhus/merge-streams" "^2.1.0" + fast-glob "^3.3.2" + ignore "^5.2.4" + path-type "^5.0.0" + slash "^5.1.0" + unicorn-magic "^0.1.0" + +graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +ignore-by-default@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== + +ignore@^5.2.4: + version "5.3.2" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" + integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== + +immutable@^4.0.0: + version "4.3.7" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.7.tgz#c70145fc90d89fb02021e65c84eb0226e4e5a381" + integrity sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== -is-glob@^4.0.1: +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== @@ -138,6 +514,20 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +lilconfig@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.2.tgz#e4a7c3cb549e3a606c8dcc32e5ae1005e62c05cb" + integrity sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow== + local-time@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/local-time/-/local-time-3.0.2.tgz#2767a1f3a9310f445efe3d75ad3bd07f634fa5f0" @@ -156,21 +546,161 @@ micromatch@^4.0.4: braces "^3.0.3" picomatch "^2.3.1" -picomatch@^2.3.1: +minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +ms@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + +node-releases@^2.0.18: + version "2.0.18" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" + integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== + +nodemon@^3.1.7: + version "3.1.7" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-3.1.7.tgz#07cb1f455f8bece6a499e0d72b5e029485521a54" + integrity sha512-hLj7fuMow6f0lbB0cD14Lz2xNjwsyruH251Pk4t/yIitCFJbmY1myuLlHm/q06aST4jg6EgAh74PIBBrRqpVAQ== + dependencies: + chokidar "^3.5.2" + debug "^4" + ignore-by-default "^1.0.1" + minimatch "^3.1.2" + pstree.remy "^1.1.8" + semver "^7.5.3" + simple-update-notifier "^2.0.0" + supports-color "^5.5.0" + touch "^3.1.0" + undefsafe "^2.0.5" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== + +path-type@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-5.0.0.tgz#14b01ed7aea7ddf9c7c3f46181d4d04f9c785bb8" + integrity sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg== + +picocolors@^1.0.0, picocolors@^1.0.1, picocolors@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.0.tgz#5358b76a78cde483ba5cef6a9dc9671440b27d59" + integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +postcss-cli@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/postcss-cli/-/postcss-cli-11.0.0.tgz#649f4b9af447501feb6cbca7f7505a132f90442b" + integrity sha512-xMITAI7M0u1yolVcXJ9XTZiO9aO49mcoKQy6pCDFdMh9kGqhzLVpWxeD/32M/QBmkhcGypZFFOLNLmIW4Pg4RA== + dependencies: + chokidar "^3.3.0" + dependency-graph "^0.11.0" + fs-extra "^11.0.0" + get-stdin "^9.0.0" + globby "^14.0.0" + picocolors "^1.0.0" + postcss-load-config "^5.0.0" + postcss-reporter "^7.0.0" + pretty-hrtime "^1.0.3" + read-cache "^1.0.0" + slash "^5.0.0" + yargs "^17.0.0" + +postcss-load-config@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-5.1.0.tgz#4ded23410da973e05edae9d41fa99bb5c1d5477f" + integrity sha512-G5AJ+IX0aD0dygOE0yFZQ/huFFMSNneyfp0e3/bT05a8OfPC5FUoZRPfGijUdGOJNMewJiwzcHJXFafFzeKFVA== + dependencies: + lilconfig "^3.1.1" + yaml "^2.4.2" + +postcss-reporter@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/postcss-reporter/-/postcss-reporter-7.1.0.tgz#5ec476d224e2fe25a054e3c66d9b2901d4fab422" + integrity sha512-/eoEylGWyy6/DOiMP5lmFRdmDKThqgn7D6hP2dXKJI/0rJSO1ADFNngZfDzxL0YAxFvws+Rtpuji1YIHj4mySA== + dependencies: + picocolors "^1.0.0" + thenby "^1.3.4" + +postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@^8.4.47: + version "8.4.47" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365" + integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ== + dependencies: + nanoid "^3.3.7" + picocolors "^1.1.0" + source-map-js "^1.2.1" + +pretty-hrtime@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + integrity sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A== + +pstree.remy@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" + integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +read-cache@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" + integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== + dependencies: + pify "^2.3.0" + readdirp@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.0.1.tgz#b2fe35f8dca63183cd3b86883ecc8f720ea96ae6" integrity sha512-GkMg9uOTpIWWKbSsgwb5fA4EavTR+SG/PMPoAY8hkhHfEEY0/vqljY+XHqtDf2cr2IJtoNRDbrrEpZUiZCkYRw== +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -183,11 +713,70 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +sass@^1.79.3: + version "1.79.3" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.79.3.tgz#7811b000eb68195fe51dea89177e73e7ef7f546f" + integrity sha512-m7dZxh0W9EZ3cw50Me5GOuYm/tVAJAn91SUnohLRo9cXBixGUOdvmryN+dXpwR831bhoY3Zv7rEFt85PUwTmzA== + dependencies: + chokidar "^4.0.0" + immutable "^4.0.0" + source-map-js ">=0.6.2 <2.0.0" + +semver@^7.5.3: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + +simple-update-notifier@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz#d70b92bdab7d6d90dfd73931195a30b6e3d7cebb" + integrity sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w== + dependencies: + semver "^7.5.3" + +slash@^5.0.0, slash@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-5.1.0.tgz#be3adddcdf09ac38eebe8dcdc7b1a57a75b095ce" + integrity sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg== + +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== + spark-md5@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/spark-md5/-/spark-md5-3.0.2.tgz#7952c4a30784347abcee73268e473b9c0167e3fc" integrity sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw== +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +thenby@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/thenby/-/thenby-1.3.4.tgz#81581f6e1bb324c6dedeae9bfc28e59b1a2201cc" + integrity sha512-89Gi5raiWA3QZ4b2ePcEwswC3me9JIg+ToSgtE0JWeCynLnLxNr/f9G+xfo9K+Oj4AFdom8YNJjibIARTJmapQ== + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -195,12 +784,72 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +touch@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.1.tgz#097a23d7b161476435e5c1344a95c0f75b4a5694" + integrity sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA== + trix@^2.1.5: version "2.1.5" resolved "https://registry.yarnpkg.com/trix/-/trix-2.1.5.tgz#512bc811172bea196de4a92fa8308c0914f263f9" integrity sha512-5pC4olCp7BwxTC8Joy1Kv33kDvSOApi9Tqf6c8wygqCgeCx9xPP5cxkZEhvKpMV+kjd9gszingd5fZo834+ktw== -turbolinks@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/turbolinks/-/turbolinks-5.2.0.tgz#e6877a55ea5c1cb3bb225f0a4ae303d6d32ff77c" - integrity sha512-pMiez3tyBo6uRHFNNZoYMmrES/IaGgMhQQM+VFF36keryjb5ms0XkVpmKHkfW/4Vy96qiGW3K9bz0tF5sK9bBw== +undefsafe@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" + integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== + +unicorn-magic@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/unicorn-magic/-/unicorn-magic-0.1.0.tgz#1bb9a51c823aaf9d73a8bfcd3d1a23dde94b0ce4" + integrity sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ== + +universalify@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== + +update-browserslist-db@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" + integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== + dependencies: + escalade "^3.1.2" + picocolors "^1.0.1" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yaml@^2.4.2: + version "2.5.1" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.5.1.tgz#c9772aacf62cb7494a95b0c4f1fb065b563db130" + integrity sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q== + +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^17.0.0: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1"