Compare commits

...

199 commits

Author SHA1 Message Date
Izalia Mae 686df3be21 Merge branch 'main' of https://git.barkshark.xyz/mirror/mastodon 2024-02-01 11:45:28 -05:00
Claire 3866597e24
Merge pull request #2601 from ClearlyClaire/glitch-soc/fixes/security-builds-latest
Fix security builds not being tagged latest
2024-02-01 11:48:45 +01:00
Claire a7b16003e1 Fix security builds not being marked latest 2024-02-01 11:31:29 +01:00
Claire 626ff320cf
Merge pull request #2600 from ClearlyClaire/glitch-soc/fixes/failures
Configure selenium to use Chrome version 120 (#29038)
2024-02-01 11:30:34 +01:00
Matt Jankowski f4416e6b3a Configure selenium to use Chrome version 120 (#29038) 2024-02-01 11:15:23 +01:00
Claire 7bb5f6efbc
Merge pull request #2599 from ClearlyClaire/glitch-soc/build-action
Add github action workflow for manual security builds
2024-02-01 11:14:40 +01:00
Claire 883f589653 Fix missing workflow_dispatch trigger for build-security (#29041) 2024-02-01 10:58:10 +01:00
Claire 85bdd145dc Adapt workflow to glitch-soc 2024-02-01 10:40:04 +01:00
Claire a48447a6b2 Add github action workflow for manual security builds (#29040) 2024-02-01 10:39:23 +01:00
Claire 8b87673f5e
Remove obsolete locale file (#2596) 2024-01-30 23:21:35 +01:00
Claire 3ede233146
Fix crash in private mention conversations in glitch-soc flavor (#2595) 2024-01-30 22:42:22 +01:00
Claire 80308d384a
[Glitch] Refactor conversations components in web UI (#2589)
Port 3205a654ca to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
Co-authored-by: Eugen Rochko <eugen@zeonfederated.com>
2024-01-28 14:53:08 +01:00
Claire a4e7cc2d94
Merge pull request #2590 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to bf153b384b
2024-01-28 14:47:35 +01:00
Claire bf153b384b Merge commit '42ab855b2339c5cea3229c856ab539f883736b12' into glitch-soc/merge-upstream
Conflicts:
- `app/controllers/auth/confirmations_controller.rb`:
  Upstream refactored, changing lines textually close of glitch-soc-only lines
  pertaining to the theming system.
  Resolved the conflict.
- `app/controllers/auth/passwords_controller.rb`:
  Upstream refactored, changing lines textually close of glitch-soc-only lines
  pertaining to the theming system.
  Resolved the conflict.
- `app/controllers/settings/two_factor_authentication/webauthn_credentials_controller.rb`:
  Upstream refactored, changing lines textually close of glitch-soc-only lines
  pertaining to the theming system.
  Resolved the conflict.
2024-01-27 19:06:41 +01:00
Claire 420ca90071
Merge pull request #2585 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 3205a654ca
2024-01-27 18:35:29 +01:00
Claire dd7a66949a Fix CSS loading in redirect controller 2024-01-26 21:04:02 +01:00
Claire 54ece5040d [Glitch] Use active variants for boost icons and increase icon size
Port 5a838ceaa9 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-01-26 20:53:53 +01:00
Eugen Rochko e5f50478b5 [Glitch] Add confirmation when redirecting logged-out requests to permalink
Port SCSS changes from b19ae521b7 to glitch-soc

Co-authored-by: Claire <claire.github-309c@sitedethib.com>
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-01-26 20:51:08 +01:00
Claire 5fa2821853 Merge commit '3205a654caf903002c2db872f802a3332201678b' into glitch-soc/merge-upstream 2024-01-26 20:47:20 +01:00
github-actions[bot] ae9c675930
New Crowdin Translations (automated) (#2564)
* New Crowdin translations

* Fix bogus translation files

---------

Co-authored-by: GitHub Actions <noreply@github.com>
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2024-01-26 19:45:04 +01:00
Claire 108fb33478
Merge pull request #2584 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 7a1f087659
2024-01-26 18:47:09 +01:00
Claire 70de52c297 Merge commit '7a1f087659204e9d0cbba2de37e45b1921cefe20' into glitch-soc/merge-upstream 2024-01-25 19:51:19 +01:00
Claire adde803656
Merge pull request #2583 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 01ce9df880
2024-01-25 19:50:12 +01:00
Matt Jankowski 42ab855b23
Add specs for Instance model scopes and add with_domain_follows scope (#28767) 2024-01-25 15:28:27 +00:00
Matt Jankowski 4cdf62e576
Extract rebuild_index method in maintenance CLI (#28911) 2024-01-25 15:26:51 +00:00
Matt Jankowski 0b38946c87
Update paperclip and climate_control gems (#28379) 2024-01-25 15:18:15 +00:00
Matt Jankowski 17ea22671d
Fix Style/GuardClause cop in app/controllers (#28420) 2024-01-25 15:13:41 +00:00
Eugen Rochko 3205a654ca
Refactor conversations components in web UI (#28833)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2024-01-25 14:34:26 +00:00
Matt Jankowski 274a48a9f4
Extract helper methods for db connection and table existence check in CLI::Maintenance task (#28281) 2024-01-25 13:49:33 +00:00
Matt Jankowski 2866106ec1
Reduce factory creation in spec/models/account_statuses_cleanup_policy (#28361) 2024-01-25 13:37:25 +00:00
Matt Jankowski c8f59d2ca4
Fix Style/TernaryParentheses cop (#28387) 2024-01-25 13:28:49 +00:00
Matt Jankowski ca7053f19c
Consolidate db test prep steps to rake task (#28886) 2024-01-25 13:10:39 +00:00
github-actions[bot] 59d2ea0d82
New Crowdin Translations (automated) (#28899)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-01-25 13:00:44 +00:00
Matt Jankowski 6b6586f5d0
Add CustomFilterKeyword#to_regex method (#28893) 2024-01-25 13:00:34 +00:00
renovate[bot] a69506a434
fix(deps): update dependency dotenv to v16.4.1 (#28889)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-25 12:37:23 +00:00
Matt Jankowski 7c9c6c7f80
Fix remaining Rails/WhereExists cop violations, regenerate todo (#28892) 2024-01-25 12:37:07 +00:00
renovate[bot] 1a565e4bea
fix(deps): update dependency axios to v1.6.6 (#28895)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-25 12:36:20 +00:00
renovate[bot] d158f7e622
chore(deps): update dependency rspec-rails to v6.1.1 (#28905)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-25 12:33:56 +00:00
Claire 087415d0fe
Add tests for processing statuses using bearcap URIs (#28904) 2024-01-25 11:13:36 +00:00
Claire 0471a78055
Add tests for redirect confirmations (#28903) 2024-01-25 11:13:33 +00:00
Claire c50274a0ac
Fix redirect confirmation for accounts (#28902) 2024-01-25 10:44:25 +00:00
KMY(雪あすか) 9a8293f58d
Fix process of receiving posts with bearcaps is not working (#26527) 2024-01-25 10:37:09 +00:00
Eugen Rochko 22e419f95e [Glitch] Fix search form re-rendering spuriously in web UI
Port 01ce9df880 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-01-24 20:53:15 +01:00
Claire 22cfab0ebf Merge commit '01ce9df88008cee705b7e02a4581802afa07c3df' into glitch-soc/merge-upstream
Conflicts:
- `tsconfig.json`:
  Upstream made style fixes, while glitch-soc had extra options.
  Ported upstream's style fixes.
2024-01-24 20:42:53 +01:00
Matt Jankowski 38f7f8b909
Tidy up association declaration in Instance model (#28880) 2024-01-24 17:30:28 +00:00
renovate[bot] 9c5be13980
chore(deps): update dependency chewy to v7.5.0 (#28730)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-24 16:51:47 +00:00
renovate[bot] 7019af431d
fix(deps): update dependency dotenv to v16.4.0 (#28872)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-24 16:51:36 +00:00
renovate[bot] 559bbf0aa6
chore(deps): update artifact actions (major) to v4 (major) (#28415)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-24 16:51:18 +00:00
renovate[bot] ea5397c373
chore(deps): update dependency selenium-webdriver to v4.17.0 (#28858)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-24 14:55:06 +00:00
renovate[bot] 64993d3f77
chore(deps): update dependency haml_lint to v0.55.0 (#28856)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-24 13:37:37 +00:00
Claire 5a838ceaa9
Use active variants for boost icons and increase icon size (#27924) 2024-01-24 12:37:43 +00:00
Matt Jankowski 1290fede65
Fix Rails/WhereExists cop in app/lib (#28862) 2024-01-24 11:51:09 +00:00
renovate[bot] 41c2af2270
chore(deps): update dependency rubocop to v1.60.1 (#28731)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-24 11:50:41 +00:00
Claire 634acd07c4
Merge pull request #2580 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to e2d9635074
2024-01-24 12:11:05 +01:00
Eugen Rochko b19ae521b7
Add confirmation when redirecting logged-out requests to permalink (#27792)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2024-01-24 10:49:19 +00:00
Matt Jankowski 7a1f087659
Add created_before and updated_before scopes to MediaAttachment (#28869) 2024-01-24 10:32:54 +00:00
Matt Jankowski a11a2fb052
Add error classes to api/base errors coverage (#28864) 2024-01-24 10:31:31 +00:00
github-actions[bot] a34d27c18f
New Crowdin Translations (automated) (#28875)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-01-24 10:06:56 +00:00
Matt Jankowski 9d413cbaf8
Fix Rails/WhereExists cop in app/models (#28863) 2024-01-24 09:57:49 +00:00
Matt Jankowski 599bc69503
Simplify AccountSummary.filtered query generation (#28868) 2024-01-24 09:57:32 +00:00
Eugen Rochko 5b1eb09d54
Add annual reports for accounts (#28693) 2024-01-24 09:38:10 +00:00
Eugen Rochko 01ce9df880
Fix search form re-rendering spuriously in web UI (#28876) 2024-01-24 07:03:30 +00:00
renovate[bot] 61a0ec69fc
chore(deps): update devdependencies (non-major) (#28840)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Renaud Chaput <renchap@gmail.com>
2024-01-23 11:44:50 +00:00
Matt Jankowski c0e8e457ab
Eager loading fixes for api/ controllers (#28848) 2024-01-23 11:41:54 +00:00
Matt Jankowski ceade78182
Fix Rails/WhereExists cop in app/services (#28853) 2024-01-23 11:41:34 +00:00
github-actions[bot] 78ee1453f9
New Crowdin Translations (automated) (#28857)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-01-23 10:11:37 +00:00
Matt Jankowski d03fe2bdee
N+1 fixes for CLI maintenance command (#28847) 2024-01-23 09:31:59 +00:00
Matt Jankowski b0207d7757
Add coverage for Tag.recently_used scope (#28850) 2024-01-23 09:10:11 +00:00
Matt Jankowski defe5f4076
Fix Rails/WhereExists cop in lib/tasks (#28852) 2024-01-23 09:07:22 +00:00
Matt Jankowski 67f54c4e75
Fix Rails/WhereExists cop in app/validators (#28854) 2024-01-23 09:06:53 +00:00
Eugen Rochko 72bae7e170 [Glitch] Fix duplicate and missing keys in search popout component in web UI
Port 9f8e3cca9a to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-01-22 19:21:02 +01:00
Claire 102eff7c05 Merge commit 'e2d9635074ad33cc8144adc434bcd90faae9c424' into glitch-soc/merge-upstream 2024-01-22 19:19:40 +01:00
renovate[bot] 1d381c1664 [Glitch] Update dependency react-redux to v9.1.0
Port 163db814c2 to glitch-soc

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Renaud Chaput <renchap@gmail.com>
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-01-22 19:15:02 +01:00
Claire 0700eb58bc Merge commit '163db814c2b3cf544b78e427e7f7bbd99b94a025' into glitch-soc/merge-upstream 2024-01-22 19:12:05 +01:00
Claire 3cac826382 Merge commit '1335083bedd1dd563cfa9c54e69abc189ba3ec7b' into glitch-soc/merge-upstream
Conflicts:
- `streaming/index.js`:
  Upstream significantly refactored that file, while one modified
  function had a different signature because of support for local-only
  posts.
  Ported upstream's change and kept the local-only support.
- `yarn.lock`:
  Upstream added new dependencies, one of which was textually close to
  a glitch-soc-only dependency.
  Updated accordingly.
2024-01-22 19:01:35 +01:00
Claire e2d9635074
Add notification email on invalid second authenticator (#28822) 2024-01-22 13:55:43 +00:00
Matt Jankowski 18004bf227
Add Account.matches_uri_prefix scope and use in activitypub/followers_synchronizations controller (#28820) 2024-01-22 13:55:37 +00:00
Matt Jankowski 7ecf7f5403
Move controller->request specs for api/v1/statuses/* (#28818) 2024-01-22 11:58:54 +00:00
Matt Jankowski 5efb00ddb8
Use ruby version 3.2.3 (#28817) 2024-01-22 11:55:51 +00:00
github-actions[bot] 76e383ea1e
New Crowdin Translations (automated) (#28827)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-01-22 11:52:26 +00:00
Andy Piper 9620b21259
docs: update FEDERATION.md to more closely follow FEP conventions. (#28838) 2024-01-22 11:11:47 +00:00
renovate[bot] e078d0048c
Update dependency @types/react to v18.2.48 (#28839)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-22 11:08:22 +00:00
renovate[bot] a83aeccac9
Update dependency dotenv to v16.3.2 (#28824)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-22 11:08:06 +00:00
renovate[bot] 9ff9849381
Update dependency core-js to v3.35.1 (#28831)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-22 11:07:44 +00:00
renovate[bot] 62001b5a31
Update dependency jsdom to v24 (#28836)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-22 11:04:28 +00:00
Emelia Smith 3fbf01918f
Streaming: Move more methods to the utils from the main file (#28825) 2024-01-22 10:02:26 +00:00
Eugen Rochko 9f8e3cca9a
Fix duplicate and missing keys in search popout component in web UI (#28834) 2024-01-21 07:44:46 +00:00
Claire 93957daa50
Fix error when processing remote files with unusually long names (#28823) 2024-01-19 18:52:59 +00:00
Claire cf2a2ed71c
Fix processing of compacted single-item JSON-LD collections (#28816) 2024-01-19 12:43:10 +00:00
Claire 3593ee2e36
Add rate-limit of TOTP authentication attempts at controller level (#28801) 2024-01-19 12:19:49 +00:00
Matt Jankowski 5fc4ae7c5f
Move privacy policy into markdown file (#28699) 2024-01-19 11:22:23 +00:00
Matt Jankowski 6a5d70e146
Update pre_migration_check postgres version requirement (#28800) 2024-01-19 11:20:20 +00:00
Claire 915cd36ac1
Merge pull request #2579 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to f866413e72
2024-01-19 12:09:01 +01:00
github-actions[bot] 9cd17020bc
New Crowdin Translations (automated) (#28798)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-01-19 09:41:57 +00:00
renovate[bot] 163db814c2
Update dependency react-redux to v9.1.0 (#28717)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Renaud Chaput <renchap@gmail.com>
2024-01-19 09:41:03 +00:00
Matt Jankowski 4ec7d7d989
Fix Rails/WhereExists cop in REST::TagSerializer model (#28790) 2024-01-19 09:35:58 +00:00
Matt Jankowski 329911b0a3
Migrate controller->request spec for api/v1/follow* (#28811) 2024-01-19 09:32:41 +00:00
HTeuMeuLeu 86cc88c216
Fix banner image not showing in follow emails (#28814) 2024-01-19 09:23:59 +00:00
renovate[bot] 6a1c998722
Update dependency kt-paperclip to v7.2.2 (#28813)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-19 09:21:07 +00:00
renovate[bot] 6dc97321a3
Update dependency intl-messageformat to v10.5.10 (#28809)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-19 09:20:16 +00:00
Matt Jankowski fd64817fbe
Fix Rails/WhereExists cop in app/lib/status_cache_hydrator (#28808) 2024-01-19 09:19:48 +00:00
Jonathan de Jong de09176ab9
Retry 401 errors on replies fetching (#28788)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2024-01-19 09:18:21 +00:00
Matt Jankowski 1480573c83
Add Account.auditable scope, fix N+1 in admin/action_logs#index (#28812) 2024-01-19 01:39:30 +00:00
Claire 528a8fa495 Merge commit 'f866413e724c2e7f8329fbc6e96f56f0b186c62a' into glitch-soc/merge-upstream 2024-01-18 22:16:16 +01:00
Claire 07b6777c99
Fix styling issue in account fields (#2578) 2024-01-18 20:27:47 +01:00
Claire d80d8f6bb9
Merge pull request #2577 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 127503eb2c
2024-01-18 20:27:31 +01:00
renovate[bot] 5ae3bae586
Update dependency sass to v1.70.0 (#28799)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-18 18:43:03 +00:00
renovate[bot] 244182ad63
Update dependency rdf-normalize to v0.7.0 (#26769)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-18 18:42:07 +00:00
Emelia Smith 1335083bed
Streaming: replace npmlog with pino & pino-http (#27828) 2024-01-18 18:40:25 +00:00
Matt Jankowski f866413e72
Extract shared tagged statuses method in FeaturedTag (#28805) 2024-01-18 16:14:15 +00:00
Matt Jankowski f0b93ab02f
Use AR database_version in PG version checks in migrations (#28804) 2024-01-18 16:11:50 +00:00
Matt Jankowski d0b3bc23d7
Remove unused matches_domain scopes on Account, DomainAllow, DomainBlock (#28803) 2024-01-18 16:11:04 +00:00
Matt Jankowski 0b853678a4
Add coverage for api/v1/peers/search endpoint and extract controller query to Instance scope (#28796) 2024-01-18 15:57:10 +00:00
Matt Jankowski 2115bc52e4
Order by sql in CLI::Maintenance task (#28289) 2024-01-18 14:53:29 +00:00
Matt Jankowski 9fb9ef418a
Fix Rails/WhereExists cop in User model (#28792) 2024-01-18 13:55:44 +00:00
Matt Jankowski 81e4e65610
Update links to upstream migration helpers, remove unused methods (#28781) 2024-01-18 12:29:54 +00:00
Matt Jankowski aaa6f2e930
Group common class_name options in associations (#28779) 2024-01-18 12:29:41 +00:00
Matt Jankowski da31792ac7
Fix Rails/WhereExists cop in FeaturedTag model (#28791) 2024-01-18 12:22:12 +00:00
Matt Jankowski 3d82040b26
Reduced repeated setup in UnallowDomainService spec (#28785) 2024-01-18 10:11:10 +00:00
Matt Jankowski 6c5a2d51bc
Reduced repeated setup in PurgeDomainService spec (#28786) 2024-01-18 10:07:49 +00:00
Matt Jankowski 07e10e3747
Combine assertions about same setup in Account#suspend! spec (#28787) 2024-01-18 09:36:59 +00:00
Matt Jankowski 89c9a4502d
Fix Rails/WhereExists cop in account/interactions concern (#28789) 2024-01-18 09:36:16 +00:00
renovate[bot] 4c23297c04
Update dependency autoprefixer to v10.4.17 (#28794)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-18 09:33:21 +00:00
renovate[bot] 83a90f20d7
Update dependency async-mutex to v0.4.1 (#28797)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-18 09:31:59 +00:00
Santiago Kozak 036e25f19d [Glitch] Improve display of lock icon in account headers
Port 30b193b856 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-01-17 18:37:04 +01:00
Claire 0207c4b055 [Glitch] Change media “ALT” label to a specific class
Port e817fe4c35 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-01-17 18:36:09 +01:00
Claire e8294925e6 [Glitch] Fix various icon alignment issues
Port baab58c80b to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-01-17 18:34:57 +01:00
Claire c59fb65ddc Merge commit '127503eb2cdd67126974bee304dde0f183300b84' into glitch-soc/merge-upstream
Conflicts:
- `app/helpers/accounts_helper.rb`:
  Conflict due to glitch-soc's option to hide followers count.
  Ported upstream changes.

Additional changes:
- `app/views/application/mailer/_account.html.haml`:
  Ported glitch-soc's option to hide followers count.
- `app/views/settings/flavours/show.html.haml`:
  Ported the `frontend_asset_url` helper change to glitch-soc.
2024-01-17 18:32:15 +01:00
renovate[bot] d56e9fb873 [Glitch] Update devDependencies (non-major)
Port 4e277f83dc to glitch-soc

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Renaud Chaput <renchap@gmail.com>
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-01-17 18:12:00 +01:00
Claire 8485bedddc Merge commit '4e277f83dc740b3a842c7fd8ed167c3c76fcabf8' into glitch-soc/merge-upstream 2024-01-17 18:09:15 +01:00
Matt Jankowski 127503eb2c
Fix Rails/RakeEnvironment cop (#28782) 2024-01-17 16:33:17 +00:00
Santiago Kozak 30b193b856
Improve display of lock icon in account headers (#28780) 2024-01-17 16:32:30 +00:00
Matt Jankowski 09f76c5c8d
Regenerate rubocop todo, removes last Layout/LineLength violation (#28778) 2024-01-17 15:42:13 +00:00
Claire e817fe4c35
Change media “ALT” label to a specific class (#28777) 2024-01-17 15:32:56 +00:00
HTeuMeuLeu 1a3859d8e2
Update follow and follow_request emails (#28755)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2024-01-17 14:37:04 +00:00
Matt Jankowski 6fab50ba9e
Use bundler version 2.5.4 (#28765) 2024-01-17 14:35:55 +00:00
github-actions[bot] 1ab42ad12b
New Crowdin Translations (automated) (#28749)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-01-17 14:23:14 +00:00
Matt Jankowski 9a475ea8b3
Finish up the CLI spec area pattern adoption for CLI::Accounts#refresh specs (#28764) 2024-01-17 13:38:37 +00:00
Renaud Chaput cb5ac15923
Use a helper to avoid using media/ asset prefixes (#28756) 2024-01-17 12:19:51 +00:00
Claire baab58c80b
Fix various icon alignment issues (#28775) 2024-01-17 10:42:47 +00:00
Matt Jankowski c523a9601b
Rename local webpack* var in development env CSP config (#28766) 2024-01-17 09:22:16 +00:00
Matt Jankowski 1b0cb3b54d
Announcement reactions query spec improvement and refactor (#28768) 2024-01-17 09:18:13 +00:00
renovate[bot] afb5e6cf46
Update dependency rails to v7.1.3 (#28772)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-17 09:11:22 +00:00
renovate[bot] 259874f2ac
Update dependency @rails/ujs to v7.1.3 (#28771)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-17 09:11:18 +00:00
Matt Jankowski 0ce081fe49
Remove monkey patch in favor of supported Devise config value (#28760) 2024-01-17 09:08:17 +00:00
renovate[bot] 8cc322a0e1
Update dependency concurrent-ruby to v1.2.3 (#28754)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-17 09:06:38 +00:00
renovate[bot] bd538598c2
Update formatjs monorepo (#28751)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-16 18:34:53 +00:00
renovate[bot] 4e277f83dc
Update devDependencies (non-major) (#28728)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Renaud Chaput <renchap@gmail.com>
2024-01-16 18:34:22 +00:00
renovate[bot] e85e2929aa
Update eslint (non-major) (#28729)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-16 17:53:32 +00:00
Jeong Arm 411efdc2d3
Fix getting started misc column on dev env (#2575)
* Fix getting started misc column on dev

---------

Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2024-01-16 17:40:03 +01:00
Claire 1fa9da1f39
Merge pull request #2573 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 01b6c83c36
2024-01-16 17:18:26 +01:00
Renaud Chaput 5b67389bba [Glitch] Add a new @/ alias for the root frontend directory and use it where possible
Port 01b6c83c36 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-01-16 12:21:13 +01:00
Claire e4d07c7bcc Merge commit '01b6c83c369061c2175d50dfb3ae1db502862664' into glitch-soc/merge-upstream 2024-01-16 12:04:11 +01:00
Renaud Chaput 01b6c83c36
Add a new @/ alias for the root frontend directory and use it where possible (#28753) 2024-01-16 10:27:26 +00:00
Jeong Arm f0abba67db
Ignore RecordNotUnique errors in LinkCrawlWorker (#28748) 2024-01-16 08:35:54 +00:00
renovate[bot] f09035cc3f
Update dependency stackprof to v0.2.26 (#28743)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-16 08:32:40 +00:00
Claire dee561604b Merge commit 'b4c332104a8b3748f619de250f77c0acc8e80628' into glitch-soc/merge-upstream 2024-01-15 22:37:21 +01:00
Matt Jankowski b4c332104a
Use top-level warn in JS errors check (#28745) 2024-01-15 21:26:11 +00:00
Claire 01df34b9db Remove bypass and use use glitch-soc's theming system for inert.css 2024-01-15 22:16:26 +01:00
Claire 34c9f77b3e Merge commit '7f471e70c0e1cc106747634d20f173a68a9272d7' into glitch-soc/merge-upstream
Conflicts:
- `app/views/layouts/mailer.html.haml`:
  Conflict caused by glitch-soc's theming system.
  Used glitch-soc's path for the mailer pack.
2024-01-15 21:30:00 +01:00
Claire 6e4d5b4736 Fix some icon-related styling issues 2024-01-15 21:05:54 +01:00
Claire 4fcb372776 Fix Ruby linting issue 2024-01-15 20:57:55 +01:00
Claire 278597c161 Merge commit '98b5f85f10a3af50a54fcd79e09fc9fd88f774fa' into glitch-soc/merge-upstream 2024-01-15 20:53:16 +01:00
Claire a1920425ca [Glitch] Switch from 48px weight 600 material symbol icons to 24px weight 400 icons
Port 6bbcd9348e to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-01-15 20:53:08 +01:00
Claire 2f521bc84a Merge commit 'a2f02a07758c32f0dcc6388b4f30ca5a84e762f3' into glitch-soc/merge-upstream 2024-01-15 20:27:41 +01:00
Renaud Chaput 8cad0a4d6b [Glitch] Change icon SVG imports to use a default import
Port 608f66f978 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-01-15 20:20:38 +01:00
Claire 464051c2d2 Merge commit '1070804a1a6121170f7bba923789d73b978e6fe7' into glitch-soc/merge-upstream 2024-01-15 20:06:31 +01:00
Claire 60298af3c4 Merge commit 'c6684aa1e392f2dd86af4362b4259809549abaad' into glitch-soc/merge-upstream
Conflicts:
- `app/views/layouts/application.html.haml`:
  Upstream changed how the `inert.css` file is included.
  The conflict is caused by glitch-soc's theming system.
  Ported the upstream change.

Additional changes:
- `config/webpack/shared.js`: bypass glitch-soc's theming
  system for `inert` pack.
2024-01-15 20:01:36 +01:00
Claire 1323dfac80 Merge commit 'a90696011e563e62100cba56e2d52f6babbaff00' into glitch-soc/merge-upstream 2024-01-15 19:19:04 +01:00
HTeuMeuLeu 7f471e70c0
Update new email templates (#28416)
Co-authored-by: Matt Jankowski <matt@jankowski.online>
2024-01-15 18:18:59 +00:00
Claire 98b5f85f10
Rename and refactor User#confirm! to User#mark_email_as_confirmed! (#28735) 2024-01-15 18:04:58 +00:00
Claire e621c1c44c
Fix registrations not checking MX records for email domain blocks requiring approval (#28608) 2024-01-15 17:10:57 +00:00
Matt Jankowski a2f02a0775
Disable Rails/SkipsModelValidations cop (#28712) 2024-01-15 13:46:47 +00:00
Claire 82d28ac956
Merge pull request #2567 from ClearlyClaire/glitch-soc/ports/convert-utils-hashtags-typescript
Convert utils and hashtags to Typescript
2024-01-15 12:41:22 +01:00
renovate[bot] b5afbe0a61
Update dependency bootsnap to v1.17.1 (#28713)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-15 11:17:25 +00:00
Claire 50188ad211
[Glitch] Use helpers to check environment in frontend (#2571)
Port 277e6968f5 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
Co-authored-by: Renaud Chaput <renchap@gmail.com>
2024-01-15 12:16:05 +01:00
renovate[bot] 367be82a29
Update libretranslate/libretranslate Docker tag to v1.5.4 (#28727)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-15 11:09:28 +00:00
Claire 8cb4825c8b
Fix sign-up restrictions based on email addresses not being enforced (#28732) 2024-01-15 11:06:48 +00:00
renovate[bot] 8013d6c56d
Update dependency faker to v3.2.3 (#28720)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-15 11:06:28 +00:00
github-actions[bot] 1012ffac9e
New Crowdin Translations (automated) (#28721)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-01-15 11:06:25 +00:00
Claire e81c5c0a51
Ignore the devise-two-factor advisory as we have rate limits in place (#28733) 2024-01-15 10:45:48 +00:00
Emelia Smith 58830be943
Streaming: Rework websocket server initialisation & authentication code (#28631) 2024-01-15 10:36:30 +00:00
Matt Jankowski e72676e83a
Improve api/v1/markers#create performance against simultaneous requests (#28718) 2024-01-15 09:47:25 +00:00
Josh Goldberg ✨ f8941c41a5 [Glitch] Converted hashtag.jsx to TypeScript
Port 3a7f10c3f1 to glitch-soc

Co-authored-by: Claire <claire.github-309c@sitedethib.com>
Co-authored-by: Renaud Chaput <renchap@gmail.com>
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-01-14 19:22:39 +01:00
Josh Goldberg ✨ 695dcc6ca8 [Glitch] Converted app/javascript/flavours/glitch/utils/ folder to TypeScript
Port 1142f4c79e to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
2024-01-14 19:22:39 +01:00
Claire 52c023a305 Convert Permalink to Typescript 2024-01-14 19:22:39 +01:00
Claire 16499bc097 Rewrite Permalink as functional component 2024-01-14 19:22:39 +01:00
Matt Jankowski cc3ff66246
Use rubygems released version of omniauth-cas gem (#28719) 2024-01-12 22:39:23 +00:00
Claire 6bbcd9348e
Switch from 48px weight 600 material symbol icons to 24px weight 400 icons (#28064) 2024-01-12 20:16:48 +00:00
Claire 1070804a1a
Fix RedownloadMediaWorker not being called on transient S3 failure (#28714) 2024-01-12 17:00:17 +00:00
MitarashiDango 2c05b8a60d
Fix Undo Announce activity is not sent, when not followed by the reblogged post author (#18482)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2024-01-12 15:58:28 +00:00
Matt Jankowski 28fdf93362
Disable Rails/LexicallyScopedActionFilter for inherited auth controllers (#28711) 2024-01-12 13:10:14 +00:00
Matt Jankowski a90c134850
Move followable by logic to suggestion class (#28710) 2024-01-12 13:09:33 +00:00
Renaud Chaput 608f66f978
Change icon SVG imports to use a default import (#28709) 2024-01-12 10:31:24 +00:00
Renaud Chaput c6684aa1e3
Use the assets pipeline to load inert.css (#28701) 2024-01-12 09:32:45 +00:00
Matt Jankowski a90696011e
Add coverage/bugfix for invalid appeal submission (#28703) 2024-01-12 09:21:00 +00:00
Matt Jankowski 7801db7ba4
Spec coverage for custom css endpoint (#28706) 2024-01-12 09:19:25 +00:00
github-actions[bot] b86083f0dc
New Crowdin Translations (automated) (#28708)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-01-12 09:17:10 +00:00
Matt Jankowski df9e220364
Add JS console errors check (#28682) 2024-01-12 09:12:31 +00:00
900 changed files with 8277 additions and 6084 deletions

6
.bundler-audit.yml Normal file
View file

@ -0,0 +1,6 @@
---
ignore:
# devise-two-factor advisory about brute-forcing TOTP
# We have rate-limits on authentication endpoints in place (including second
# factor verification) since Mastodon v3.2.0
- CVE-2024-0227

View file

@ -5,7 +5,7 @@
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
"features": {
"ghcr.io/devcontainers/features/sshd:1": {}
"ghcr.io/devcontainers/features/sshd:1": {},
},
"runServices": ["app", "db", "redis"],
@ -15,16 +15,16 @@
"portsAttributes": {
"3000": {
"label": "web",
"onAutoForward": "notify"
"onAutoForward": "notify",
},
"4000": {
"label": "stream",
"onAutoForward": "silent"
}
"onAutoForward": "silent",
},
},
"otherPortsAttributes": {
"onAutoForward": "silent"
"onAutoForward": "silent",
},
"remoteEnv": {
@ -33,7 +33,7 @@
"STREAMING_API_BASE_URL": "https://${localEnv:CODESPACE_NAME}-4000.app.github.dev",
"DISABLE_FORGERY_REQUEST_PROTECTION": "true",
"ES_ENABLED": "",
"LIBRE_TRANSLATE_ENDPOINT": ""
"LIBRE_TRANSLATE_ENDPOINT": "",
},
"onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}",
@ -43,7 +43,7 @@
"customizations": {
"vscode": {
"settings": {},
"extensions": ["EditorConfig.EditorConfig", "webben.browserslist"]
}
}
"extensions": ["EditorConfig.EditorConfig", "webben.browserslist"],
},
},
}

View file

@ -5,7 +5,7 @@
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
"features": {
"ghcr.io/devcontainers/features/sshd:1": {}
"ghcr.io/devcontainers/features/sshd:1": {},
},
"forwardPorts": [3000, 4000],
@ -14,17 +14,17 @@
"3000": {
"label": "web",
"onAutoForward": "notify",
"requireLocalPort": true
"requireLocalPort": true,
},
"4000": {
"label": "stream",
"onAutoForward": "silent",
"requireLocalPort": true
}
"requireLocalPort": true,
},
},
"otherPortsAttributes": {
"onAutoForward": "silent"
"onAutoForward": "silent",
},
"onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}",
@ -34,7 +34,7 @@
"customizations": {
"vscode": {
"settings": {},
"extensions": ["EditorConfig.EditorConfig", "webben.browserslist"]
}
}
"extensions": ["EditorConfig.EditorConfig", "webben.browserslist"],
},
},
}

View file

@ -70,7 +70,7 @@ services:
hard: -1
libretranslate:
image: libretranslate/libretranslate:v1.5.3
image: libretranslate/libretranslate:v1.5.4
restart: unless-stopped
volumes:
- lt-data:/home/libretranslate/.local

61
.github/workflows/build-security.yml vendored Normal file
View file

@ -0,0 +1,61 @@
name: Build security nightly container image
on:
workflow_dispatch:
permissions:
contents: read
packages: write
jobs:
compute-suffix:
runs-on: ubuntu-latest
steps:
- id: version_vars
env:
TZ: Etc/UTC
run: |
echo mastodon_version_prerelease=nightly.$(date --date='next day' +'%Y-%m-%d')-security>> $GITHUB_OUTPUT
outputs:
prerelease: ${{ steps.version_vars.outputs.mastodon_version_prerelease }}
build-image:
needs: compute-suffix
uses: ./.github/workflows/build-container-image.yml
with:
file_to_build: Dockerfile
platforms: linux/amd64,linux/arm64
use_native_arm64_builder: true
cache: false
push_to_images: |
ghcr.io/${{ github.repository_owner }}/mastodon
version_prerelease: ${{ needs.compute-suffix.outputs.prerelease }}
labels: |
org.opencontainers.image.description=Nightly build image used for testing purposes
flavor: |
latest=true
tags: |
type=raw,value=edge
type=raw,value=nightly
type=schedule,pattern=${{ needs.compute-suffix.outputs.prerelease }}
secrets: inherit
build-image-streaming:
needs: compute-suffix
uses: ./.github/workflows/build-container-image.yml
with:
file_to_build: streaming/Dockerfile
platforms: linux/amd64,linux/arm64
use_native_arm64_builder: false
cache: false
push_to_images: |
ghcr.io/${{ github.repository_owner }}/mastodon
version_prerelease: ${{ needs.compute-suffix.outputs.prerelease }}
labels: |
org.opencontainers.image.description=Nightly build image used for testing purposes
flavor: |
latest=true
tags: |
type=raw,value=edge
type=raw,value=nightly
type=schedule,pattern=${{ needs.compute-suffix.outputs.prerelease }}
secrets: inherit

View file

@ -78,23 +78,8 @@ jobs:
- name: Create database
run: './bin/rails db:create'
- name: Run migrations up to v2.0.0
run: './bin/rails db:migrate VERSION=20171010025614'
- name: Populate database with test data
run: './bin/rails tests:migrations:populate_v2'
- name: Run migrations up to v2.4.0
run: './bin/rails db:migrate VERSION=20180514140000'
- name: Populate database with test data
run: './bin/rails tests:migrations:populate_v2_4'
- name: Run migrations up to v2.4.3
run: './bin/rails db:migrate VERSION=20180707154237'
- name: Populate database with test data
run: './bin/rails tests:migrations:populate_v2_4_3'
- name: Run historical migrations with data population
run: './bin/rails tests:migrations:prepare_database'
- name: Run all remaining migrations
run: './bin/rails db:migrate'

View file

@ -45,6 +45,7 @@ jobs:
--health-retries 5
ports:
- 5432:5432
redis:
image: redis:7-alpine
options: >-
@ -77,28 +78,11 @@ jobs:
- name: Create database
run: './bin/rails db:create'
- name: Run migrations up to v2.0.0
run: './bin/rails db:migrate VERSION=20171010025614'
- name: Populate database with test data
run: './bin/rails tests:migrations:populate_v2'
- name: Run pre-deployment migrations up to v2.4.0
run: './bin/rails db:migrate VERSION=20180514140000'
- name: Run historical migrations with data population
run: './bin/rails tests:migrations:prepare_database'
env:
SKIP_POST_DEPLOYMENT_MIGRATIONS: true
- name: Populate database with test data
run: './bin/rails tests:migrations:populate_v2_4'
- name: Run migrations up to v2.4.3
run: './bin/rails db:migrate VERSION=20180707154237'
env:
SKIP_POST_DEPLOYMENT_MIGRATIONS: true
- name: Populate database with test data
run: './bin/rails tests:migrations:populate_v2_4_3'
- name: Run all remaining pre-deployment migrations
run: './bin/rails db:migrate'
env:

View file

@ -52,7 +52,7 @@ jobs:
run: |
tar --exclude={"*.br","*.gz"} -zcf artifacts.tar.gz public/assets public/packs*
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
if: matrix.mode == 'test'
with:
path: |-
@ -117,7 +117,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
path: './'
name: ${{ github.sha }}
@ -193,7 +193,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
path: './public'
name: ${{ github.sha }}
@ -213,14 +213,14 @@ jobs:
- run: bundle exec rake spec:system
- name: Archive logs
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
if: failure()
with:
name: e2e-logs-${{ matrix.ruby-version }}
path: log/
- name: Archive test screenshots
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
if: failure()
with:
name: e2e-screenshots
@ -297,7 +297,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
path: './public'
name: ${{ github.sha }}
@ -317,14 +317,14 @@ jobs:
- run: bin/rspec --tag search
- name: Archive logs
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
if: failure()
with:
name: test-search-logs-${{ matrix.ruby-version }}
path: log/
- name: Archive test screenshots
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
if: failure()
with:
name: test-search-screenshots

View file

@ -103,9 +103,26 @@ Rails/Exit:
- 'config/boot.rb'
- 'lib/mastodon/cli/*.rb'
Rails/SkipsModelValidations:
# Reason: Conflicts with `Lint/UselessMethodDefinition` for inherited controller actions
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railslexicallyscopedactionfilter
Rails/LexicallyScopedActionFilter:
Exclude:
- 'db/*migrate/**/*'
- 'app/controllers/auth/*'
# Reason: These tasks are doing local work which do not need full env loaded
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsrakeenvironment
Rails/RakeEnvironment:
Exclude:
- 'lib/tasks/auto_annotate_models.rake'
- 'lib/tasks/emojis.rake'
- 'lib/tasks/mastodon.rake'
- 'lib/tasks/repo.rake'
- 'lib/tasks/statistics.rake'
# Reason: There are appropriate times to use these features
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsskipsmodelvalidations
Rails/SkipsModelValidations:
Enabled: false
# Reason: We want to preserve the ability to migrate from arbitrary old versions,
# and cannot guarantee that every installation has run every migration as they upgrade.

View file

@ -1,6 +1,6 @@
# This configuration was generated by
# `rubocop --auto-gen-config --auto-gen-only-exclude --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp`
# using RuboCop version 1.59.0.
# using RuboCop version 1.60.2.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
@ -13,13 +13,6 @@ Bundler/OrderedGems:
Exclude:
- 'Gemfile'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
# URISchemes: http, https
Layout/LineLength:
Exclude:
- 'app/models/account.rb'
Lint/NonLocalExitFromIterator:
Exclude:
- 'app/helpers/jsonld_helper.rb'
@ -64,64 +57,10 @@ Rails/HasAndBelongsToMany:
- 'app/models/status.rb'
- 'app/models/tag.rb'
# Configuration parameters: Include.
# Include: app/controllers/**/*.rb, app/mailers/**/*.rb
Rails/LexicallyScopedActionFilter:
Exclude:
- 'app/controllers/auth/passwords_controller.rb'
- 'app/controllers/auth/registrations_controller.rb'
Rails/OutputSafety:
Exclude:
- 'config/initializers/simple_form.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: Include.
# Include: **/Rakefile, **/*.rake
Rails/RakeEnvironment:
Exclude:
- 'lib/tasks/auto_annotate_models.rake'
- 'lib/tasks/db.rake'
- 'lib/tasks/emojis.rake'
- 'lib/tasks/mastodon.rake'
- 'lib/tasks/repo.rake'
- 'lib/tasks/statistics.rake'
# Configuration parameters: ForbiddenMethods, AllowedMethods.
# ForbiddenMethods: decrement!, decrement_counter, increment!, increment_counter, insert, insert!, insert_all, insert_all!, toggle!, touch, touch_all, update_all, update_attribute, update_column, update_columns, update_counters, upsert, upsert_all
Rails/SkipsModelValidations:
Exclude:
- 'app/controllers/admin/invites_controller.rb'
- 'app/controllers/concerns/session_tracking_concern.rb'
- 'app/models/concerns/account/merging.rb'
- 'app/models/concerns/expireable.rb'
- 'app/models/status.rb'
- 'app/models/trends/links.rb'
- 'app/models/trends/preview_card_batch.rb'
- 'app/models/trends/preview_card_provider_batch.rb'
- 'app/models/trends/status_batch.rb'
- 'app/models/trends/statuses.rb'
- 'app/models/trends/tag_batch.rb'
- 'app/models/trends/tags.rb'
- 'app/models/user.rb'
- 'app/services/activitypub/process_status_update_service.rb'
- 'app/services/approve_appeal_service.rb'
- 'app/services/block_domain_service.rb'
- 'app/services/delete_account_service.rb'
- 'app/services/process_mentions_service.rb'
- 'app/services/unallow_domain_service.rb'
- 'app/services/unblock_domain_service.rb'
- 'app/services/update_status_service.rb'
- 'app/workers/activitypub/post_upgrade_worker.rb'
- 'app/workers/move_worker.rb'
- 'app/workers/scheduler/ip_cleanup_scheduler.rb'
- 'app/workers/scheduler/scheduled_statuses_scheduler.rb'
- 'lib/mastodon/cli/accounts.rb'
- 'lib/mastodon/cli/maintenance.rb'
- 'spec/lib/activitypub/activity/follow_spec.rb'
- 'spec/services/follow_service_spec.rb'
- 'spec/services/update_account_service_spec.rb'
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/UniqueValidationWithoutIndex:
@ -131,38 +70,6 @@ Rails/UniqueValidationWithoutIndex:
- 'app/models/identity.rb'
- 'app/models/webauthn_credential.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: exists, where
Rails/WhereExists:
Exclude:
- 'app/controllers/activitypub/inboxes_controller.rb'
- 'app/controllers/admin/email_domain_blocks_controller.rb'
- 'app/lib/activitypub/activity/create.rb'
- 'app/lib/delivery_failure_tracker.rb'
- 'app/lib/feed_manager.rb'
- 'app/lib/status_cache_hydrator.rb'
- 'app/lib/suspicious_sign_in_detector.rb'
- 'app/models/concerns/account/interactions.rb'
- 'app/models/featured_tag.rb'
- 'app/models/poll.rb'
- 'app/models/session_activation.rb'
- 'app/models/status.rb'
- 'app/models/user.rb'
- 'app/policies/status_policy.rb'
- 'app/serializers/rest/announcement_serializer.rb'
- 'app/serializers/rest/tag_serializer.rb'
- 'app/services/activitypub/fetch_remote_status_service.rb'
- 'app/services/vote_service.rb'
- 'app/validators/reaction_validator.rb'
- 'app/validators/vote_validator.rb'
- 'app/workers/move_worker.rb'
- 'lib/tasks/tests.rake'
- 'spec/models/account_spec.rb'
- 'spec/services/activitypub/process_collection_service_spec.rb'
- 'spec/services/purge_domain_service_spec.rb'
- 'spec/services/unallow_domain_service_spec.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: AllowedMethods, AllowedPatterns.
# AllowedMethods: ==, equal?, eql?
@ -201,7 +108,6 @@ Style/FetchEnvVar:
# AllowedMethods: redirect
Style/FormatStringToken:
Exclude:
- 'app/models/privacy_policy.rb'
- 'config/initializers/devise.rb'
- 'lib/paperclip/color_extractor.rb'
@ -215,10 +121,6 @@ Style/GlobalStdStream:
# Configuration parameters: MinBodyLength, AllowConsecutiveConditionals.
Style/GuardClause:
Exclude:
- 'app/controllers/admin/confirmations_controller.rb'
- 'app/controllers/auth/confirmations_controller.rb'
- 'app/controllers/auth/passwords_controller.rb'
- 'app/controllers/settings/two_factor_authentication/webauthn_credentials_controller.rb'
- 'app/lib/activitypub/activity/block.rb'
- 'app/lib/request.rb'
- 'app/lib/request_pool.rb'
@ -373,13 +275,6 @@ Style/StringLiterals:
- 'config/initializers/webauthn.rb'
- 'config/routes.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle, AllowSafeAssignment.
# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex
Style/TernaryParentheses:
Exclude:
- 'config/environments/development.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyleForMultiline.
# SupportedStylesForMultiline: comma, consistent_comma, no_comma

View file

@ -1 +1 @@
3.2.2
3.2.3

View file

@ -7,15 +7,15 @@
ARG TARGETPLATFORM=${TARGETPLATFORM}
ARG BUILDPLATFORM=${BUILDPLATFORM}
# Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.2.2"]
ARG RUBY_VERSION="3.2.2"
# Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.2.3"]
ARG RUBY_VERSION="3.2.3"
# # Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"]
ARG NODE_MAJOR_VERSION="20"
# Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"]
ARG DEBIAN_VERSION="bookworm"
# Node image to use for base image based on combined variables (ex: 20-bookworm-slim)
FROM docker.io/node:${NODE_MAJOR_VERSION}-${DEBIAN_VERSION}-slim as node
# Ruby image to use for base image based on combined variables (ex: 3.2.2-slim-bookworm)
# Ruby image to use for base image based on combined variables (ex: 3.2.3-slim-bookworm)
FROM docker.io/ruby:${RUBY_VERSION}-slim-${DEBIAN_VERSION} as ruby
# Resulting version string is vX.X.X-MASTODON_VERSION_PRERELEASE+MASTODON_VERSION_METADATA

View file

@ -1,19 +1,35 @@
## ActivityPub federation in Mastodon
# Federation
## Supported federation protocols and standards
- [ActivityPub](https://www.w3.org/TR/activitypub/) (Server-to-Server)
- [WebFinger](https://webfinger.net/)
- [Http Signatures](https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures)
- [NodeInfo](https://nodeinfo.diaspora.software/)
## Supported FEPs
- [FEP-67ff: FEDERATION.md](https://codeberg.org/fediverse/fep/src/branch/main/fep/67ff/fep-67ff.md)
- [FEP-f1d5: NodeInfo in Fediverse Software](https://codeberg.org/fediverse/fep/src/branch/main/fep/f1d5/fep-f1d5.md)
- [FEP-8fcf: Followers collection synchronization across servers](https://codeberg.org/fediverse/fep/src/branch/main/fep/8fcf/fep-8fcf.md)
- [FEP-5feb: Search indexing consent for actors](https://codeberg.org/fediverse/fep/src/branch/main/fep/5feb/fep-5feb.md)
## ActivityPub in Mastodon
Mastodon largely follows the ActivityPub server-to-server specification but it makes uses of some non-standard extensions, some of which are required for interacting with Mastodon at all.
Supported vocabulary: https://docs.joinmastodon.org/spec/activitypub/
- [Supported ActivityPub vocabulary](https://docs.joinmastodon.org/spec/activitypub/)
### Required extensions
#### Webfinger
#### WebFinger
In Mastodon, users are identified by a `username` and `domain` pair (e.g., `Gargron@mastodon.social`).
This is used both for discovery and for unambiguously mentioning users across the fediverse. Furthermore, this is part of Mastodon's database design from its very beginnings.
As a result, Mastodon requires that each ActivityPub actor uniquely maps back to an `acct:` URI that can be resolved via WebFinger.
More information and examples are available at: https://docs.joinmastodon.org/spec/webfinger/
- [WebFinger information and examples](https://docs.joinmastodon.org/spec/webfinger/)
#### HTTP Signatures
@ -21,11 +37,13 @@ In order to authenticate activities, Mastodon relies on HTTP Signatures, signing
Mastodon requires all `POST` requests to be signed, and MAY require `GET` requests to be signed, depending on the configuration of the Mastodon server.
More information on HTTP Signatures, as well as examples, can be found here: https://docs.joinmastodon.org/spec/security/#http
- [HTTP Signatures information and examples](https://docs.joinmastodon.org/spec/security/#http)
### Optional extensions
- Linked-Data Signatures: https://docs.joinmastodon.org/spec/security/#ld
- Bearcaps: https://docs.joinmastodon.org/spec/bearcaps/
- Followers collection synchronization: https://codeberg.org/fediverse/fep/src/branch/main/fep/8fcf/fep-8fcf.md
- Search indexing consent for actors: https://codeberg.org/fediverse/fep/src/branch/main/fep/5feb/fep-5feb.md
- [Linked-Data Signatures](https://docs.joinmastodon.org/spec/security/#ld)
- [Bearcaps](https://docs.joinmastodon.org/spec/bearcaps/)
### Additional documentation
- [Mastodon documentation](https://docs.joinmastodon.org/)

View file

@ -39,8 +39,7 @@ end
gem 'net-ldap', '~> 0.18'
# TODO: Point back at released omniauth-cas gem when new version is released
gem 'omniauth-cas', github: 'dlindahl/omniauth-cas', ref: '9d9d3a91b316c55d49ab6e621977f2067010c5bf'
gem 'omniauth-cas', '~> 3.0.0.beta.1'
gem 'omniauth-saml', '~> 2.0'
gem 'omniauth_openid_connect', '~> 0.6.1'
gem 'omniauth', '~> 2.0'
@ -124,7 +123,7 @@ group :test do
gem 'database_cleaner-active_record'
# Used to mock environment variables
gem 'climate_control', '~> 0.2'
gem 'climate_control'
# Generating fake data for specs
gem 'faker', '~> 3.2'

View file

@ -7,16 +7,6 @@ GIT
hkdf (~> 0.2)
jwt (~> 2.0)
GIT
remote: https://github.com/dlindahl/omniauth-cas.git
revision: 9d9d3a91b316c55d49ab6e621977f2067010c5bf
ref: 9d9d3a91b316c55d49ab6e621977f2067010c5bf
specs:
omniauth-cas (3.0.0)
addressable (~> 2.8)
nokogiri (~> 1.12)
omniauth (~> 2.1)
GIT
remote: https://github.com/jhawthorn/nsa.git
revision: e020fcc3a54d993ab45b7194d89ab720296c111b
@ -31,35 +21,35 @@ GIT
GEM
remote: https://rubygems.org/
specs:
actioncable (7.1.2)
actionpack (= 7.1.2)
activesupport (= 7.1.2)
actioncable (7.1.3)
actionpack (= 7.1.3)
activesupport (= 7.1.3)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
zeitwerk (~> 2.6)
actionmailbox (7.1.2)
actionpack (= 7.1.2)
activejob (= 7.1.2)
activerecord (= 7.1.2)
activestorage (= 7.1.2)
activesupport (= 7.1.2)
actionmailbox (7.1.3)
actionpack (= 7.1.3)
activejob (= 7.1.3)
activerecord (= 7.1.3)
activestorage (= 7.1.3)
activesupport (= 7.1.3)
mail (>= 2.7.1)
net-imap
net-pop
net-smtp
actionmailer (7.1.2)
actionpack (= 7.1.2)
actionview (= 7.1.2)
activejob (= 7.1.2)
activesupport (= 7.1.2)
actionmailer (7.1.3)
actionpack (= 7.1.3)
actionview (= 7.1.3)
activejob (= 7.1.3)
activesupport (= 7.1.3)
mail (~> 2.5, >= 2.5.4)
net-imap
net-pop
net-smtp
rails-dom-testing (~> 2.2)
actionpack (7.1.2)
actionview (= 7.1.2)
activesupport (= 7.1.2)
actionpack (7.1.3)
actionview (= 7.1.3)
activesupport (= 7.1.3)
nokogiri (>= 1.8.5)
racc
rack (>= 2.2.4)
@ -67,15 +57,15 @@ GEM
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
actiontext (7.1.2)
actionpack (= 7.1.2)
activerecord (= 7.1.2)
activestorage (= 7.1.2)
activesupport (= 7.1.2)
actiontext (7.1.3)
actionpack (= 7.1.3)
activerecord (= 7.1.3)
activestorage (= 7.1.3)
activesupport (= 7.1.3)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (7.1.2)
activesupport (= 7.1.2)
actionview (7.1.3)
activesupport (= 7.1.3)
builder (~> 3.1)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
@ -85,22 +75,22 @@ GEM
activemodel (>= 4.1)
case_transform (>= 0.2)
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
activejob (7.1.2)
activesupport (= 7.1.2)
activejob (7.1.3)
activesupport (= 7.1.3)
globalid (>= 0.3.6)
activemodel (7.1.2)
activesupport (= 7.1.2)
activerecord (7.1.2)
activemodel (= 7.1.2)
activesupport (= 7.1.2)
activemodel (7.1.3)
activesupport (= 7.1.3)
activerecord (7.1.3)
activemodel (= 7.1.3)
activesupport (= 7.1.3)
timeout (>= 0.4.0)
activestorage (7.1.2)
actionpack (= 7.1.2)
activejob (= 7.1.2)
activerecord (= 7.1.2)
activesupport (= 7.1.2)
activestorage (7.1.3)
actionpack (= 7.1.3)
activejob (= 7.1.3)
activerecord (= 7.1.3)
activesupport (= 7.1.3)
marcel (~> 1.0)
activesupport (7.1.2)
activesupport (7.1.3)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
@ -160,12 +150,12 @@ GEM
erubi (~> 1.4)
parser (>= 2.4)
smart_properties
bigdecimal (3.1.5)
bigdecimal (3.1.6)
bindata (2.4.15)
binding_of_caller (1.0.0)
debug_inspector (>= 0.0.1)
blurhash (0.1.7)
bootsnap (1.17.0)
bootsnap (1.17.1)
msgpack (~> 1.2)
brakeman (6.1.1)
racc
@ -190,15 +180,15 @@ GEM
activesupport
cbor (0.5.9.6)
charlock_holmes (0.7.7)
chewy (7.4.0)
chewy (7.5.0)
activesupport (>= 5.2)
elasticsearch (>= 7.12.0, < 7.14.0)
elasticsearch-dsl
chunky_png (1.4.0)
climate_control (0.2.0)
climate_control (1.2.0)
cocoon (1.2.15)
color_diff (0.1)
concurrent-ruby (1.2.2)
concurrent-ruby (1.2.3)
connection_pool (2.4.1)
cose (1.3.0)
cbor (~> 0.5.9)
@ -267,7 +257,7 @@ GEM
tzinfo
excon (0.109.0)
fabrication (2.31.0)
faker (3.2.2)
faker (3.2.3)
i18n (>= 1.8.11, < 2)
faraday (1.10.3)
faraday-em_http (~> 1.0)
@ -329,7 +319,7 @@ GEM
activesupport (>= 5.1)
haml (>= 4.0.6)
railties (>= 5.1)
haml_lint (0.53.0)
haml_lint (0.55.0)
haml (>= 5.0)
parallel (~> 1.10)
rainbow
@ -370,7 +360,7 @@ GEM
rainbow (>= 2.2.2, < 4.0)
terminal-table (>= 1.5.1)
idn-ruby (0.1.5)
io-console (0.7.1)
io-console (0.7.2)
irb (1.11.1)
rdoc
reline (>= 0.4.2)
@ -408,12 +398,12 @@ GEM
activerecord
kaminari-core (= 1.2.2)
kaminari-core (1.2.2)
kt-paperclip (7.2.1)
kt-paperclip (7.2.2)
activemodel (>= 4.2.0)
activesupport (>= 4.2.0)
marcel (~> 1.0.1)
mime-types
terrapin (~> 0.6.0)
terrapin (>= 0.6.0, < 2.0)
language_server-protocol (3.17.0.3)
launchy (2.5.2)
addressable (~> 2.8)
@ -455,7 +445,7 @@ GEM
mime-types-data (3.2023.1205)
mini_mime (1.1.5)
mini_portile2 (2.8.5)
minitest (5.20.0)
minitest (5.21.2)
msgpack (1.7.2)
multi_json (1.15.0)
multipart-post (2.3.0)
@ -464,7 +454,7 @@ GEM
uri
net-http-persistent (4.0.2)
connection_pool (~> 2.2)
net-imap (0.4.4)
net-imap (0.4.9.1)
date
net-protocol
net-ldap (0.19.0)
@ -472,7 +462,7 @@ GEM
net-protocol
net-protocol (0.2.2)
timeout
net-smtp (0.4.0)
net-smtp (0.4.0.1)
net-protocol
nio4r (2.5.9)
nokogiri (1.16.0)
@ -484,6 +474,10 @@ GEM
hashie (>= 3.4.6)
rack (>= 2.2.3)
rack-protection
omniauth-cas (3.0.0.beta.1)
addressable (~> 2.8)
nokogiri (~> 1.12)
omniauth (~> 2.1)
omniauth-rails_csrf_protection (1.0.1)
actionpack (>= 4.2)
omniauth (~> 2.0)
@ -510,7 +504,7 @@ GEM
orm_adapter (0.5.0)
ox (2.14.17)
parallel (1.24.0)
parser (3.2.2.4)
parser (3.3.0.5)
ast (~> 2.4.1)
racc
parslet (2.0.0)
@ -558,27 +552,27 @@ GEM
rack
rack-proxy (0.7.6)
rack
rack-session (1.0.1)
rack-session (1.0.2)
rack (< 3)
rack-test (2.1.0)
rack (>= 1.3)
rackup (1.0.0)
rack (< 3)
webrick
rails (7.1.2)
actioncable (= 7.1.2)
actionmailbox (= 7.1.2)
actionmailer (= 7.1.2)
actionpack (= 7.1.2)
actiontext (= 7.1.2)
actionview (= 7.1.2)
activejob (= 7.1.2)
activemodel (= 7.1.2)
activerecord (= 7.1.2)
activestorage (= 7.1.2)
activesupport (= 7.1.2)
rails (7.1.3)
actioncable (= 7.1.3)
actionmailbox (= 7.1.3)
actionmailer (= 7.1.3)
actionpack (= 7.1.3)
actiontext (= 7.1.3)
actionview (= 7.1.3)
activejob (= 7.1.3)
activemodel (= 7.1.3)
activerecord (= 7.1.3)
activestorage (= 7.1.3)
activesupport (= 7.1.3)
bundler (>= 1.15.0)
railties (= 7.1.2)
railties (= 7.1.3)
rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1)
actionview (>= 5.0.1.rc1)
@ -593,9 +587,9 @@ GEM
rails-i18n (7.0.8)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8)
railties (7.1.2)
actionpack (= 7.1.2)
activesupport (= 7.1.2)
railties (7.1.3)
actionpack (= 7.1.3)
activesupport (= 7.1.3)
irb
rackup (>= 1.0.0)
rake (>= 12.2)
@ -606,8 +600,8 @@ GEM
rdf (3.3.1)
bcp47_spec (~> 0.2)
link_header (~> 0.0, >= 0.0.8)
rdf-normalize (0.6.1)
rdf (~> 3.2)
rdf-normalize (0.7.0)
rdf (~> 3.3)
rdoc (6.6.2)
psych (>= 4.0.0)
redcarpet (3.6.0)
@ -616,7 +610,7 @@ GEM
redis (>= 4)
redlock (1.3.2)
redis (>= 3.0.0, < 6.0)
regexp_parser (2.8.3)
regexp_parser (2.9.0)
reline (0.4.2)
io-console (~> 0.5)
request_store (1.5.1)
@ -642,7 +636,7 @@ GEM
rspec-mocks (3.12.6)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-rails (6.1.0)
rspec-rails (6.1.1)
actionpack (>= 6.1)
activesupport (>= 6.1)
railties (>= 6.1)
@ -656,11 +650,11 @@ GEM
rspec-mocks (~> 3.0)
sidekiq (>= 5, < 8)
rspec-support (3.12.1)
rubocop (1.59.0)
rubocop (1.60.2)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.2.2.4)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
@ -702,7 +696,8 @@ GEM
scenic (1.7.0)
activerecord (>= 4.0.0)
railties (>= 4.0.0)
selenium-webdriver (4.16.0)
selenium-webdriver (4.17.0)
base64 (~> 0.2)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
@ -736,7 +731,7 @@ GEM
simplecov-lcov (0.8.0)
simplecov_json_formatter (0.1.4)
smart_properties (1.17.0)
stackprof (0.2.25)
stackprof (0.2.26)
statsd-ruby (1.5.0)
stoplight (3.0.2)
redlock (~> 1.0)
@ -751,8 +746,8 @@ GEM
temple (0.10.3)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
terrapin (0.6.0)
climate_control (>= 0.0.3, < 1.0)
terrapin (1.0.1)
climate_control
test-prof (1.3.1)
thor (1.3.0)
tilt (2.3.0)
@ -841,7 +836,7 @@ DEPENDENCIES
capybara (~> 3.39)
charlock_holmes (~> 0.7.7)
chewy (~> 7.3)
climate_control (~> 0.2)
climate_control
cocoon (~> 1.2)
color_diff (~> 0.1)
concurrent-ruby
@ -894,7 +889,7 @@ DEPENDENCIES
nsa!
oj (~> 3.14)
omniauth (~> 2.0)
omniauth-cas!
omniauth-cas (~> 3.0.0.beta.1)
omniauth-rails_csrf_protection (~> 1.0)
omniauth-saml (~> 2.0)
omniauth_openid_connect (~> 0.6.1)
@ -961,4 +956,4 @@ RUBY VERSION
ruby 3.2.2p53
BUNDLED WITH
2.4.20
2.5.4

View file

@ -24,7 +24,7 @@ class ActivityPub::FollowersSynchronizationsController < ActivityPub::BaseContro
end
def set_items
@items = @account.followers.where(Account.arel_table[:uri].matches("#{Account.sanitize_sql_like(uri_prefix)}/%", false, true)).or(@account.followers.where(uri: uri_prefix)).pluck(:uri)
@items = @account.followers.matches_uri_prefix(uri_prefix).pluck(:uri)
end
def collection_presenter

View file

@ -24,7 +24,7 @@ class ActivityPub::InboxesController < ActivityPub::BaseController
def unknown_affected_account?
json = Oj.load(body, mode: :strict)
json.is_a?(Hash) && %w(Delete Update).include?(json['type']) && json['actor'].present? && json['actor'] == value_or_id(json['object']) && !Account.where(uri: json['actor']).exists?
json.is_a?(Hash) && %w(Delete Update).include?(json['type']) && json['actor'].present? && json['actor'] == value_or_id(json['object']) && !Account.exists?(uri: json['actor'])
rescue Oj::ParseError
false
end

View file

@ -6,7 +6,7 @@ module Admin
def index
authorize :audit_log, :index?
@auditable_accounts = Account.where(id: Admin::ActionLog.select('distinct account_id')).select(:id, :username)
@auditable_accounts = Account.auditable.select(:id, :username)
end
private

View file

@ -3,11 +3,11 @@
module Admin
class ConfirmationsController < BaseController
before_action :set_user
before_action :check_confirmation, only: [:resend]
before_action :redirect_confirmed_user, only: [:resend], if: :user_confirmed?
def create
authorize @user, :confirm?
@user.confirm!
@user.mark_email_as_confirmed!
log_action :confirm, @user
redirect_to admin_accounts_path
end
@ -25,11 +25,13 @@ module Admin
private
def check_confirmation
if @user.confirmed?
flash[:error] = I18n.t('admin.accounts.resend_confirmation.already_confirmed')
redirect_to admin_accounts_path
end
def redirect_confirmed_user
flash[:error] = I18n.t('admin.accounts.resend_confirmation.already_confirmed')
redirect_to admin_accounts_path
end
def user_confirmed?
@user.confirmed?
end
end
end

View file

@ -38,7 +38,7 @@ module Admin
log_action :create, @email_domain_block
(@email_domain_block.other_domains || []).uniq.each do |domain|
next if EmailDomainBlock.where(domain: domain).exists?
next if EmailDomainBlock.exists?(domain: domain)
other_email_domain_block = EmailDomainBlock.create!(domain: domain, allow_with_approval: @email_domain_block.allow_with_approval, parent: @email_domain_block)
log_action :create, other_email_domain_block

View file

@ -49,7 +49,7 @@ module Admin
next
end
@warning_domains = Instance.where(domain: @domain_blocks.map(&:domain)).where('EXISTS (SELECT 1 FROM follows JOIN accounts ON follows.account_id = accounts.id OR follows.target_account_id = accounts.id WHERE accounts.domain = instances.domain)').pluck(:domain)
@warning_domains = instances_from_imported_blocks.pluck(:domain)
rescue ActionController::ParameterMissing
flash.now[:alert] = I18n.t('admin.export_domain_blocks.no_file')
set_dummy_import!
@ -58,6 +58,10 @@ module Admin
private
def instances_from_imported_blocks
Instance.with_domain_follows(@domain_blocks.map(&:domain))
end
def export_filename
'domain_blocks.csv'
end

View file

@ -21,7 +21,7 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
return [] if hide_results?
scope = default_accounts
scope = scope.where.not(id: current_account.excluded_from_timeline_account_ids) unless current_account.nil? || current_account.id == @account.id
scope = scope.not_excluded_by_account(current_account) unless current_account.nil? || current_account.id == @account.id
scope.merge(paginated_follows).to_a
end
@ -30,7 +30,7 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
end
def default_accounts
Account.includes(:active_relationships, :account_stat).references(:active_relationships)
Account.includes(:active_relationships, :account_stat, :user).references(:active_relationships)
end
def paginated_follows

View file

@ -21,7 +21,7 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
return [] if hide_results?
scope = default_accounts
scope = scope.where.not(id: current_account.excluded_from_timeline_account_ids) unless current_account.nil? || current_account.id == @account.id
scope = scope.not_excluded_by_account(current_account) unless current_account.nil? || current_account.id == @account.id
scope.merge(paginated_follows).to_a
end
@ -30,7 +30,7 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
end
def default_accounts
Account.includes(:passive_relationships, :account_stat).references(:passive_relationships)
Account.includes(:passive_relationships, :account_stat, :user).references(:passive_relationships)
end
def paginated_follows

View file

@ -0,0 +1,30 @@
# frozen_string_literal: true
class Api::V1::AnnualReportsController < Api::BaseController
before_action -> { doorkeeper_authorize! :read, :'read:accounts' }, only: :index
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, except: :index
before_action :require_user!
before_action :set_annual_report, except: :index
def index
with_read_replica do
@presenter = AnnualReportsPresenter.new(GeneratedAnnualReport.where(account_id: current_account.id).pending)
@relationships = StatusRelationshipsPresenter.new(@presenter.statuses, current_account.id)
end
render json: @presenter,
serializer: REST::AnnualReportsSerializer,
relationships: @relationships
end
def read
@annual_report.view!
render_empty
end
private
def set_annual_report
@annual_report = GeneratedAnnualReport.find_by!(account_id: current_account.id, year: params[:id])
end
end

View file

@ -17,7 +17,7 @@ class Api::V1::BlocksController < Api::BaseController
end
def paginated_blocks
@paginated_blocks ||= Block.eager_load(target_account: :account_stat)
@paginated_blocks ||= Block.eager_load(target_account: [:account_stat, :user])
.joins(:target_account)
.merge(Account.without_suspended)
.where(account: current_account)

View file

@ -27,7 +27,7 @@ class Api::V1::DirectoriesController < Api::BaseController
scope.merge!(local_account_scope) if local_accounts?
scope.merge!(account_exclusion_scope) if current_account
scope.merge!(account_domain_block_scope) if current_account && !local_accounts?
end
end.includes(:account_stat, user: :role)
end
def local_accounts?

View file

@ -25,7 +25,7 @@ class Api::V1::EndorsementsController < Api::BaseController
end
def endorsed_accounts
current_account.endorsed_accounts.includes(:account_stat).without_suspended
current_account.endorsed_accounts.includes(:account_stat, :user).without_suspended
end
def insert_pagination_headers

View file

@ -37,7 +37,7 @@ class Api::V1::FollowRequestsController < Api::BaseController
end
def default_accounts
Account.without_suspended.includes(:follow_requests, :account_stat).references(:follow_requests)
Account.without_suspended.includes(:follow_requests, :account_stat, :user).references(:follow_requests)
end
def paginated_follow_requests

View file

@ -37,9 +37,9 @@ class Api::V1::Lists::AccountsController < Api::BaseController
def load_accounts
if unlimited?
@list.accounts.without_suspended.includes(:account_stat).all
@list.accounts.without_suspended.includes(:account_stat, :user).all
else
@list.accounts.without_suspended.includes(:account_stat).paginate_by_max_id(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:max_id], params[:since_id])
@list.accounts.without_suspended.includes(:account_stat, :user).paginate_by_max_id(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:max_id], params[:since_id])
end
end

View file

@ -19,7 +19,7 @@ class Api::V1::MarkersController < Api::BaseController
@markers = {}
resource_params.each_pair do |timeline, timeline_params|
@markers[timeline] = current_user.markers.find_or_initialize_by(timeline: timeline)
@markers[timeline] = current_user.markers.find_or_create_by(timeline: timeline)
@markers[timeline].update!(timeline_params)
end
end

View file

@ -17,7 +17,7 @@ class Api::V1::MutesController < Api::BaseController
end
def paginated_mutes
@paginated_mutes ||= Mute.eager_load(:target_account)
@paginated_mutes ||= Mute.eager_load(target_account: [:account_stat, :user])
.joins(:target_account)
.merge(Account.without_suspended)
.where(account: current_account)

View file

@ -27,7 +27,7 @@ class Api::V1::Peers::SearchController < Api::BaseController
@domains = InstancesIndex.query(function_score: {
query: {
prefix: {
domain: TagManager.instance.normalize_domain(params[:q].strip),
domain: normalized_domain,
},
},
@ -37,11 +37,18 @@ class Api::V1::Peers::SearchController < Api::BaseController
},
}).limit(10).pluck(:domain)
else
domain = params[:q].strip
domain = TagManager.instance.normalize_domain(domain)
@domains = Instance.searchable.where(Instance.arel_table[:domain].matches("#{Instance.sanitize_sql_like(domain)}%", false, true)).limit(10).pluck(:domain)
domain = normalized_domain
@domains = Instance.searchable.domain_starts_with(domain).limit(10).pluck(:domain)
end
rescue Addressable::URI::InvalidURIError
@domains = []
end
def normalized_domain
TagManager.instance.normalize_domain(query_value)
end
def query_value
params[:q].strip
end
end

View file

@ -14,14 +14,14 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::V1::Statuses::Bas
def load_accounts
scope = default_accounts
scope = scope.where.not(id: current_account.excluded_from_timeline_account_ids) unless current_account.nil?
scope = scope.not_excluded_by_account(current_account) unless current_account.nil?
scope.merge(paginated_favourites).to_a
end
def default_accounts
Account
.without_suspended
.includes(:favourites, :account_stat)
.includes(:favourites, :account_stat, :user)
.references(:favourites)
.where(favourites: { status_id: @status.id })
end

View file

@ -14,12 +14,12 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::V1::Statuses::Base
def load_accounts
scope = default_accounts
scope = scope.where.not(id: current_account.excluded_from_timeline_account_ids) unless current_account.nil?
scope = scope.not_excluded_by_account(current_account) unless current_account.nil?
scope.merge(paginated_statuses).to_a
end
def default_accounts
Account.without_suspended.includes(:statuses, :account_stat).references(:statuses)
Account.without_suspended.includes(:statuses, :account_stat, :user).references(:statuses)
end
def paginated_statuses

View file

@ -35,7 +35,7 @@ class Api::V2::FiltersController < Api::BaseController
private
def set_filters
@filters = current_account.custom_filters.includes(:keywords)
@filters = current_account.custom_filters.includes(:keywords, :statuses)
end
def set_filter

View file

@ -8,7 +8,7 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
before_action :set_body_classes
before_action :set_pack
before_action :set_confirmation_user!, only: [:show, :confirm_captcha]
before_action :require_unconfirmed!
before_action :redirect_confirmed_user, if: :signed_in_confirmed_user?
before_action :extend_csp_for_captcha!, only: [:show, :confirm_captcha]
before_action :require_captcha_if_needed!, only: [:show]
@ -70,10 +70,12 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
use_pack 'auth'
end
def require_unconfirmed!
if user_signed_in? && current_user.confirmed? && current_user.unconfirmed_email.blank?
redirect_to(current_user.approved? ? root_path : edit_user_registration_path)
end
def redirect_confirmed_user
redirect_to(current_user.approved? ? root_path : edit_user_registration_path)
end
def signed_in_confirmed_user?
user_signed_in? && current_user.confirmed? && current_user.unconfirmed_email.blank?
end
def set_body_classes

View file

@ -2,7 +2,7 @@
class Auth::PasswordsController < Devise::PasswordsController
skip_before_action :check_self_destruct!
before_action :check_validity_of_reset_password_token, only: :edit
before_action :redirect_invalid_reset_token, only: :edit, unless: :reset_password_token_is_valid?
before_action :set_pack
before_action :set_body_classes
@ -20,11 +20,9 @@ class Auth::PasswordsController < Devise::PasswordsController
private
def check_validity_of_reset_password_token
unless reset_password_token_is_valid?
flash[:error] = I18n.t('auth.invalid_reset_password_token')
redirect_to new_password_path(resource_name)
end
def redirect_invalid_reset_token
flash[:error] = I18n.t('auth.invalid_reset_password_token')
redirect_to new_password_path(resource_name)
end
def set_body_classes

View file

@ -1,6 +1,10 @@
# frozen_string_literal: true
class Auth::SessionsController < Devise::SessionsController
include Redisable
MAX_2FA_ATTEMPTS_PER_HOUR = 10
layout 'auth'
skip_before_action :check_self_destruct!
@ -135,9 +139,23 @@ class Auth::SessionsController < Devise::SessionsController
session.delete(:attempt_user_updated_at)
end
def clear_2fa_attempt_from_user(user)
redis.del(second_factor_attempts_key(user))
end
def check_second_factor_rate_limits(user)
attempts, = redis.multi do |multi|
multi.incr(second_factor_attempts_key(user))
multi.expire(second_factor_attempts_key(user), 1.hour)
end
attempts >= MAX_2FA_ATTEMPTS_PER_HOUR
end
def on_authentication_success(user, security_measure)
@on_authentication_success_called = true
clear_2fa_attempt_from_user(user)
clear_attempt_from_session
user.update_sign_in!(new_sign_in: true)
@ -168,5 +186,14 @@ class Auth::SessionsController < Devise::SessionsController
ip: request.remote_ip,
user_agent: request.user_agent
)
# Only send a notification email every hour at most
return if redis.set("2fa_failure_notification:#{user.id}", '1', ex: 1.hour, get: true).present?
UserMailer.failed_2fa(user, request.remote_ip, request.user_agent, Time.now.utc).deliver_later!
end
def second_factor_attempts_key(user)
"2fa_auth_attempts:#{user.id}:#{Time.now.utc.hour}"
end
end

View file

@ -66,6 +66,11 @@ module Auth::TwoFactorAuthenticationConcern
end
def authenticate_with_two_factor_via_otp(user)
if check_second_factor_rate_limits(user)
flash.now[:alert] = I18n.t('users.rate_limited')
return prompt_for_two_factor(user)
end
if valid_otp_attempt?(user)
on_authentication_success(user, :otp)
else

View file

@ -22,11 +22,20 @@ module WebAppControllerConcern
def redirect_unauthenticated_to_permalinks!
return if user_signed_in? # NOTE: Different from upstream because we allow moved users to log in
redirect_path = PermalinkRedirector.new(request.path).redirect_path
return if redirect_path.blank?
permalink_redirector = PermalinkRedirector.new(request.path)
return if permalink_redirector.redirect_path.blank?
expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.day) unless user_signed_in?
redirect_to(redirect_path)
respond_to do |format|
format.html do
redirect_to(permalink_redirector.redirect_confirmation_path, allow_other_host: false)
end
format.json do
redirect_to(permalink_redirector.redirect_uri, allow_other_host: true)
end
end
end
def set_pack

View file

@ -1,8 +1,21 @@
# frozen_string_literal: true
class CustomCssController < ActionController::Base # rubocop:disable Rails/ApplicationController
before_action :set_user_roles
def show
expires_in 3.minutes, public: true
render content_type: 'text/css'
end
private
def custom_css_styles
Setting.custom_css
end
helper_method :custom_css_styles
def set_user_roles
@user_roles = UserRole.where(highlighted: true).where.not(color: [nil, ''])
end
end

View file

@ -0,0 +1,10 @@
# frozen_string_literal: true
class Redirect::AccountsController < Redirect::BaseController
private
def set_resource
@resource = Account.find(params[:id])
not_found if @resource.local?
end
end

View file

@ -0,0 +1,29 @@
# frozen_string_literal: true
class Redirect::BaseController < ApplicationController
vary_by 'Accept-Language'
before_action :set_pack
before_action :set_resource
before_action :set_app_body_class
def show
@redirect_path = ActivityPub::TagManager.instance.url_for(@resource)
render 'redirects/show', layout: 'application'
end
private
def set_app_body_class
@body_classes = 'app-body'
end
def set_resource
raise NotImplementedError
end
def set_pack
use_pack 'public'
end
end

View file

@ -0,0 +1,10 @@
# frozen_string_literal: true
class Redirect::StatusesController < Redirect::BaseController
private
def set_resource
@resource = Status.find(params[:id])
not_found if @resource.local? || !@resource.distributable?
end
end

View file

@ -6,8 +6,8 @@ module Settings
skip_before_action :check_self_destruct!
skip_before_action :require_functional!
before_action :require_otp_enabled
before_action :require_webauthn_enabled, only: [:index, :destroy]
before_action :redirect_invalid_otp, unless: -> { current_user.otp_enabled? }
before_action :redirect_invalid_webauthn, only: [:index, :destroy], unless: -> { current_user.webauthn_enabled? }
def index; end
def new; end
@ -89,18 +89,14 @@ module Settings
use_pack 'auth'
end
def require_otp_enabled
unless current_user.otp_enabled?
flash[:error] = t('webauthn_credentials.otp_required')
redirect_to settings_two_factor_authentication_methods_path
end
def redirect_invalid_otp
flash[:error] = t('webauthn_credentials.otp_required')
redirect_to settings_two_factor_authentication_methods_path
end
def require_webauthn_enabled
unless current_user.webauthn_enabled?
flash[:error] = t('webauthn_credentials.not_enabled')
redirect_to settings_two_factor_authentication_methods_path
end
def redirect_invalid_webauthn
flash[:error] = t('webauthn_credentials.not_enabled')
redirect_to settings_two_factor_authentication_methods_path
end
end
end

View file

@ -31,22 +31,26 @@ module AccountsHelper
Setting.hide_followers_count || account.user&.settings&.[]('hide_followers_count')
end
def account_formatted_stat(value)
number_to_human(value, precision: 3, strip_insignificant_zeros: true)
end
def account_description(account)
prepend_stats = [
[
number_to_human(account.statuses_count, precision: 3, strip_insignificant_zeros: true),
account_formatted_stat(account.statuses_count),
I18n.t('accounts.posts', count: account.statuses_count),
].join(' '),
[
number_to_human(account.following_count, precision: 3, strip_insignificant_zeros: true),
account_formatted_stat(account.following_count),
I18n.t('accounts.following', count: account.following_count),
].join(' '),
]
unless hide_followers_count?(account)
prepend_stats << [
number_to_human(account.followers_count, precision: 3, strip_insignificant_zeros: true),
account_formatted_stat(account.followers_count),
I18n.t('accounts.followers', count: account.followers_count),
].join(' ')
end

View file

@ -155,7 +155,7 @@ module JsonLdHelper
end
end
def fetch_resource(uri, id, on_behalf_of = nil)
def fetch_resource(uri, id, on_behalf_of = nil, request_options: {})
unless id
json = fetch_resource_without_id_validation(uri, on_behalf_of)
@ -164,14 +164,14 @@ module JsonLdHelper
uri = json['id']
end
json = fetch_resource_without_id_validation(uri, on_behalf_of)
json = fetch_resource_without_id_validation(uri, on_behalf_of, request_options: request_options)
json.present? && json['id'] == uri ? json : nil
end
def fetch_resource_without_id_validation(uri, on_behalf_of = nil, raise_on_temporary_error = false)
def fetch_resource_without_id_validation(uri, on_behalf_of = nil, raise_on_temporary_error = false, request_options: {})
on_behalf_of ||= Account.representative
build_request(uri, on_behalf_of).perform do |response|
build_request(uri, on_behalf_of, options: request_options).perform do |response|
raise Mastodon::UnexpectedResponseError, response unless response_successful?(response) || response_error_unsalvageable?(response) || !raise_on_temporary_error
body_to_json(response.body_with_limit) if response.code == 200
@ -204,8 +204,8 @@ module JsonLdHelper
response.code == 501 || ((400...500).cover?(response.code) && ![401, 408, 429].include?(response.code))
end
def build_request(uri, on_behalf_of = nil)
Request.new(:get, uri).tap do |request|
def build_request(uri, on_behalf_of = nil, options: {})
Request.new(:get, uri, **options).tap do |request|
request.on_behalf_of(on_behalf_of) if on_behalf_of
request.add_headers('Accept' => 'application/activity+json, application/ld+json')
end

View file

@ -2,7 +2,7 @@
module MascotHelper
def mascot_url
full_asset_url(instance_presenter.mascot&.file&.url || asset_pack_path('media/images/elephant_ui_plane.svg'))
full_asset_url(instance_presenter.mascot&.file&.url || frontend_asset_path('images/elephant_ui_plane.svg'))
end
def instance_presenter

View file

@ -24,8 +24,12 @@ module RoutingHelper
Rails.configuration.action_controller.asset_host || root_url
end
def full_pack_url(source, **options)
full_asset_url(asset_pack_path(source, **options))
def frontend_asset_path(source, **options)
asset_pack_path("media/#{source}", **options)
end
def frontend_asset_url(source, **options)
full_asset_url(frontend_asset_path(source, **options))
end
def use_storage?

View file

@ -1,3 +1,3 @@
// eslint-disable-next-line import/no-anonymous-default-export
export default 'SvgrURL';
export const ReactComponent = 'div';
const ReactComponent = 'div';
export default ReactComponent;

View file

@ -0,0 +1,4 @@
/* Placeholder file to have `inert.scss` compiled by Webpack
This is used by the `wicg-inert` polyfill */
import '../styles/inert.scss';

View file

@ -10,6 +10,9 @@ pack:
embed: embed.js
error:
home:
inert:
filename: inert.js
stylesheet: true
mailer:
filename: mailer.js
stylesheet: true

View file

@ -170,6 +170,11 @@ export const openURL = routerHistory => (dispatch, getState) => {
export const clickSearchResult = (q, type) => (dispatch, getState) => {
const previous = getState().getIn(['search', 'recent']);
if (previous.some(x => x.get('q') === q && x.get('type') === type)) {
return;
}
const me = getState().getIn(['meta', 'me']);
const current = previous.add(fromJS({ type, q })).takeLast(4);
@ -198,4 +203,4 @@ export const hydrateSearch = () => (dispatch, getState) => {
if (history !== null) {
dispatch(updateSearchHistory(history));
}
};
};

View file

@ -17,7 +17,7 @@ import { Avatar } from './avatar';
import { Button } from './button';
import { FollowersCounter } from './counters';
import { DisplayName } from './display_name';
import Permalink from './permalink';
import { Permalink } from './permalink';
import { RelativeTimestamp } from './relative_timestamp';
const messages = defineMessages({

View file

@ -6,7 +6,7 @@ import { FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import api from 'flavours/glitch/api';
import Hashtag from 'flavours/glitch/components/hashtag';
import { Hashtag } from 'flavours/glitch/components/hashtag';
export default class Trends extends PureComponent {

View file

@ -7,10 +7,10 @@ import classNames from 'classnames';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { ReactComponent as LinkIcon } from '@material-symbols/svg-600/outlined/link.svg';
import LinkIcon from '@/material-icons/400-24px/link.svg?react';
import { Icon } from 'flavours/glitch/components/icon';
const filename = url => url.split('/').pop().split('#')[0].split('?')[0];
export default class AttachmentList extends ImmutablePureComponent {

View file

@ -2,9 +2,9 @@ import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import { ReactComponent as GroupsIcon } from '@material-symbols/svg-600/outlined/group.svg';
import { ReactComponent as PersonIcon } from '@material-symbols/svg-600/outlined/person.svg';
import { ReactComponent as SmartToyIcon } from '@material-symbols/svg-600/outlined/smart_toy.svg';
import GroupsIcon from '@/material-icons/400-24px/group.svg?react';
import PersonIcon from '@/material-icons/400-24px/person.svg?react';
import SmartToyIcon from '@/material-icons/400-24px/smart_toy.svg?react';
export const Badge = ({ icon, label, domain }) => (

View file

@ -2,8 +2,7 @@ import { useCallback } from 'react';
import { FormattedMessage } from 'react-intl';
import { ReactComponent as ArrowBackIcon } from '@material-symbols/svg-600/outlined/arrow_back.svg';
import ArrowBackIcon from '@/material-icons/400-24px/arrow_back.svg?react';
import { Icon } from 'flavours/glitch/components/icon';
import { ButtonInTabsBar } from 'flavours/glitch/features/ui/util/columns_context';

View file

@ -6,17 +6,17 @@ import { FormattedMessage, injectIntl, defineMessages } from 'react-intl';
import classNames from 'classnames';
import { withRouter } from 'react-router-dom';
import { ReactComponent as AddIcon } from '@material-symbols/svg-600/outlined/add.svg';
import { ReactComponent as ArrowBackIcon } from '@material-symbols/svg-600/outlined/arrow_back.svg';
import { ReactComponent as ChevronLeftIcon } from '@material-symbols/svg-600/outlined/chevron_left.svg';
import { ReactComponent as ChevronRightIcon } from '@material-symbols/svg-600/outlined/chevron_right.svg';
import { ReactComponent as CloseIcon } from '@material-symbols/svg-600/outlined/close.svg';
import { ReactComponent as TuneIcon } from '@material-symbols/svg-600/outlined/tune.svg';
import AddIcon from '@/material-icons/400-24px/add.svg?react';
import ArrowBackIcon from '@/material-icons/400-24px/arrow_back.svg?react';
import ChevronLeftIcon from '@/material-icons/400-24px/chevron_left.svg?react';
import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react';
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
import TuneIcon from '@/material-icons/400-24px/tune.svg?react';
import { Icon } from 'flavours/glitch/components/icon';
import { ButtonInTabsBar, useColumnsContext } from 'flavours/glitch/features/ui/util/columns_context';
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
import { useAppHistory } from './router';
const messages = defineMessages({

View file

@ -8,8 +8,7 @@ import { useCallback, useState, useEffect } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { ReactComponent as CloseIcon } from '@material-symbols/svg-600/outlined/close.svg';
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
import { changeSetting } from 'flavours/glitch/actions/settings';
import { bannerSettings } from 'flavours/glitch/settings';
import { useAppSelector, useAppDispatch } from 'flavours/glitch/store';

View file

@ -2,7 +2,7 @@ import { useCallback } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { ReactComponent as LockOpenIcon } from '@material-symbols/svg-600/outlined/lock_open.svg';
import LockOpenIcon from '@/material-icons/400-24px/lock_open.svg?react';
import { IconButton } from './icon_button';

View file

@ -6,10 +6,10 @@ import { withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { ReactComponent as CloseIcon } from '@material-symbols/svg-600/outlined/close.svg';
import { supportsPassiveEvents } from 'detect-passive-events';
import Overlay from 'react-overlays/Overlay';
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
import { CircularProgress } from 'flavours/glitch/components/circular_progress';
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';

View file

@ -5,8 +5,8 @@ import { FormattedMessage, injectIntl } from 'react-intl';
import { connect } from 'react-redux';
import { ReactComponent as ArrowDropDownIcon } from '@material-symbols/svg-600/outlined/arrow_drop_down.svg';
import ArrowDropDownIcon from '@/material-icons/400-24px/arrow_drop_down.svg?react';
import { openModal } from 'flavours/glitch/actions/modal';
import { Icon } from 'flavours/glitch/components/icon';
import InlineAccount from 'flavours/glitch/components/inline_account';

View file

@ -1,123 +0,0 @@
// @ts-check
import PropTypes from 'prop-types';
import { Component } from 'react';
import { FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { Sparklines, SparklinesCurve } from 'react-sparklines';
import { ShortNumber } from 'flavours/glitch/components/short_number';
import { Skeleton } from 'flavours/glitch/components/skeleton';
import Permalink from './permalink';
class SilentErrorBoundary extends Component {
static propTypes = {
children: PropTypes.node,
};
state = {
error: false,
};
componentDidCatch() {
this.setState({ error: true });
}
render() {
if (this.state.error) {
return null;
}
return this.props.children;
}
}
/**
* Used to render counter of how much people are talking about hashtag
* @type {(displayNumber: JSX.Element, pluralReady: number) => JSX.Element}
*/
export const accountsCountRenderer = (displayNumber, pluralReady) => (
<FormattedMessage
id='trends.counter_by_accounts'
defaultMessage='{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {# days}}'
values={{
count: pluralReady,
counter: <strong>{displayNumber}</strong>,
days: 2,
}}
/>
);
// @ts-expect-error
export const ImmutableHashtag = ({ hashtag }) => (
<Hashtag
name={hashtag.get('name')}
href={hashtag.get('url')}
to={`/tags/${hashtag.get('name')}`}
people={hashtag.getIn(['history', 0, 'accounts']) * 1 + hashtag.getIn(['history', 1, 'accounts']) * 1}
// @ts-expect-error
history={hashtag.get('history').reverse().map((day) => day.get('uses')).toArray()}
/>
);
ImmutableHashtag.propTypes = {
hashtag: ImmutablePropTypes.map.isRequired,
};
// @ts-expect-error
const Hashtag = ({ name, href, to, people, uses, history, className, description, withGraph }) => (
<div className={classNames('trends__item', className)}>
<div className='trends__item__name'>
<Permalink href={href} to={to}>
{name ? <>#<span>{name}</span></> : <Skeleton width={50} />}
</Permalink>
{description ? (
<span>{description}</span>
) : (
typeof people !== 'undefined' ? <ShortNumber value={people} renderer={accountsCountRenderer} /> : <Skeleton width={100} />
)}
</div>
{typeof uses !== 'undefined' && (
<div className='trends__item__current'>
<ShortNumber value={uses} />
</div>
)}
{withGraph && (
<div className='trends__item__sparkline'>
<SilentErrorBoundary>
<Sparklines width={50} height={28} data={history ? history : Array.from(Array(7)).map(() => 0)}>
<SparklinesCurve style={{ fill: 'none' }} />
</Sparklines>
</SilentErrorBoundary>
</div>
)}
</div>
);
Hashtag.propTypes = {
name: PropTypes.string,
href: PropTypes.string,
to: PropTypes.string,
people: PropTypes.number,
description: PropTypes.node,
uses: PropTypes.number,
history: PropTypes.arrayOf(PropTypes.number),
className: PropTypes.string,
withGraph: PropTypes.bool,
};
Hashtag.defaultProps = {
withGraph: true,
};
export default Hashtag;

View file

@ -0,0 +1,149 @@
import type { JSX } from 'react';
import { Component } from 'react';
import { FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import type Immutable from 'immutable';
import { Sparklines, SparklinesCurve } from 'react-sparklines';
import { ShortNumber } from 'flavours/glitch/components/short_number';
import { Skeleton } from 'flavours/glitch/components/skeleton';
import { Permalink } from './permalink';
interface SilentErrorBoundaryProps {
children: React.ReactNode;
}
class SilentErrorBoundary extends Component<SilentErrorBoundaryProps> {
state = {
error: false,
};
componentDidCatch() {
this.setState({ error: true });
}
render() {
if (this.state.error) {
return null;
}
return this.props.children;
}
}
/**
* Used to render counter of how much people are talking about hashtag
* @param displayNumber Counter number to display
* @param pluralReady Whether the count is plural
* @returns Formatted counter of how much people are talking about hashtag
*/
export const accountsCountRenderer = (
displayNumber: JSX.Element,
pluralReady: number,
) => (
<FormattedMessage
id='trends.counter_by_accounts'
defaultMessage='{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {# days}}'
values={{
count: pluralReady,
counter: <strong>{displayNumber}</strong>,
days: 2,
}}
/>
);
interface ImmutableHashtagProps {
hashtag: Immutable.Map<string, unknown>;
}
export const ImmutableHashtag = ({ hashtag }: ImmutableHashtagProps) => (
<Hashtag
name={hashtag.get('name') as string}
href={hashtag.get('url') as string}
to={`/tags/${hashtag.get('name') as string}`}
people={
(hashtag.getIn(['history', 0, 'accounts']) as number) * 1 +
(hashtag.getIn(['history', 1, 'accounts']) as number) * 1
}
history={(
hashtag.get('history') as Immutable.Collection.Indexed<
Immutable.Map<string, number>
>
)
.reverse()
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
.map((day) => day.get('uses')!)
.toArray()}
/>
);
export interface HashtagProps {
className?: string;
description?: React.ReactNode;
history?: number[];
href: string;
name: string;
people: number;
to: string;
uses?: number;
withGraph?: boolean;
}
export const Hashtag: React.FC<HashtagProps> = ({
name,
href,
to,
people,
uses,
history,
className,
description,
withGraph = true,
}) => (
<div className={classNames('trends__item', className)}>
<div className='trends__item__name'>
<Permalink href={href} to={to}>
{name ? (
<>
#<span>{name}</span>
</>
) : (
<Skeleton width={50} />
)}
</Permalink>
{description ? (
<span>{description}</span>
) : typeof people !== 'undefined' ? (
<ShortNumber value={people} renderer={accountsCountRenderer} />
) : (
<Skeleton width={100} />
)}
</div>
{typeof uses !== 'undefined' && (
<div className='trends__item__current'>
<ShortNumber value={uses} />
</div>
)}
{withGraph && (
<div className='trends__item__sparkline'>
<SilentErrorBoundary>
<Sparklines
width={50}
height={28}
data={history ? history : Array.from(Array(7)).map(() => 0)}
>
<SparklinesCurve style={{ fill: 'none' }} />
</Sparklines>
</SilentErrorBoundary>
</div>
)}
</div>
);

View file

@ -1,6 +1,7 @@
import classNames from 'classnames';
import { ReactComponent as CheckBoxOutlineBlankIcon } from '@material-symbols/svg-600/outlined/check_box_outline_blank.svg';
import CheckBoxOutlineBlankIcon from '@/material-icons/400-24px/check_box_outline_blank.svg?react';
import { isProduction } from 'flavours/glitch/utils/environment';
interface SVGPropsWithTitle extends React.SVGProps<SVGSVGElement> {
title?: string;
@ -24,7 +25,7 @@ export const Icon: React.FC<Props> = ({
}) => {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!IconComponent) {
if (process.env.NODE_ENV !== 'production') {
if (!isProduction()) {
throw new Error(
`<Icon id="${id}" className="${className}"> is missing an "icon" prop.`,
);

View file

@ -2,8 +2,7 @@ import { useCallback } from 'react';
import { useIntl, defineMessages } from 'react-intl';
import { ReactComponent as MoreHorizIcon } from '@material-symbols/svg-600/outlined/more_horiz.svg';
import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react';
import { Icon } from 'flavours/glitch/components/icon';
const messages = defineMessages({

View file

@ -1,4 +1,4 @@
import logo from 'mastodon/../images/logo.svg';
import logo from '@/images/logo.svg';
export const WordmarkLogo = () => (
<svg viewBox='0 0 261 66' className='logo logo--wordmark' role='img'>

View file

@ -8,9 +8,9 @@ import classNames from 'classnames';
import { is } from 'immutable';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { ReactComponent as VisibilityOffIcon } from '@material-symbols/svg-600/outlined/visibility_off.svg';
import { debounce } from 'lodash';
import VisibilityOffIcon from '@/material-icons/400-24px/visibility_off.svg?react';
import { Blurhash } from 'flavours/glitch/components/blurhash';
import { autoPlayGif, displayMedia, useBlurhash } from '../initial_state';
@ -123,7 +123,7 @@ class Item extends PureComponent {
}
if (attachment.get('description')?.length > 0) {
badges.push(<span key='alt' className='media-gallery__gifv__label'>ALT</span>);
badges.push(<span key='alt' className='media-gallery__alt__label'>ALT</span>);
}
const description = attachment.getIn(['translation', 'description']) || attachment.get('description');

View file

@ -12,10 +12,10 @@ import classNames from 'classnames';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { ReactComponent as DeleteIcon } from '@material-symbols/svg-600/outlined/delete.svg';
import DeleteIcon from '@/material-icons/400-24px/delete.svg?react';
import { Icon } from 'flavours/glitch/components/icon';
const messages = defineMessages({
btnAll : { id: 'notification_purge.btn_all', defaultMessage: 'Select\nall' },
btnNone : { id: 'notification_purge.btn_none', defaultMessage: 'Select\nnone' },

View file

@ -1,50 +0,0 @@
import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import { withOptionalRouter, WithOptionalRouterPropTypes } from 'flavours/glitch/utils/react_router';
class Permalink extends PureComponent {
static propTypes = {
className: PropTypes.string,
href: PropTypes.string.isRequired,
to: PropTypes.string.isRequired,
children: PropTypes.node,
onInterceptClick: PropTypes.func,
...WithOptionalRouterPropTypes,
};
handleClick = (e) => {
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
if (this.props.onInterceptClick && this.props.onInterceptClick()) {
e.preventDefault();
return;
}
if (this.props.history) {
e.preventDefault();
this.props.history.push(this.props.to);
}
}
};
render () {
const {
children,
className,
href,
to,
onInterceptClick,
...other
} = this.props;
return (
<a target='_blank' href={href} onClick={this.handleClick} {...other} className={`permalink${className ? ' ' + className : ''}`}>
{children}
</a>
);
}
}
export default withOptionalRouter(Permalink);

View file

@ -0,0 +1,41 @@
import { useCallback } from 'react';
import { useAppHistory } from './router';
interface Props extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
to: string;
}
export const Permalink: React.FC<Props> = ({
className,
href,
to,
children,
...props
}) => {
const history = useAppHistory();
const handleClick = useCallback<React.MouseEventHandler<HTMLAnchorElement>>(
(e) => {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- history can actually be undefined as the component can be mounted outside a router context
if (e.button === 0 && !(e.ctrlKey || e.metaKey) && history) {
e.preventDefault();
history.push(to);
}
},
[history, to],
);
return (
<a
target='_blank'
rel='noreferrer'
href={href}
onClick={handleClick}
className={`permalink${className ? ' ' + className : ''}`}
{...props}
>
{children}
</a>
);
};

View file

@ -5,8 +5,8 @@ import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import { ReactComponent as CancelPresentationIcon } from '@material-symbols/svg-600/outlined/cancel_presentation.svg';
import CancelPresentationIcon from '@/material-icons/400-24px/cancel_presentation.svg?react';
import { removePictureInPicture } from 'flavours/glitch/actions/picture_in_picture';
import { Icon } from 'flavours/glitch/components/icon';

View file

@ -7,10 +7,10 @@ import classNames from 'classnames';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { ReactComponent as CheckIcon } from '@material-symbols/svg-600/outlined/check.svg';
import escapeTextContentForBrowser from 'escape-html';
import spring from 'react-motion/lib/spring';
import CheckIcon from '@/material-icons/400-24px/check.svg?react';
import { Icon } from 'flavours/glitch/components/icon';
import emojify from 'flavours/glitch/features/emoji/emoji';
import Motion from 'flavours/glitch/features/ui/util/optional_motion';

View file

@ -11,6 +11,7 @@ import type {
import { createBrowserHistory } from 'history';
import { layoutFromWindow } from 'flavours/glitch/is_mobile';
import { isDevelopment } from 'flavours/glitch/utils/environment';
interface MastodonLocationState {
fromMastodon?: boolean;
@ -40,7 +41,7 @@ function normalizePath(
} else if (
location.state !== undefined &&
state !== undefined &&
process.env.NODE_ENV === 'development'
isDevelopment()
) {
// eslint-disable-next-line no-console
console.log(

View file

@ -8,21 +8,22 @@ import { withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { ReactComponent as BookmarkIcon } from '@material-symbols/svg-600/outlined/bookmark-fill.svg';
import { ReactComponent as BookmarkBorderIcon } from '@material-symbols/svg-600/outlined/bookmark.svg';
import { ReactComponent as MoreHorizIcon } from '@material-symbols/svg-600/outlined/more_horiz.svg';
import { ReactComponent as RepeatIcon } from '@material-symbols/svg-600/outlined/repeat.svg';
import { ReactComponent as ReplyIcon } from '@material-symbols/svg-600/outlined/reply.svg';
import { ReactComponent as ReplyAllIcon } from '@material-symbols/svg-600/outlined/reply_all.svg';
import { ReactComponent as StarIcon } from '@material-symbols/svg-600/outlined/star-fill.svg';
import { ReactComponent as StarBorderIcon } from '@material-symbols/svg-600/outlined/star.svg';
import { ReactComponent as VisibilityIcon } from '@material-symbols/svg-600/outlined/visibility.svg';
import BookmarkIcon from '@/material-icons/400-24px/bookmark-fill.svg?react';
import BookmarkBorderIcon from '@/material-icons/400-24px/bookmark.svg?react';
import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react';
import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react';
import ReplyIcon from '@/material-icons/400-24px/reply.svg?react';
import ReplyAllIcon from '@/material-icons/400-24px/reply_all.svg?react';
import StarIcon from '@/material-icons/400-24px/star-fill.svg?react';
import StarBorderIcon from '@/material-icons/400-24px/star.svg?react';
import VisibilityIcon from '@/material-icons/400-24px/visibility.svg?react';
import RepeatActiveIcon from '@/svg-icons/repeat_active.svg?react';
import RepeatDisabledIcon from '@/svg-icons/repeat_disabled.svg';
import RepeatPrivateIcon from '@/svg-icons/repeat_private.svg';
import RepeatPrivateActiveIcon from '@/svg-icons/repeat_private_active.svg?react';
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'flavours/glitch/permissions';
import { accountAdminLink, statusAdminLink } from 'flavours/glitch/utils/backend_links';
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
import { ReactComponent as RepeatDisabledIcon } from 'mastodon/../svg-icons/repeat_disabled.svg';
import { ReactComponent as RepeatPrivateIcon } from 'mastodon/../svg-icons/repeat_private.svg';
import DropdownMenuContainer from '../containers/dropdown_menu_container';
import { me } from '../initial_state';
@ -304,7 +305,7 @@ class StatusActionBar extends ImmutablePureComponent {
if (status.get('reblogged')) {
reblogTitle = intl.formatMessage(messages.cancel_reblog_private);
reblogIconComponent = publicStatus ? RepeatIcon : RepeatPrivateIcon;
reblogIconComponent = publicStatus ? RepeatActiveIcon : RepeatPrivateActiveIcon;
} else if (publicStatus) {
reblogTitle = intl.formatMessage(messages.reblog);
reblogIconComponent = RepeatIcon;

View file

@ -9,17 +9,17 @@ import { withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { connect } from 'react-redux';
import { ReactComponent as ImageIcon } from '@material-symbols/svg-600/outlined/image.svg';
import { ReactComponent as InsertChartIcon } from '@material-symbols/svg-600/outlined/insert_chart.svg';
import { ReactComponent as LinkIcon } from '@material-symbols/svg-600/outlined/link.svg';
import { ReactComponent as MovieIcon } from '@material-symbols/svg-600/outlined/movie.svg';
import { ReactComponent as MusicNoteIcon } from '@material-symbols/svg-600/outlined/music_note.svg';
import ImageIcon from '@/material-icons/400-24px/image.svg?react';
import InsertChartIcon from '@/material-icons/400-24px/insert_chart.svg?react';
import LinkIcon from '@/material-icons/400-24px/link.svg?react';
import MovieIcon from '@/material-icons/400-24px/movie.svg?react';
import MusicNoteIcon from '@/material-icons/400-24px/music_note.svg?react';
import { Icon } from 'flavours/glitch/components/icon';
import { autoPlayGif, languages as preloadedLanguages } from 'flavours/glitch/initial_state';
import { decode as decodeIDNA } from 'flavours/glitch/utils/idna';
import Permalink from './permalink';
import { Permalink } from './permalink';
const textMatchesTarget = (text, origin, host) => {
return (text === origin || text === host

View file

@ -6,18 +6,18 @@ import { defineMessages, injectIntl } from 'react-intl';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { ReactComponent as ExpandLessIcon } from '@material-symbols/svg-600/outlined/expand_less.svg';
import { ReactComponent as ForumIcon } from '@material-symbols/svg-600/outlined/forum.svg';
import { ReactComponent as HomeIcon } from '@material-symbols/svg-600/outlined/home.svg';
import { ReactComponent as ImageIcon } from '@material-symbols/svg-600/outlined/image.svg';
import { ReactComponent as InsertChartIcon } from '@material-symbols/svg-600/outlined/insert_chart.svg';
import { ReactComponent as LinkIcon } from '@material-symbols/svg-600/outlined/link.svg';
import { ReactComponent as MovieIcon } from '@material-symbols/svg-600/outlined/movie.svg';
import { ReactComponent as MusicNoteIcon } from '@material-symbols/svg-600/outlined/music_note.svg';
import ExpandLessIcon from '@/material-icons/400-24px/expand_less.svg?react';
import ForumIcon from '@/material-icons/400-24px/forum.svg?react';
import HomeIcon from '@/material-icons/400-24px/home.svg?react';
import ImageIcon from '@/material-icons/400-24px/image.svg?react';
import InsertChartIcon from '@/material-icons/400-24px/insert_chart.svg?react';
import LinkIcon from '@/material-icons/400-24px/link.svg?react';
import MovieIcon from '@/material-icons/400-24px/movie.svg?react';
import MusicNoteIcon from '@/material-icons/400-24px/music_note.svg?react';
import { Icon } from 'flavours/glitch/components/icon';
import { languages } from 'flavours/glitch/initial_state';
import { IconButton } from './icon_button';
import { VisibilityIcon } from './visibility_icon';

View file

@ -6,16 +6,16 @@ import { FormattedMessage } from 'react-intl';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { ReactComponent as EditIcon } from '@material-symbols/svg-600/outlined/edit.svg';
import { ReactComponent as HomeIcon } from '@material-symbols/svg-600/outlined/home-fill.svg';
import { ReactComponent as InsertChartIcon } from '@material-symbols/svg-600/outlined/insert_chart.svg';
import { ReactComponent as PushPinIcon } from '@material-symbols/svg-600/outlined/push_pin.svg';
import { ReactComponent as RepeatIcon } from '@material-symbols/svg-600/outlined/repeat.svg';
import { ReactComponent as StarIcon } from '@material-symbols/svg-600/outlined/star-fill.svg';
import EditIcon from '@/material-icons/400-24px/edit.svg?react';
import HomeIcon from '@/material-icons/400-24px/home-fill.svg?react';
import InsertChartIcon from '@/material-icons/400-24px/insert_chart.svg?react';
import PushPinIcon from '@/material-icons/400-24px/push_pin.svg?react';
import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react';
import StarIcon from '@/material-icons/400-24px/star-fill.svg?react';
import { Icon } from 'flavours/glitch/components/icon';
import { me } from 'flavours/glitch/initial_state';
export default class StatusPrepend extends PureComponent {
static propTypes = {

View file

@ -1,4 +1,4 @@
import { ReactComponent as CheckIcon } from '@material-symbols/svg-600/outlined/check.svg';
import CheckIcon from '@/material-icons/400-24px/check.svg?react';
import { Icon } from './icon';

View file

@ -1,9 +1,9 @@
import { defineMessages, useIntl } from 'react-intl';
import { ReactComponent as LockIcon } from '@material-symbols/svg-600/outlined/lock.svg';
import { ReactComponent as LockOpenIcon } from '@material-symbols/svg-600/outlined/lock_open.svg';
import { ReactComponent as MailIcon } from '@material-symbols/svg-600/outlined/mail.svg';
import { ReactComponent as PublicIcon } from '@material-symbols/svg-600/outlined/public.svg';
import LockIcon from '@/material-icons/400-24px/lock.svg?react';
import LockOpenIcon from '@/material-icons/400-24px/lock_open.svg?react';
import MailIcon from '@/material-icons/400-24px/mail.svg?react';
import PublicIcon from '@/material-icons/400-24px/public.svg?react';
import { Icon } from './icon';

View file

@ -18,8 +18,9 @@ import UI from 'flavours/glitch/features/ui';
import initialState, { title as siteTitle } from 'flavours/glitch/initial_state';
import { IntlProvider } from 'flavours/glitch/locales';
import { store } from 'flavours/glitch/store';
import { isProduction } from 'flavours/glitch/utils/environment';
const title = process.env.NODE_ENV === 'production' ? siteTitle : `${siteTitle} (Dev)`;
const title = isProduction() ? siteTitle : `${siteTitle} (Dev)`;
const hydrateAction = hydrateStore(initialState);

View file

@ -10,9 +10,9 @@ import { List as ImmutableList } from 'immutable';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { connect } from 'react-redux';
import { ReactComponent as ChevronRightIcon } from '@material-symbols/svg-600/outlined/chevron_right.svg';
import { ReactComponent as ExpandMoreIcon } from '@material-symbols/svg-600/outlined/expand_more.svg';
import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react';
import ExpandMoreIcon from '@/material-icons/400-24px/expand_more.svg?react';
import { fetchServer, fetchExtendedDescription, fetchDomainBlocks } from 'flavours/glitch/actions/server';
import Column from 'flavours/glitch/components/column';
import { Icon } from 'flavours/glitch/components/icon';

View file

@ -6,10 +6,10 @@ import { NavLink } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { ReactComponent as InfoIcon } from '@material-symbols/svg-600/outlined/info.svg';
import InfoIcon from '@/material-icons/400-24px/info.svg?react';
import { Icon } from 'flavours/glitch/components/icon';
class ActionBar extends PureComponent {
static propTypes = {
@ -30,7 +30,8 @@ class ActionBar extends PureComponent {
return (
<div>
<div className='account__disclaimer'>
<Icon id='info-circle' icon={InfoIcon} /> <FormattedMessage
<Icon id='info-circle' icon={InfoIcon} />
<FormattedMessage
id='account.suspended_disclaimer_full'
defaultMessage='This user has been suspended by a moderator.'
/>
@ -44,14 +45,17 @@ class ActionBar extends PureComponent {
if (account.get('acct') !== account.get('username')) {
extraInfo = (
<div className='account__disclaimer'>
<Icon id='info-circle' icon={InfoIcon} /> <FormattedMessage
id='account.disclaimer_full'
defaultMessage="Information below may reflect the user's profile incompletely."
/>
{' '}
<a target='_blank' rel='noopener' href={account.get('url')}>
<FormattedMessage id='account.view_full_profile' defaultMessage='View full profile' />
</a>
<Icon id='info-circle' icon={InfoIcon} />
<div>
<FormattedMessage
id='account.disclaimer_full'
defaultMessage="Information below may reflect the user's profile incompletely."
/>
{' '}
<a target='_blank' rel='noopener' href={account.get('url')}>
<FormattedMessage id='account.view_full_profile' defaultMessage='View full profile' />
</a>
</div>
</div>
);
}

View file

@ -5,7 +5,7 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import Hashtag from 'flavours/glitch/components/hashtag';
import { Hashtag } from 'flavours/glitch/components/hashtag';
const messages = defineMessages({
lastStatusAt: { id: 'account.featured_tags.last_status_at', defaultMessage: 'Last post on {date}' },

View file

@ -3,11 +3,11 @@ import { FormattedMessage } from 'react-intl';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { ReactComponent as CheckIcon } from '@material-symbols/svg-600/outlined/check.svg';
import { ReactComponent as CloseIcon } from '@material-symbols/svg-600/outlined/close.svg';
import CheckIcon from '@/material-icons/400-24px/check.svg?react';
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
import { Icon } from 'flavours/glitch/components/icon';
export default class FollowRequestNote extends ImmutablePureComponent {
static propTypes = {

View file

@ -9,12 +9,12 @@ import { withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { ReactComponent as CheckIcon } from '@material-symbols/svg-600/outlined/check.svg';
import { ReactComponent as LockIcon } from '@material-symbols/svg-600/outlined/lock.svg';
import { ReactComponent as MoreHorizIcon } from '@material-symbols/svg-600/outlined/more_horiz.svg';
import { ReactComponent as NotificationsIcon } from '@material-symbols/svg-600/outlined/notifications.svg';
import { ReactComponent as NotificationsActiveIcon } from '@material-symbols/svg-600/outlined/notifications_active-fill.svg';
import CheckIcon from '@/material-icons/400-24px/check.svg?react';
import LockIcon from '@/material-icons/400-24px/lock.svg?react';
import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react';
import NotificationsIcon from '@/material-icons/400-24px/notifications.svg?react';
import NotificationsActiveIcon from '@/material-icons/400-24px/notifications_active-fill.svg?react';
import { Avatar } from 'flavours/glitch/components/avatar';
import { Badge, AutomatedBadge, GroupBadge } from 'flavours/glitch/components/badge';
import { Button } from 'flavours/glitch/components/button';

View file

@ -3,7 +3,7 @@ import { PureComponent } from 'react';
import { injectIntl, defineMessages } from 'react-intl';
import { ReactComponent as PersonIcon } from '@material-symbols/svg-600/outlined/person.svg';
import PersonIcon from '@/material-icons/400-24px/person.svg?react';
import ColumnHeader from '../../../components/column_header';

View file

@ -5,14 +5,14 @@ import classNames from 'classnames';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { ReactComponent as AudiotrackIcon } from '@material-symbols/svg-600/outlined/music_note.svg';
import { ReactComponent as PlayArrowIcon } from '@material-symbols/svg-600/outlined/play_arrow.svg';
import { ReactComponent as VisibilityOffIcon } from '@material-symbols/svg-600/outlined/visibility_off.svg';
import AudiotrackIcon from '@/material-icons/400-24px/music_note.svg?react';
import PlayArrowIcon from '@/material-icons/400-24px/play_arrow.svg?react';
import VisibilityOffIcon from '@/material-icons/400-24px/visibility_off.svg?react';
import { Blurhash } from 'flavours/glitch/components/blurhash';
import { Icon } from 'flavours/glitch/components/icon';
import { autoPlayGif, displayMedia, useBlurhash } from 'flavours/glitch/initial_state';
export default class MediaItem extends ImmutablePureComponent {
static propTypes = {

View file

@ -5,8 +5,8 @@ import { withRouter } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { ReactComponent as TripIcon } from '@material-symbols/svg-600/outlined/trip.svg';
import TripIcon from '@/material-icons/400-24px/trip.svg?react';
import { Icon } from 'flavours/glitch/components/icon';
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';

View file

@ -7,17 +7,18 @@ import classNames from 'classnames';
import { is } from 'immutable';
import { ReactComponent as DownloadIcon } from '@material-symbols/svg-600/outlined/download.svg';
import { ReactComponent as PauseIcon } from '@material-symbols/svg-600/outlined/pause.svg';
import { ReactComponent as PlayArrowIcon } from '@material-symbols/svg-600/outlined/play_arrow-fill.svg';
import { ReactComponent as VisibilityOffIcon } from '@material-symbols/svg-600/outlined/visibility_off.svg';
import { ReactComponent as VolumeOffIcon } from '@material-symbols/svg-600/outlined/volume_off-fill.svg';
import { ReactComponent as VolumeUpIcon } from '@material-symbols/svg-600/outlined/volume_up-fill.svg';
import { throttle, debounce } from 'lodash';
import DownloadIcon from '@/material-icons/400-24px/download.svg?react';
import PauseIcon from '@/material-icons/400-24px/pause.svg?react';
import PlayArrowIcon from '@/material-icons/400-24px/play_arrow-fill.svg?react';
import VisibilityOffIcon from '@/material-icons/400-24px/visibility_off.svg?react';
import VolumeOffIcon from '@/material-icons/400-24px/volume_off-fill.svg?react';
import VolumeUpIcon from '@/material-icons/400-24px/volume_up-fill.svg?react';
import { Icon } from 'flavours/glitch/components/icon';
import { formatTime, getPointerPosition, fileNameFromURL } from 'flavours/glitch/features/video';
import { Blurhash } from '../../components/blurhash';
import { displayMedia, useBlurhash } from '../../initial_state';

View file

@ -6,9 +6,10 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { connect } from 'react-redux';
import { ReactComponent as BlockIcon } from '@material-symbols/svg-600/outlined/block-fill.svg';
import { debounce } from 'lodash';
import BlockIcon from '@/material-icons/400-24px/block-fill.svg?react';
import { fetchBlocks, expandBlocks } from '../../actions/blocks';
import { LoadingIndicator } from '../../components/loading_indicator';
import ScrollableList from '../../components/scrollable_list';

View file

@ -8,9 +8,9 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { connect } from 'react-redux';
import { ReactComponent as BookmarksIcon } from '@material-symbols/svg-600/outlined/bookmarks-fill.svg';
import { debounce } from 'lodash';
import BookmarksIcon from '@/material-icons/400-24px/bookmarks-fill.svg?react';
import { fetchBookmarkedStatuses, expandBookmarkedStatuses } from 'flavours/glitch/actions/bookmarks';
import { addColumn, removeColumn, moveColumn } from 'flavours/glitch/actions/columns';
import ColumnHeader from 'flavours/glitch/components/column_header';

View file

@ -7,8 +7,8 @@ import { Helmet } from 'react-helmet';
import { connect } from 'react-redux';
import { ReactComponent as PeopleIcon } from '@material-symbols/svg-600/outlined/group.svg';
import PeopleIcon from '@/material-icons/400-24px/group.svg?react';
import { DismissableBanner } from 'flavours/glitch/components/dismissable_banner';
import { domain } from 'flavours/glitch/initial_state';

View file

@ -5,10 +5,10 @@ import { defineMessages, injectIntl } from 'react-intl';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { ReactComponent as MenuIcon } from '@material-symbols/svg-600/outlined/menu.svg';
import MenuIcon from '@/material-icons/400-24px/menu.svg?react';
import { preferencesLink, profileLink } from 'flavours/glitch/utils/backend_links';
import DropdownMenuContainer from '../../../containers/dropdown_menu_container';
const messages = defineMessages({

View file

@ -7,18 +7,18 @@ import { Link } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { ReactComponent as PeopleIcon } from '@material-symbols/svg-600/outlined/group.svg';
import { ReactComponent as HomeIcon } from '@material-symbols/svg-600/outlined/home-fill.svg';
import { ReactComponent as LogoutIcon } from '@material-symbols/svg-600/outlined/logout.svg';
import { ReactComponent as ManufacturingIcon } from '@material-symbols/svg-600/outlined/manufacturing.svg';
import { ReactComponent as MenuIcon } from '@material-symbols/svg-600/outlined/menu.svg';
import { ReactComponent as NotificationsIcon } from '@material-symbols/svg-600/outlined/notifications-fill.svg';
import { ReactComponent as PublicIcon } from '@material-symbols/svg-600/outlined/public.svg';
import PeopleIcon from '@/material-icons/400-24px/group.svg?react';
import HomeIcon from '@/material-icons/400-24px/home-fill.svg?react';
import LogoutIcon from '@/material-icons/400-24px/logout.svg?react';
import ManufacturingIcon from '@/material-icons/400-24px/manufacturing.svg?react';
import MenuIcon from '@/material-icons/400-24px/menu.svg?react';
import NotificationsIcon from '@/material-icons/400-24px/notifications-fill.svg?react';
import PublicIcon from '@/material-icons/400-24px/public.svg?react';
import { Icon } from 'flavours/glitch/components/icon';
import { signOutLink } from 'flavours/glitch/utils/backend_links';
import { conditionalRender } from 'flavours/glitch/utils/react_helpers';
const messages = defineMessages({
community: {
defaultMessage: 'Local timeline',

View file

@ -5,7 +5,7 @@ import { FormattedMessage } from 'react-intl';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import Permalink from 'flavours/glitch/components/permalink';
import { Permalink } from 'flavours/glitch/components/permalink';
import { profileLink } from 'flavours/glitch/utils/backend_links';
import { Avatar } from '../../../components/avatar';

View file

@ -6,19 +6,20 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { connect } from 'react-redux';
import { ReactComponent as AttachFileIcon } from '@material-symbols/svg-600/outlined/attach_file.svg';
import { ReactComponent as BrushIcon } from '@material-symbols/svg-600/outlined/brush.svg';
import { ReactComponent as CodeIcon } from '@material-symbols/svg-600/outlined/code.svg';
import { ReactComponent as DescriptionIcon } from '@material-symbols/svg-600/outlined/description.svg';
import { ReactComponent as InsertChartIcon } from '@material-symbols/svg-600/outlined/insert_chart.svg';
import { ReactComponent as MarkdownIcon } from '@material-symbols/svg-600/outlined/markdown.svg';
import { ReactComponent as MoreHorizIcon } from '@material-symbols/svg-600/outlined/more_horiz.svg';
import { ReactComponent as UploadFileIcon } from '@material-symbols/svg-600/outlined/upload_file.svg';
import Toggle from 'react-toggle';
import AttachFileIcon from '@/material-icons/400-24px/attach_file.svg?react';
import BrushIcon from '@/material-icons/400-24px/brush.svg?react';
import CodeIcon from '@/material-icons/400-24px/code.svg?react';
import DescriptionIcon from '@/material-icons/400-24px/description.svg?react';
import InsertChartIcon from '@/material-icons/400-24px/insert_chart.svg?react';
import MarkdownIcon from '@/material-icons/400-24px/markdown.svg?react';
import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react';
import UploadFileIcon from '@/material-icons/400-24px/upload_file.svg?react';
import { IconButton } from 'flavours/glitch/components/icon_button';
import { pollLimits } from 'flavours/glitch/initial_state';
import DropdownContainer from '../containers/dropdown_container';
import LanguageDropdown from '../containers/language_dropdown_container';
import PrivacyDropdownContainer from '../containers/privacy_dropdown_container';

View file

@ -8,9 +8,9 @@ import classNames from 'classnames';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { ReactComponent as AddIcon } from '@material-symbols/svg-600/outlined/add.svg';
import { ReactComponent as CloseIcon } from '@material-symbols/svg-600/outlined/close.svg';
import AddIcon from '@/material-icons/400-24px/add.svg?react';
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
import AutosuggestInput from 'flavours/glitch/components/autosuggest_input';
import { Icon } from 'flavours/glitch/components/icon';
import { IconButton } from 'flavours/glitch/components/icon_button';

View file

@ -3,10 +3,10 @@ import { PureComponent } from 'react';
import { injectIntl, defineMessages } from 'react-intl';
import { ReactComponent as LockIcon } from '@material-symbols/svg-600/outlined/lock.svg';
import { ReactComponent as LockOpenIcon } from '@material-symbols/svg-600/outlined/lock_open.svg';
import { ReactComponent as MailIcon } from '@material-symbols/svg-600/outlined/mail.svg';
import { ReactComponent as PublicIcon } from '@material-symbols/svg-600/outlined/public.svg';
import LockIcon from '@/material-icons/400-24px/lock.svg?react';
import LockOpenIcon from '@/material-icons/400-24px/lock_open.svg?react';
import MailIcon from '@/material-icons/400-24px/mail.svg?react';
import PublicIcon from '@/material-icons/400-24px/public.svg?react';
import Dropdown from './dropdown';

Some files were not shown because too many files have changed in this diff Show more