neeto-commons-backend 1.0.89

Sign up to get free protection for your applications and to get access to all the features.
Files changed (189) hide show
  1. checksums.yaml +7 -0
  2. data/.eslintignore +14 -0
  3. data/.eslintrc.js +87 -0
  4. data/.husky/helpers/verify_neeto_audit.sh +18 -0
  5. data/.husky/pre-push +5 -0
  6. data/.neetoci/neetoci.yml +26 -0
  7. data/.prettierrc.js +15 -0
  8. data/.rubocop.yml +626 -0
  9. data/.ruby-version +1 -0
  10. data/.semaphore/semaphore.yml +32 -0
  11. data/.semaphore/staging-deploy.yml +23 -0
  12. data/Gemfile +92 -0
  13. data/Gemfile.lock +461 -0
  14. data/README.md +286 -0
  15. data/Rakefile +18 -0
  16. data/app/controllers/api/base_controller.rb +6 -0
  17. data/app/controllers/neeto_commons_backend/api/base_controller.rb +9 -0
  18. data/app/controllers/neeto_commons_backend/api/direct_uploads_controller.rb +57 -0
  19. data/app/controllers/neeto_commons_backend/app_versions_controller.rb +20 -0
  20. data/app/controllers/neeto_commons_backend/failures_controller.rb +29 -0
  21. data/app/controllers/neeto_commons_backend/health_check_controller.rb +9 -0
  22. data/app/controllers/neeto_commons_backend/well_knowns_controller.rb +13 -0
  23. data/app/mailers/neeto_commons_backend/application_mailer.rb +22 -0
  24. data/app/models/concerns/neeto_commons_backend/sluggable.rb +27 -0
  25. data/app/models/concerns/neeto_commons_backend/soft_deletable.rb +20 -0
  26. data/app/services/neeto_commons_backend/sample_data/common/admin_service.rb +26 -0
  27. data/app/services/neeto_commons_backend/sample_data/common/app_organization_service.rb +11 -0
  28. data/app/services/neeto_commons_backend/sample_data/common/base.rb +49 -0
  29. data/app/services/neeto_commons_backend/sample_data/common/database_cleanup_service.rb +13 -0
  30. data/app/services/neeto_commons_backend/sample_data/common/loader_service.rb +30 -0
  31. data/app/services/neeto_commons_backend/sample_data/common/neeto_team_members_service.rb +16 -0
  32. data/app/services/neeto_commons_backend/sample_data/common/organization_base.rb +36 -0
  33. data/app/services/neeto_commons_backend/sample_data/common/organization_service.rb +11 -0
  34. data/app/services/neeto_commons_backend/source_map_publish_service.rb +47 -0
  35. data/app/views/neeto_commons_backend/failures/show.html.erb +1 -0
  36. data/app/views/shared/_common.html.erb +8 -0
  37. data/app/views/shared/_neeto_engineering_replay_widget.html.erb +31 -0
  38. data/app/views/shared/_neeto_widget.html.erb +30 -0
  39. data/app/workers/neeto_commons_backend/base_workers/auth.rb +9 -0
  40. data/app/workers/neeto_commons_backend/base_workers/base.rb +52 -0
  41. data/app/workers/neeto_commons_backend/base_workers/default.rb +8 -0
  42. data/app/workers/neeto_commons_backend/base_workers/low.rb +9 -0
  43. data/app/workers/neeto_commons_backend/base_workers/urgent.rb +9 -0
  44. data/app/workers/neeto_commons_backend/purge_unattached_files_worker.rb +11 -0
  45. data/babel.config.js +47 -0
  46. data/bin/console +15 -0
  47. data/bin/rails +16 -0
  48. data/bin/setup +8 -0
  49. data/config/brakeman.ignore +52 -0
  50. data/config/locales/en.yml +5 -0
  51. data/docs/carriers/README.md +5 -0
  52. data/docs/controller_concerns/README.md +34 -0
  53. data/docs/controllers/README.md +27 -0
  54. data/docs/gemfiles/README.md +5 -0
  55. data/docs/helpers/README.md +21 -0
  56. data/docs/mailers/README.md +5 -0
  57. data/docs/model_concerns/README.md +39 -0
  58. data/docs/routes/README.md +44 -0
  59. data/docs/scripts/README.md +5 -0
  60. data/docs/semaphore/README.md +5 -0
  61. data/docs/services/README.md +23 -0
  62. data/docs/workers/README.md +32 -0
  63. data/docs/workflows/README.md +9 -0
  64. data/lib/Rakefile +4 -0
  65. data/lib/neeto-commons-backend.rb +62 -0
  66. data/lib/neeto_commons_backend/.circleci/config.yml +84 -0
  67. data/lib/neeto_commons_backend/.slugignore +17 -0
  68. data/lib/neeto_commons_backend/carriers/app_url_carrier.rb +71 -0
  69. data/lib/neeto_commons_backend/common_files/.bundler-version +1 -0
  70. data/lib/neeto_commons_backend/common_files/.editorconfig +10 -0
  71. data/lib/neeto_commons_backend/common_files/.erb-lint.yml +20 -0
  72. data/lib/neeto_commons_backend/common_files/.eslintignore +14 -0
  73. data/lib/neeto_commons_backend/common_files/.eslintrc.js +2 -0
  74. data/lib/neeto_commons_backend/common_files/.gitignore +132 -0
  75. data/lib/neeto_commons_backend/common_files/.husky/helpers/lint_staged.sh +5 -0
  76. data/lib/neeto_commons_backend/common_files/.husky/helpers/prevent_conflict_markers.sh +35 -0
  77. data/lib/neeto_commons_backend/common_files/.husky/helpers/prevent_pushing_to_main.sh +24 -0
  78. data/lib/neeto_commons_backend/common_files/.husky/helpers/verify_neeto_audit.sh +17 -0
  79. data/lib/neeto_commons_backend/common_files/.husky/pre-commit +9 -0
  80. data/lib/neeto_commons_backend/common_files/.husky/pre-push +7 -0
  81. data/lib/neeto_commons_backend/common_files/.node-version +1 -0
  82. data/lib/neeto_commons_backend/common_files/.nvmrc +1 -0
  83. data/lib/neeto_commons_backend/common_files/.postcssrc.yml +6 -0
  84. data/lib/neeto_commons_backend/common_files/.prettierrc.js +1 -0
  85. data/lib/neeto_commons_backend/common_files/.rubocop.yml +625 -0
  86. data/lib/neeto_commons_backend/common_files/.ruby-version +1 -0
  87. data/lib/neeto_commons_backend/common_files/.semaphore/commands/run_eslint_on_modified_files.sh +5 -0
  88. data/lib/neeto_commons_backend/common_files/.vscode/extensions.json +10 -0
  89. data/lib/neeto_commons_backend/common_files/.vscode/settings.json +21 -0
  90. data/lib/neeto_commons_backend/common_files/Dockerfile.dev +50 -0
  91. data/lib/neeto_commons_backend/common_files/app/javascript/jsconfig.json +62 -0
  92. data/lib/neeto_commons_backend/common_files/app/javascript/src/types.d.ts +36 -0
  93. data/lib/neeto_commons_backend/common_files/babel.config.js +1 -0
  94. data/lib/neeto_commons_backend/common_files/bin/bundle +5 -0
  95. data/lib/neeto_commons_backend/common_files/bin/rails +6 -0
  96. data/lib/neeto_commons_backend/common_files/bin/rake +6 -0
  97. data/lib/neeto_commons_backend/common_files/bin/setup +40 -0
  98. data/lib/neeto_commons_backend/common_files/bin/update +33 -0
  99. data/lib/neeto_commons_backend/common_files/bin/webpacker +17 -0
  100. data/lib/neeto_commons_backend/common_files/bin/webpacker-dev-server +17 -0
  101. data/lib/neeto_commons_backend/common_files/bin/yarn +19 -0
  102. data/lib/neeto_commons_backend/common_files/cypress-tests/.eslintrc.js +57 -0
  103. data/lib/neeto_commons_backend/common_files/cypress-tests/cypress/plugins/index.js +63 -0
  104. data/lib/neeto_commons_backend/common_files/github/workflows/auto_update_prs_with_latest_master.yml +21 -0
  105. data/lib/neeto_commons_backend/common_files/neeto_gems/github/workflows/bump_version.yml +51 -0
  106. data/lib/neeto_commons_backend/common_files/newrelic.yml +31 -0
  107. data/lib/neeto_commons_backend/common_files/package-common.json +119 -0
  108. data/lib/neeto_commons_backend/common_files/roles.yml +34 -0
  109. data/lib/neeto_commons_backend/common_files/semaphore/semaphore.yml +58 -0
  110. data/lib/neeto_commons_backend/common_files/sitemap.xml +15 -0
  111. data/lib/neeto_commons_backend/common_files/test/support/assertion_support.rb +9 -0
  112. data/lib/neeto_commons_backend/common_files/webpacker.yml +90 -0
  113. data/lib/neeto_commons_backend/config/secrets.yml +169 -0
  114. data/lib/neeto_commons_backend/controllers/concerns/api_exceptions.rb +83 -0
  115. data/lib/neeto_commons_backend/controllers/concerns/api_helpers.rb +9 -0
  116. data/lib/neeto_commons_backend/controllers/concerns/api_responders.rb +33 -0
  117. data/lib/neeto_commons_backend/controllers/concerns/authenticatable.rb +51 -0
  118. data/lib/neeto_commons_backend/controllers/concerns/honeybadger_context.rb +17 -0
  119. data/lib/neeto_commons_backend/controllers/concerns/store_user_location.rb +23 -0
  120. data/lib/neeto_commons_backend/cypress/cypress.review.json +13 -0
  121. data/lib/neeto_commons_backend/cypress/jsconfig.json +17 -0
  122. data/lib/neeto_commons_backend/cypress/package.json +51 -0
  123. data/lib/neeto_commons_backend/cypress/resolve.js +16 -0
  124. data/lib/neeto_commons_backend/cypress/webpack.config.js +21 -0
  125. data/lib/neeto_commons_backend/engine.rb +6 -0
  126. data/lib/neeto_commons_backend/environments/application.rb +33 -0
  127. data/lib/neeto_commons_backend/environments/development.rb +46 -0
  128. data/lib/neeto_commons_backend/environments/heroku.rb +35 -0
  129. data/lib/neeto_commons_backend/environments/production.rb +45 -0
  130. data/lib/neeto_commons_backend/environments/staging.rb +43 -0
  131. data/lib/neeto_commons_backend/environments/test.rb +29 -0
  132. data/lib/neeto_commons_backend/gemfiles/Gemfile.common.rb +240 -0
  133. data/lib/neeto_commons_backend/helpers/auth_server_api.rb +92 -0
  134. data/lib/neeto_commons_backend/helpers/favicon.rb +18 -0
  135. data/lib/neeto_commons_backend/helpers/global_props.rb +76 -0
  136. data/lib/neeto_commons_backend/helpers/neeto_widget_helper.rb +19 -0
  137. data/lib/neeto_commons_backend/helpers/test_helper.rb +90 -0
  138. data/lib/neeto_commons_backend/initializers/_enable_extension_hack.rb +32 -0
  139. data/lib/neeto_commons_backend/initializers/assets.rb +11 -0
  140. data/lib/neeto_commons_backend/initializers/bullet.rb +26 -0
  141. data/lib/neeto_commons_backend/initializers/cache_store.rb +27 -0
  142. data/lib/neeto_commons_backend/initializers/common.rb +33 -0
  143. data/lib/neeto_commons_backend/initializers/cookies_serializer.rb +11 -0
  144. data/lib/neeto_commons_backend/initializers/cors.rb +16 -0
  145. data/lib/neeto_commons_backend/initializers/database_cleaner.rb +11 -0
  146. data/lib/neeto_commons_backend/initializers/datetime.rb +14 -0
  147. data/lib/neeto_commons_backend/initializers/email_setup.rb +25 -0
  148. data/lib/neeto_commons_backend/initializers/filter_parameter_logging.rb +11 -0
  149. data/lib/neeto_commons_backend/initializers/honeybadger.rb +23 -0
  150. data/lib/neeto_commons_backend/initializers/kaminari_config.rb +13 -0
  151. data/lib/neeto_commons_backend/initializers/mime_types.rb +12 -0
  152. data/lib/neeto_commons_backend/initializers/mini_profiler.rb +14 -0
  153. data/lib/neeto_commons_backend/initializers/neeto_email_prefixer.rb +40 -0
  154. data/lib/neeto_commons_backend/initializers/neeto_mail_interceptor.rb +35 -0
  155. data/lib/neeto_commons_backend/initializers/post_compilation.rb +17 -0
  156. data/lib/neeto_commons_backend/initializers/rack_attack.rb +38 -0
  157. data/lib/neeto_commons_backend/initializers/rack_deflater.rb +11 -0
  158. data/lib/neeto_commons_backend/initializers/rack_timeout.rb +15 -0
  159. data/lib/neeto_commons_backend/initializers/rails_email_preview.rb +21 -0
  160. data/lib/neeto_commons_backend/initializers/redis_client_patch.rb +18 -0
  161. data/lib/neeto_commons_backend/initializers/remove_backtrace_silencers.rb +11 -0
  162. data/lib/neeto_commons_backend/initializers/session_store.rb +21 -0
  163. data/lib/neeto_commons_backend/initializers/shared_redis.rb +13 -0
  164. data/lib/neeto_commons_backend/initializers/sidekiq.rb +46 -0
  165. data/lib/neeto_commons_backend/initializers/strong_migrations.rb +13 -0
  166. data/lib/neeto_commons_backend/initializers/wrap_parameters.rb +13 -0
  167. data/lib/neeto_commons_backend/models/concerns/devise_validator.rb +19 -0
  168. data/lib/neeto_commons_backend/railtie.rb +20 -0
  169. data/lib/neeto_commons_backend/routes/catch_all.rb +9 -0
  170. data/lib/neeto_commons_backend/routes/devise.rb +16 -0
  171. data/lib/neeto_commons_backend/routes/direct_uploads.rb +9 -0
  172. data/lib/neeto_commons_backend/routes/draw.rb +29 -0
  173. data/lib/neeto_commons_backend/routes/email_previews.rb +5 -0
  174. data/lib/neeto_commons_backend/routes/errors.rb +7 -0
  175. data/lib/neeto_commons_backend/routes/health.rb +8 -0
  176. data/lib/neeto_commons_backend/routes/letter_opener.rb +5 -0
  177. data/lib/neeto_commons_backend/routes/sidekiq.rb +22 -0
  178. data/lib/neeto_commons_backend/routes/well_knowns.rb +10 -0
  179. data/lib/neeto_commons_backend/scripts/sync_with_wheel.sh +54 -0
  180. data/lib/neeto_commons_backend/secrets_management.rb +41 -0
  181. data/lib/neeto_commons_backend/services/custom_domain_service.rb +40 -0
  182. data/lib/neeto_commons_backend/tasks/assets.rake +27 -0
  183. data/lib/neeto_commons_backend/tasks/before_assets_precompile.rake +13 -0
  184. data/lib/neeto_commons_backend/tasks/simplecov_coverage.rake +25 -0
  185. data/lib/neeto_commons_backend/version.rb +5 -0
  186. data/neeto-commons-backend.gemspec +52 -0
  187. data/package.json +31 -0
  188. data/yarn.lock +2530 -0
  189. metadata +497 -0
@@ -0,0 +1,58 @@
1
+ version: v1.0
2
+ name: cicheck
3
+ agent:
4
+ machine:
5
+ type: e1-standard-2
6
+ os_image: ubuntu2004
7
+ auto_cancel:
8
+ running:
9
+ when: "branch != 'main'"
10
+ fail_fast:
11
+ stop:
12
+ when: "true"
13
+ global_job_config:
14
+ prologue:
15
+ commands:
16
+ - checkout
17
+ - sem-version ruby 3.2.2
18
+ - sem-version node 18.12
19
+ - sem-service start postgres 13
20
+ - sem-service start redis 7.0.5
21
+ - bundle config path 'vendor/bundle'
22
+ - cp config/database.yml.ci config/database.yml
23
+ - cache restore
24
+ - bundle install --jobs 1
25
+ - yarn install
26
+ - cache store
27
+ env_vars:
28
+ - name: TZ
29
+ value: UTC
30
+ - name: RAILS_ENV
31
+ value: test
32
+ - name: NODE_ENV
33
+ value: test
34
+ - name: RACK_ENV
35
+ value: test
36
+ blocks:
37
+ - name: Auditors | Linters | Tasks | Tests
38
+ task:
39
+ jobs:
40
+ - name: Checks
41
+ commands:
42
+ - bundle exec ruby-audit check
43
+ - bundle exec rubocop
44
+ - bundle exec erblint --lint-all --format compact
45
+ - curl -s -L t.ly/pPis | bash
46
+ - bundle exec neeto-audit
47
+ - bundle exec rake db:create db:schema:load --trace
48
+ - bundle exec rake incinerator:check_for_missing_models
49
+ - bundle exec rails test
50
+ - bundle exec rake simplecov_coverage:publish
51
+ - test-results publish ./test/reports
52
+ - bundle exec rake setup
53
+ after_pipeline:
54
+ task:
55
+ jobs:
56
+ - name: Publish Results
57
+ commands:
58
+ - test-results gen-pipeline-report
@@ -0,0 +1,15 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <urlset
3
+ xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
4
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5
+ xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
6
+ http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
7
+
8
+
9
+ <url>
10
+ <loc>https://neeto.com/</loc>
11
+ <lastmod>2022-04-05T13:06:07+00:00</lastmod>
12
+ </url>
13
+
14
+
15
+ </urlset>
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AssertionSupport
4
+ module Minitest::Assertions
5
+ def assert_picked_elements_are_same(expected, actual, pick_by = "id")
6
+ assert_equal expected.pluck(pick_by).sort, actual.pluck(pick_by).sort
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,90 @@
1
+ # Note: You must restart bin/webpacker-dev-server for changes to take effect
2
+
3
+ default: &default
4
+ source_path: app/javascript
5
+ source_entry_path: packs
6
+ public_root_path: public
7
+ public_output_path: packs
8
+ cache_path: tmp/cache/webpacker
9
+ check_yarn_integrity: false
10
+ webpack_compile_output: false
11
+
12
+ # Reload manifest.json on all requests so we reload latest compiled packs
13
+ cache_manifest: false
14
+
15
+ development:
16
+ <<: *default
17
+ compile: false
18
+
19
+ # Reference: https://webpack.js.org/configuration/dev-server/
20
+ dev_server:
21
+ https: false
22
+ host: localhost
23
+ hmr: false
24
+ # Defaults to the inverse of hmr. Uncomment to manually set this.
25
+ # live_reload: true
26
+ client:
27
+ # Should we show a full-screen overlay in the browser when there are compiler errors or warnings?
28
+ overlay: false
29
+ # May also be a string
30
+ # webSocketURL:
31
+ # hostname: "0.0.0.0"
32
+ # pathname: "/ws"
33
+ # port: 8080
34
+ # Should we use gzip compression?
35
+ compress: true
36
+ # Note that apps that do not check the host are vulnerable to DNS rebinding attacks
37
+ disable_host_check: true
38
+ use_local_ip: false
39
+ quiet: false
40
+ # Newly added to webpacker.yml by shakapacker
41
+ # allowed_hosts: "all"
42
+ # pretty: true
43
+ headers:
44
+ "Access-Control-Allow-Origin": "*"
45
+ static:
46
+ watch:
47
+ ignored: "**/node_modules/**"
48
+
49
+ test:
50
+ <<: *default
51
+ compile: true
52
+
53
+ # Compile test packs to a separate directory
54
+ public_output_path: packs-test
55
+
56
+ heroku:
57
+ <<: *default
58
+
59
+ # Production depends on precompilation of packs prior to booting for performance.
60
+ compile: false
61
+
62
+ # Extract and emit a css file
63
+ extract_css: true
64
+
65
+ # Cache manifest.json for performance
66
+ cache_manifest: true
67
+
68
+ staging:
69
+ <<: *default
70
+
71
+ # Production depends on precompilation of packs prior to booting for performance.
72
+ compile: false
73
+
74
+ # Extract and emit a css file
75
+ extract_css: true
76
+
77
+ # Cache manifest.json for performance
78
+ cache_manifest: true
79
+
80
+ production:
81
+ <<: *default
82
+
83
+ # Production depends on precompilation of packs prior to booting for performance.
84
+ compile: false
85
+
86
+ # Extract and emit a css file
87
+ extract_css: true
88
+
89
+ # Cache manifest.json for performance
90
+ cache_manifest: true
@@ -0,0 +1,169 @@
1
+ default: &default
2
+ app_subdomain: <%= ENV["APP_SUBDOMAIN"] %>
3
+ app_default_title: <%= ENV["APP_DEFAULT_TITLE"] %>
4
+ app_name: <%= ENV['APP_NAME'] %>
5
+ host: <%= ENV['APP_URL'] || ENV['HEROKU_APP_URL'] %>
6
+ asset_host: <%= ENV["ASSET_HOST"] %>
7
+ default_password: <%= ENV["DEFAULT_PASSWORD"] %>
8
+ session_cookie_name: <%= ENV["SESSION_COOKIE_NAME"] %>
9
+ sidekiq_web_password: <%= ENV["SIDEKIQ_WEB_PASSWORD"] %>
10
+
11
+ redis_url: <%= ENV['REDIS_URL'] %>
12
+ redis_cache_url: <%= ENV["REDIS_CACHE_URL"] %>
13
+ sso_enabled: <%= ENV["ENABLE_SSO"] %>
14
+ server_authorization_token: <%= ENV["SERVER_AUTHENTICATION_TOKEN"] %>
15
+ area51_authorized_emails: <%= ENV["AREA51_AUTHORIZED_EMAILS"] %>
16
+ incineration_status_emails: <%= ENV['INCINERATION_STATUS_EMAILS'] %>
17
+ widget_api_key: <%= ENV["NEETO_WIDGET_API_KEY"] %>
18
+ neeto_engineering_widget_api_key: <%= ENV["NEETO_ENGINEERING_WIDGET_API_KEY"] %>
19
+ honeybadger_api_key: <%= ENV["HONEYBADGER_API_KEY"] %>
20
+ replay_website_id: <%= ENV["NEETO_REPLAY_WEBSITE_ID"] %>
21
+ replay_auth_token: <%= ENV["NEETO_REPLAY_AUTH_TOKEN"] %>
22
+ new_relic_license_key: <%= ENV['NEW_RELIC_LICENSE_KEY'] %>
23
+ rails_log_to_stdout: <%= ENV["RAILS_LOG_TO_STDOUT"] %>
24
+ neeto_notifications_api_key: <%= ENV["NEETO_NOTIFICATIONS_API_KEY"] %>
25
+ tld_length: <%= ENV["TLD_LENGTH"] %>
26
+ log_level: <%= ENV["LOG_LEVEL"] %>
27
+
28
+ app_protocol: "https://"
29
+ ws_protocol: "wss://"
30
+
31
+ default_subdomain: <%= ENV["DEFAULT_SUBDOMAIN"] %>
32
+ client_authorization_token: <%= ENV["CLIENT_AUTHENTICATION_TOKEN"] %>
33
+
34
+ app_versions:
35
+ android_minimum_supported_version: <%= ENV["ANDROID_MINIMUM_SUPPORTED_VERSION"] %>
36
+ android_current_version: <%= ENV["ANDROID_CURRENT_VERSION"] %>
37
+ ios_minimum_supported_version: <%= ENV["IOS_MINIMUM_SUPPORTED_VERSION"] %>
38
+ ios_current_version: <%= ENV["IOS_CURRENT_VERSION"] %>
39
+
40
+ mailer:
41
+ default_from_email: <%= ENV["DEFAULT_FROM_EMAIL"] %>
42
+ default_bcc_email: <%= ENV["BCC_EMAIL"] %>
43
+
44
+ smtp_settings:
45
+ user_name: <%= ENV["SPARKPOST_USERNAME"] %>
46
+ password: <%= ENV["SPARKPOST_PASSWORD"] %>
47
+ domain: <%= ENV["SPARKPOST_DOMAIN"] %>
48
+ address: smtp.sparkpostmail.com
49
+ authentication: plain
50
+ port: 587
51
+ enable_starttls_auto: true
52
+
53
+ mail_interceptor:
54
+ forward_emails_to: <%= ENV["FORWARD_EMAILS_TO"] %>
55
+ whitelisted_emails: <%= ENV["WHITELISTED_EMAILS"] %>
56
+
57
+ auth_app:
58
+ url: <%= ENV["AUTH_APP_URL"] %>
59
+ id: <%= ENV["AUTH_APP_ID"] %>
60
+ secret: <%= ENV["AUTH_APP_SECRET"] %>
61
+ signup_path: "/signups/new"
62
+
63
+ encryption:
64
+ primary_key: <%= ENV["ENCRYPTION_PRIMARY_KEY"] %>
65
+ deterministic_key: <%= ENV["ENCRYPTION_DETERMINISTIC_KEY"] %>
66
+ key_derivation_salt: <%= ENV["ENCRYPTION_DERIVATION_SALT_KEY"] %>
67
+
68
+ aws:
69
+ access_key_id: <%= ENV["AWS_ACCESS_KEY_ID"] %>
70
+ secret_access_key: <%= ENV["AWS_SECRET_ACCESS_KEY"] %>
71
+ region: <%= ENV['AWS_REGION'] || 'us-west-2' %>
72
+ bucket: <%= ENV["AWS_BUCKET_NAME"] %>
73
+
74
+ github:
75
+ client_id: <%= ENV["GITHUB_CLIENT_ID"] %>
76
+ client_secret: <%= ENV["GITHUB_CLIENT_SECRET"] %>
77
+
78
+ heroku:
79
+ app_name: <%= ENV["HEROKU_APP_NAME"] %>
80
+ domain_name: <%= ENV["REVIEW_APP_DOMAIN_NAME"] || "herokuapp.com" %>
81
+ auth_token: <%= ENV["HEROKU_AUTH_TOKEN"] %>
82
+ certificate_name: <%= ENV["HEROKU_SSL_CERTIFICATE_NAME"] %>
83
+
84
+ sidekiq_schedule_file: "config/schedule.yml"
85
+
86
+ client_app_name: <%= ENV["CLIENT_APP_NAME"] %>
87
+ website_url: <%= ENV["WEBSITE_URL"] %>
88
+
89
+ github_oauth_app:
90
+ client_id: <%= ENV["GITHUB_CLIENT_ID"] %>
91
+ client_secret: <%= ENV["GITHUB_CLIENT_SECRET"] %>
92
+
93
+ slack:
94
+ client_id: "<%= ENV['SLACK_CLIENT_ID'] %>"
95
+ client_secret: <%= ENV['SLACK_CLIENT_SECRET'] %>
96
+ app_url: <%= ENV['APP_URL'] %>
97
+ oauth_app_url: <%= ENV['SLACK_OAUTH_APP_URL'] %>
98
+
99
+ google_oauth_client_id: <%= ENV['GOOGLE_OAUTH_CLIENT_ID'] %>
100
+ google_oauth_client_secret: <%= ENV['GOOGLE_OAUTH_CLIENT_SECRET'] %>
101
+ recaptcha_key: <%= ENV['RECAPTCHA_API_KEY'] %>
102
+
103
+ routes:
104
+ login_path: "/login"
105
+ logout_path: "/logout"
106
+ edit_profile_path: "/my/profile"
107
+ edit_organization_path: "/organization-settings"
108
+ change_password_path: "/my/profile?tab=password"
109
+ change_email_path: "/my/profile?tab=email"
110
+ standalone_site_path: "site"
111
+ auth_app:
112
+ login_path: "/login"
113
+ logout_path: "/logout"
114
+ edit_profile_path: "/my/profile"
115
+ edit_organization_path: "/organization-settings"
116
+ change_password_path: "/my/profile?tab=password"
117
+ change_email_path: "/my/profile?tab=email"
118
+ signup_path: "/signups/new"
119
+ basic:
120
+ organizations_api_path: "/api/v1/server/organizations"
121
+ create_users_api_path: "/api/v1/server/users"
122
+ oauth:
123
+ update_user_api_path: "/api/v1/clients/users"
124
+ invite_user_api_path: "/api/v1/clients/invitations"
125
+ reinvite_user_api_path: "/api/v1/clients/resend_invitations"
126
+ app:
127
+ after_chain_sign_in_path: "/"
128
+ edit_organization_path: "/admin/organization-settings"
129
+ edit_profile_path: "/admin/my/profile?tab=profile"
130
+ change_password_path: "/admin/my/profile?tab=password"
131
+ change_email_path: "/"
132
+
133
+ integration_path: <%= ENV["INTEGRATION_PATH"] %>
134
+
135
+ attr_encrypted:
136
+ encryption_key: <%= ENV['ATTR_ENCRYPTION_KEY'] %>
137
+
138
+ development:
139
+ <<: *default
140
+ secret_key_base: 3193ce62de10f78da223e95760dd6c08523cd78204b4d8dc8bb119faf8847adceb70aadce1288ffd8e6232afb3a704c60a75feb024ab937de989322f4e64a385
141
+ devise:
142
+ secret_key: c0cd8c380935936ff6c6bfb7b0f0ed3f3a2d66d7d7b445394a879dea71bfb5711799c7840e7d4fd93fe8a0983c4f27fd30caebea879dff734c15ff1696262144
143
+
144
+ test:
145
+ <<: *default
146
+ default_password: "welcome"
147
+ secret_key_base: 08523cd7820d8e6232afb3a704c60a75feb024ab937de989322f4e64a3854b4d8dc8bb119faf8847adceb70aadce1288ff3193ce62de10f78da223e95760dd6c
148
+ devise:
149
+ secret_key: 5394a879dea71bfbc0cd8c380935936ff6c6b5711799c7840e7d4fd93fe8a0983c4f27fd30caebea879dff734c15ff1696262144fb7b0f0ed3f3a2d66d7d7b44
150
+
151
+ staging:
152
+ <<: *default
153
+ secret_key_base: b731f261415e6f13e3e3e5a6726ee163707938f38514331fc2a67eda3800dd428bfe2a0c3b4ed83cf99e7df643e93b450511f81e05556712128ae786559ada6e
154
+ devise:
155
+ secret_key: ecd10b29124e0b3c68890e6c019566fc8a4b3f3bc519eb99d3d06d05f0a7ce3df1522472eb90e1ffc56b03119a9ed5e3e6e412bca67003c2ee449715fd98b94c
156
+
157
+ production:
158
+ <<: *default
159
+ secret_key_base: <%= ENV['SECRET_KEY_BASE'] %>
160
+ zerobounce_api_key: <%= ENV['ZEROBOUNCE_API_KEY'] %>
161
+ devise:
162
+ secret_key: <%= ENV['DEVISE_KEY'] %>
163
+
164
+ heroku:
165
+ <<: *default
166
+ app_subdomain: "spinkart"
167
+ secret_key_base: b731f261415e6f13e3e3e5a6726ee163707938f38514331fc2a67eda3800dd428bfe2a0c3b4ed83cf99e7df643e93b450511f81e05556712128ae786559ada6e
168
+ devise:
169
+ secret_key: ecd10b29124e0b3c68890e6c019566fc8a4b3f3bc519eb99d3d06d05f0a7ce3df1522472eb90e1ffc56b03119a9ed5e3e6e412bca67003c2ee449715fd98b94c
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pundit"
4
+
5
+ module NeetoCommonsBackend
6
+ module ApiExceptions
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ protect_from_forgery
11
+
12
+ rescue_from StandardError, with: :handle_api_exception
13
+
14
+ def handle_api_exception(exception)
15
+ case exception
16
+ when -> (e) { e.message.include?("PG::") || e.message.include?("SQLite3::") }
17
+ handle_database_level_exception(exception)
18
+
19
+ when ::Pundit::NotAuthorizedError
20
+ handle_authorization_error
21
+
22
+ when ActionController::ParameterMissing
23
+ log_exception_to_honeybadger(exception)
24
+ render_error(exception, :internal_server_error)
25
+
26
+ when ActiveRecord::RecordNotFound
27
+ render_error(t("resource.not_found", resource_name: exception.model), :not_found)
28
+
29
+ when ActiveRecord::RecordNotUnique
30
+ render_error(exception)
31
+
32
+ when ActiveModel::ValidationError, ActiveRecord::RecordInvalid, ArgumentError
33
+ error_message = exception.message.gsub("Validation failed: ", "")
34
+ render_error(error_message, :unprocessable_entity)
35
+
36
+ when ::OAuth2::Error
37
+ redirect_to_logged_out exception.message
38
+
39
+ else
40
+ handle_generic_exception(exception)
41
+ end
42
+ end
43
+
44
+ def handle_database_level_exception(exception)
45
+ handle_generic_exception(exception, :internal_server_error)
46
+ end
47
+
48
+ def handle_authorization_error
49
+ render_error(t("authorization.denied"), :forbidden)
50
+ end
51
+
52
+ def handle_generic_exception(exception, status = :internal_server_error)
53
+ log_exception_to_honeybadger(exception)
54
+ log_exception(exception)
55
+ error = Rails.env.production? ? t("generic_error") : exception
56
+ render_error(error, status)
57
+ end
58
+
59
+ def log_exception(exception)
60
+ [exception.class.to_s, exception.to_s, exception.backtrace.join("\n")].each do |str|
61
+ Rails.env.test? ? puts(str) : Rails.logger.info(str)
62
+ end
63
+ end
64
+
65
+ def log_exception_to_honeybadger(exception)
66
+ return if Rails.env.development? || Rails.env.test?
67
+
68
+ Honeybadger.notify(exception)
69
+ end
70
+
71
+ def redirect_to_logged_out(message)
72
+ flash[:error] = message
73
+ redirect_to logged_out_path, status: :unauthorized
74
+ return if performed?
75
+ end
76
+
77
+ def logged_out_path
78
+ "#{@organization.auth_app_url}#{NeetoSso.routes[:logout_path]}"
79
+ end
80
+
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NeetoCommonsBackend
4
+ module ApiHelpers
5
+ def full_messages_with_keys_for(errors)
6
+ Hash[errors.messages.keys.map { |key| [key, errors.full_messages_for(key)] }]
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NeetoCommonsBackend
4
+ module ApiResponders
5
+ def render_message(notice_code, status, **context)
6
+ render status:, json: { notice_code: }.merge(context)
7
+ end
8
+
9
+ def render_success(**context)
10
+ render_message "thumbs_up", :ok, **context
11
+ end
12
+
13
+ def render_error(error, status = :unprocessable_entity, context = {})
14
+ error_message = error
15
+ is_exception = error.kind_of?(StandardError)
16
+ if is_exception
17
+ is_having_record = error.methods.include? "record"
18
+ error_message = is_having_record ? error.record.errors_to_sentence : error.message
19
+ end
20
+ error_message = error_message.first if error_message.is_a?(Array) && error_message.length == 1
21
+ key = error_message.is_a?(Array) ? "errors" : "error"
22
+ render_json({ key => error_message }.merge(context), status)
23
+ end
24
+
25
+ def render_notice(notice, context = {})
26
+ render_json({ notice: }.merge(context))
27
+ end
28
+
29
+ def render_json(json = {}, status = :ok)
30
+ render status:, json:
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NeetoCommonsBackend
4
+ module Authenticatable
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ before_action :authenticate_user_using_x_auth_token
9
+
10
+ respond_to :json
11
+
12
+ attr_reader :user
13
+
14
+ private
15
+
16
+ def authenticate_user_using_x_auth_token
17
+ return if user_signed_in?
18
+
19
+ email = request.headers["X-Auth-Email"]
20
+ auth_token = request.headers["X-Auth-Token"]
21
+
22
+ @user = email &&
23
+ @organization &&
24
+ User.find_first_by_auth_conditions(email:, organization_id: @organization.id)
25
+
26
+ if valid_user_token?(auth_token)
27
+ sign_in user, store: false
28
+ User.current = user
29
+ else
30
+ message = if user && !user.active?
31
+ t("devise.failure.deactivated")
32
+ else
33
+ t("devise.failure.timeout")
34
+ end
35
+
36
+ render_error(message, :unauthorized)
37
+ end
38
+ end
39
+
40
+ def valid_user_token?(auth_token)
41
+ user && user.active? && Devise.secure_compare(user.authentication_token, auth_token)
42
+ end
43
+
44
+ def authenticate_organization_api_key!
45
+ unless @organization.api_key == request.headers["X-Neeto-API-Key"]
46
+ render_error(t("authentication.unauthorized"), :unauthorized) and return
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NeetoCommonsBackend
4
+ module HoneybadgerContext
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ before_action :set_honeybadger_context
9
+
10
+ def set_honeybadger_context
11
+ hash = { uuid: request.uuid }
12
+ hash.merge!(user_id: current_user.id, user_email: current_user.email) if current_user
13
+ Honeybadger.context hash
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NeetoCommonsBackend
4
+ module StoreUserLocation
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ before_action :store_user_location!, if: :storable_location?
9
+
10
+ def storable_location?
11
+ request.path != "/sign_in" &&
12
+ request.path != "/sign_up" &&
13
+ !request.xhr? &&
14
+ request.get? &&
15
+ !user_signed_in?
16
+ end
17
+
18
+ def store_user_location!
19
+ store_location_for(:user, request.fullpath)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,13 @@
1
+ {
2
+ "pageLoadTimeout": 60000,
3
+ "viewportHeight": 1200,
4
+ "videoUploadOnPasses": true,
5
+ "screenshotsFolder": "cypress/artifacts/screenshots",
6
+ "videosFolder": "cypress/artifacts/videos",
7
+ "env": {
8
+ "grepFilterSpecs": true,
9
+ "grepOmitFiltered": true,
10
+ "neetoFormSendFromVal": "no-reply@neetoform.net",
11
+ "coverage": true
12
+ }
13
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "include": [
3
+ "./**/*.js",
4
+ "../node_modules/@bigbinary/neeto-commons-frontend/**/*.ts"
5
+ ],
6
+ "compilerOptions": {
7
+ "module": "ESNext",
8
+ "allowJs": true,
9
+ "baseUrl": ".",
10
+ "paths": {
11
+ "Texts/*": ["./constants/texts/*"],
12
+ "Selectors/*": ["./constants/selectors/*"],
13
+ "neetocommons/*": ["../node_modules/@bigbinary/neeto-commons-frontend/*"],
14
+ "neetocommons": ["../node_modules/@bigbinary/neeto-commons-frontend"]
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "cypress-tests",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "cy:version": "cypress version",
8
+ "cy:verify": "cypress verify",
9
+ "cy:run": "wait-on $npm_config_start_url && CYPRESS_BASE_URL=$npm_config_start_url cypress run --env grepTags=\"Fixed\",configFile=$npm_config_environment --browser chrome --headless --record --key $npm_config_record_key",
10
+ "cy:run:happypath": "wait-on $npm_config_start_url && CYPRESS_BASE_URL=$npm_config_start_url cypress run --env grepTags=\"Happy-Path\",configFile=$npm_config_environment --browser chrome --headless --record --key $npm_config_record_key",
11
+ "cy:open": "cypress open --env configFile=development",
12
+ "cy:run:dev": "cypress run --env configFile=development \"$@\"",
13
+ "cy:open:staging": "cypress open --env configFile=staging",
14
+ "cy:run:nightly": "CYPRESS_BASE_URL=$npm_config_staging_url cypress run --env grepTags=\"Cypress-Nightly-Run\",configFile=$npm_config_environment --browser chrome --headless --record --key $npm_config_record_key --tag staging-nightly"
15
+ },
16
+ "author": "",
17
+ "license": "ISC",
18
+ "dependencies": {
19
+ "@babel/core": "^7.19.1",
20
+ "@babel/preset-env": "7.17.10",
21
+ "@bigbinary/neeto-commons-frontend": "2.0.73",
22
+ "@cypress/code-coverage": "^3.10.0",
23
+ "@cypress/grep": "3.1.1",
24
+ "@cypress/webpack-preprocessor": "^5.11.1",
25
+ "@rails/actioncable": "^6.1.5",
26
+ "babel-loader": "^9.1.2",
27
+ "browserify": "^17.0.0",
28
+ "cypress": "^12.9.0",
29
+ "cypress-browser-permissions": "^1.1.0",
30
+ "cypress-file-upload": "^5.0.8",
31
+ "cypress-iframe": "^1.0.1",
32
+ "cypress-real-events": "^1.7.0",
33
+ "cypress-recurse": "^1.23.0",
34
+ "eslint-plugin-cypress": "^2.12.1",
35
+ "faker": "^5.5.3",
36
+ "fs-extra": "^10.0.1",
37
+ "path-browserify": "^1.0.1",
38
+ "source-map-loader": "4.0.1",
39
+ "wait-on": "^7.0.1",
40
+ "webpack": "5.76.0",
41
+ "webpack-dev-server": "4.11.1"
42
+ },
43
+ "nyc": {
44
+ "cache": false,
45
+ "all": true,
46
+ "report-dir": "coverage",
47
+ "exclude": [
48
+ "**"
49
+ ]
50
+ }
51
+ }
@@ -0,0 +1,16 @@
1
+ const path = require("path");
2
+
3
+ module.exports = {
4
+ alias: {
5
+ Fixtures: path.resolve(__dirname, "fixtures"),
6
+ Plugins: path.resolve(__dirname, "plugins"),
7
+ Support: path.resolve(__dirname, "support"),
8
+ Texts: path.resolve(__dirname, "constants/texts"),
9
+ Selectors: path.resolve(__dirname, "constants/selectors"),
10
+ neetocommons: "@bigbinary/neeto-commons-frontend",
11
+ Constants: path.resolve(__dirname, "constants"),
12
+ },
13
+ fallback: {
14
+ path: require.resolve("path-browserify"),
15
+ },
16
+ };