Compare commits

..

887 Commits

Author SHA1 Message Date
Penar Musaraj
c8381edf0c
Update Rails to v6.1.7.1 2023-01-23 20:32:19 -05:00
Penar Musaraj
c4ad6659dc
Revert "Update Rails to v6.1.7.1"
This reverts commit d45d9a31ac.
2023-01-23 20:31:38 -05:00
Penar Musaraj
d45d9a31ac
Update Rails to v6.1.7.1 2023-01-23 20:28:19 -05:00
Alan Guo Xiang Tan
df6d323bd1 Version bump to v2.8.14 (#19755) 2023-01-05 10:54:47 +08:00
Alan Guo Xiang Tan
ffc59a3b28 SECURITY: BCC active user emails from group SMTP (#19724)
When sending emails out via group SMTP, if we
are sending them to non-staged users we want
to mask those emails with BCC, just so we don't
expose them to anyone we shouldn't. Staged users
are ones that have likely only interacted with
support via email, and will likely include other
people who were CC'd on the original email to the
group.

Co-authored-by: Martin Brennan <martin@discourse.org>
2023-01-05 10:54:47 +08:00
Alan Guo Xiang Tan
7a47c7b3f1 Revert "SECURITY: BCC active user emails from group SMTP (#19724)"
This reverts commit a09dc2d5c2.
2023-01-05 10:54:47 +08:00
Alan Guo Xiang Tan
2bb31f1ce6 Revert "Version bump to v2.8.14 (#19755)"
This reverts commit 8665f06f63.
2023-01-05 10:54:47 +08:00
Alan Guo Xiang Tan
8665f06f63
Version bump to v2.8.14 (#19755) 2023-01-05 09:56:13 +08:00
Alan Guo Xiang Tan
a09dc2d5c2 SECURITY: BCC active user emails from group SMTP (#19724)
When sending emails out via group SMTP, if we
are sending them to non-staged users we want
to mask those emails with BCC, just so we don't
expose them to anyone we shouldn't. Staged users
are ones that have likely only interacted with
support via email, and will likely include other
people who were CC'd on the original email to the
group.

Co-authored-by: Martin Brennan <martin@discourse.org>
2023-01-05 09:45:30 +08:00
Alan Guo Xiang Tan
1cb5200450 Revert "SECURITY: BCC active user emails from group SMTP (#19724)"
This reverts commit 7bd83ef6b5.
2023-01-05 09:45:30 +08:00
Alan Guo Xiang Tan
c83a7c91d1
SECURITY: Convert send_digest to a post request (#19748)
Co-authored-by: Isaac Janzen <isaac.janzen@discourse.org>
2023-01-05 08:51:39 +08:00
Alan Guo Xiang Tan
fae0cd9f54
SECURITY: use rstrip instead of regex gsub to prevent ReDOS (#19738)
`rstrip` implementation is much more performant than regex

Co-authored-by: Krzysztof Kotlarek <kotlarek.krzysztof@gmail.com>
2023-01-05 08:51:33 +08:00
Alan Guo Xiang Tan
4bf306f0e3
SECURITY: Delete email tokens when a user's email is changed or deleted (#19736)
Co-authored-by: OsamaSayegh <asooomaasoooma90@gmail.com>
2023-01-05 08:51:27 +08:00
Alan Guo Xiang Tan
b9e2e997f4
SECURITY: Check the length of raw post body (#19734)
Co-authored-by: Jarek Radosz <jradosz@gmail.com>
2023-01-05 08:51:21 +08:00
Alan Guo Xiang Tan
66ab2d71ff
SECURITY: escape quotes in tag description when rendering (#19731)
Co-authored-by: Daniel Waterworth <me@danielwaterworth.com>
2023-01-05 08:51:16 +08:00
Alan Guo Xiang Tan
9470ae7190
SECURITY: Don't expose user post counts to users who can't see the topic (#19729)
Co-authored-by: Daniel Waterworth <me@danielwaterworth.com>
Co-authored-by: Penar Musaraj <pmusaraj@gmail.com>
2023-01-05 08:51:10 +08:00
Alan Guo Xiang Tan
06a70d249b
SECURITY: Sanitize PendingPost titles before rendering to prevent XSS (#19727)
Co-authored-by: Daniel Waterworth <me@danielwaterworth.com>
2023-01-05 08:51:00 +08:00
Alan Guo Xiang Tan
7bd83ef6b5
SECURITY: BCC active user emails from group SMTP (#19724)
When sending emails out via group SMTP, if we
are sending them to non-staged users we want
to mask those emails with BCC, just so we don't
expose them to anyone we shouldn't. Staged users
are ones that have likely only interacted with
support via email, and will likely include other
people who were CC'd on the original email to the
group.

Co-authored-by: Martin Brennan <martin@discourse.org>
2023-01-05 08:50:54 +08:00
David Taylor
c77a9f18be
DEV: Use ruby-2.7 for stable branch CI (#19749) 2023-01-05 08:50:22 +08:00
Selase Krakani
fbd6c300d2
SECURITY: Restrict unlisted topic creation (#19258) 2022-12-02 15:55:17 +00:00
Selase Krakani
a65c3ba079
FIX: Fix failing spec caused by unpersisted user instance (#19288)
Active Record's `to_sql` method seems to return an empty string instead
of the expected SQL query when called on a query involving an
unpersisted model instance.

This replaces the admin `user` used in the specs with a persisted instance.
2022-12-02 03:28:05 +00:00
Daniel Waterworth
1fbcf57767
Version bump to v2.8.13 (#19244) 2022-11-29 11:12:55 -06:00
Daniel Waterworth
fdc4984ade SECURITY: Filter tags in user notifications for visibility 2022-11-29 10:36:02 -06:00
Daniel Waterworth
f0b9ce42d6 FIX: When filtering tags for visibility, respect tag group permissions (#19152) 2022-11-29 10:36:02 -06:00
Martin Brennan
27d93b4658
FIX: Backport invite fixes from main (#19218)
Backports the following:

* 40e8912395
* bbcb69461f

Which were showing an error when users were
trying to claim invites multiple times and
a subsequent follow-up fix.
2022-11-28 15:15:00 +10:00
Martin Brennan
15823d4a50
Version bump to v2.8.12 (#19214) 2022-11-28 11:14:35 +10:00
Martin Brennan
131c5cff25
SECURITY: Hide notifications for inaccessible topics (#19209)
Filter notifications the user cannot see anymore
via guardian.can_see_topic_ids
2022-11-28 10:42:05 +10:00
David Taylor
bf30689059 Disable ember-cli-based CI tests for stable branch
The upgrade of node in our discourse_test docker image has caused these to start failing. Ember-cli assets are default-disabled on the stable branch, so there is little need to run these tests.
2022-11-17 14:17:45 +00:00
David Taylor
b25f469018 PERF: Update s3:expire_missing_assets to delete in batches (#18908)
Some sites may have thousands of stale assets - deleting them one-by-one is very slow.

Followup to e8570b5cc9
2022-11-17 14:17:45 +00:00
David Taylor
006a857272 Fix and improve s3:expire_missing_assets task (#18863)
- Ensure it works with prefixed S3 buckets
- Perform a sanity check that all current assets are present on S3 before starting deletion
- Remove the lifecycle rule configuration and delete expired assets immediately. This task should be run post-deploy anyway, so adding a 10-day window is not required
2022-11-17 14:17:45 +00:00
David Taylor
1291fc1afe PERF: Correct should_skip? logic in s3:upload (#18862)
This task is supposed to skip uploading if the asset is already present in S3. However, when a bucket 'folder path' was configured, this logic was broken and so the assets would be re-uploaded every time.

This commit fixes that logic to include the bucket 'folder path' in the check
2022-11-17 14:17:45 +00:00
Daniel Waterworth
c0971b19cb
FIX: Update GitImporter to match main (#18974)
Fixes:

 * An issue where the git url gets updated when it shouldn't,
 * Fetching from gitlab,
2022-11-14 12:28:00 -06:00
Martin Brennan
e67d5f222c
Version bump to v2.8.11 (#19008) 2022-11-14 13:14:01 +10:00
Martin Brennan
aca0f239c8
SECURITY: Prevent email from being nil in InviteRedeemer (#19005)
This commit adds some protections in InviteRedeemer to ensure that email
can never be nil, which could cause issues with inviting the invited
person to private topics since there was an incorrect inner join.

If the email is nil and the invite is scoped to an email, we just use
that invite.email unconditionally.  If a redeeming_user (an existing
    user) is passed in when redeeming an email, we use their email to
override the passed in email.  Otherwise we just use the passed in
email.  We now raise an error after all this if the email is still nil.
This commit also adds some tests to catch the private topic fix, and
some general improvements and comments around the invite code.

This commit also includes a migration to delete TopicAllowedUser records
for users who were mistakenly added to topics as part of the invite
redemption process.
2022-11-14 12:02:09 +10:00
Bianca Nenciu
3a985c82c7
SECURITY: Correctly render link title in draft preview (#18958)
The additional unescaping could cause link titles to be rendered
incorrectly.
2022-11-09 15:54:47 +02:00
David Taylor
ce28fd2e1d
Version bump to v2.8.10 (#18824) 2022-11-01 17:12:07 +00:00
David Taylor
7e4e8c8ad2
SECURITY: Fix invite link validation (stable) (#18818)
See https://github.com/discourse/discourse/security/advisories/GHSA-x8w7-rwmr-w278

Co-authored-by: Martin Brennan <martin@discourse.org>
2022-11-01 16:50:14 +00:00
David Taylor
ec9734bc42
SECURITY: Expand and improve SSRF Protections (stable) (#18816)
See https://github.com/discourse/discourse/security/advisories/GHSA-rcc5-28r3-23rr

Co-authored-by: OsamaSayegh <asooomaasoooma90@gmail.com>
Co-authored-by: Daniel Waterworth <me@danielwaterworth.com>
2022-11-01 16:34:12 +00:00
Alan Guo Xiang Tan
65820e8ac1
SECURITY: Restrict display of topic titles associated with user badges (#18768) (#18770)
Before this commit, we did not have guardian checks in place to determine if a
topic's title associated with a user badge should be displayed or not.
This means that the topic title of topics with restricted access
could be leaked to anon and users without access if certain conditions
are met. While we will not specify the conditions required, we have internally
assessed that the odds of meeting such conditions are low.

With this commit, we will now apply a guardian check to ensure that the
current user is able to see a topic before the topic's title is included
in the serialized object of a `UserBadge`.
2022-10-27 11:48:00 +08:00
Alan Guo Xiang Tan
365eef3a64
DEV: Introduce TopicGuardian#can_see_topic_ids method (#18692) (#18765)
Before this commit, there was no way for us to efficiently check an
array of topics for which a user can see. Therefore, this commit
introduces the `TopicGuardian#can_see_topic_ids` method which accepts an
array of `Topic#id`s and filters out the ids which the user is not
allowed to see. The `TopicGuardian#can_see_topic_ids` method is meant to
maintain feature parity with `TopicGuardian#can_see_topic?` at all
times so a consistency check has been added in our tests to ensure that
`TopicGuardian#can_see_topic_ids` returns the same result as
`TopicGuardian#can_see_topic?`. In the near future, the plan is for us
to switch to `TopicGuardian#can_see_topic_ids` completely but I'm not
doing that in this commit as we have to be careful with the performance
impact of such a change.

This method is currently not being used in the current commit but will
be relied on in a subsequent commit.
2022-10-27 07:46:28 +08:00
Michael Fitz-Payne
29f0bc4ea2 DEV(cache_critical_dns): add caching for MessageBus Redis hostname
We are already caching any DB_HOST and REDIS_HOST (and their
accompanying replicas), we should also cache the resolved addresses for
the MessageBus specific Redis. This is a noop if no MB redis is defined
in config. A side effect is that the MB will also support SRV lookup and
priorities, following the same convention as the other cached services.

The port argument was added to redis_healthcheck so that the script
supports a setup where Redis is running on a non-default port.

Did some minor refactoring to improve readability when filtering out the
CRITICAL_HOST_ENV_VARS. The `select` block was a bit confusing, so the
sequence was made easier to follow.

We were coercing an environment variable to an int in a few places, so
the `env_as_int` method was introduced to do that coercion in one place and
for convenience purposes default to a value if provided.

See /t/68301/30.
2022-10-26 09:22:20 +10:00
Michael Fitz-Payne
bc8ad2a5d2 DEV(cache_critical_dns): add option to run once and exit
There are situations where a container running Discourse may want to
cache the critical DNS services without running the cache_critical_dns
service, for example running migrations prior to running a full bore
application container.

Add a `--once` argument for the cache_critical_dns script that will
only execute the main loop once, and return the status code for the
script to use when exiting. 0 indicates no errors occured during SRV
resolution, and 1 indicates a failure during the SRV lookup.

Nothing is reported to prometheus in run_once mode. Generally this
mode of operation would be a part of a unix pipeline, in which the exit
status is a more meaningful and immediate signal than a prometheus metric.

The reporting has been moved into it's own method that can be called
only when the script is running as a service.

See /t/69597.
2022-10-26 09:22:20 +10:00
Michael Fitz-Payne
7804eb44e6 DOC(cache_critical_dns): add program description
Describes the behaviour and configuration of the cache_critical_dns
script, mainly cribbed from commit messages. Tries to make this program
a bit less of an enigma.
2022-10-26 09:22:20 +10:00
Michael Fitz-Payne
cf86886448 DEV(cache_critical_dns): improve postgres_healthcheck
The `PG::Connection#ping` method is only reliable for checking if the
given host is accepting connections, and not if the authentication
details are valid.

This extends the healthcheck to confirm that the auth details are
able to both create a connection and execute queries against the
database.

We expect the empty query to return an empty result set, so we can
assert on that. If a failure occurs for any reason, the healthcheck will
return false.
2022-10-26 09:22:20 +10:00
Gabe Pacuilla
5340b09ad1 FIX(cache_critical_dns): use correct DISCOURSE_DB_USERNAME envvar (#16862) 2022-10-26 09:22:20 +10:00
Gabe Pacuilla
ab88591536 FIX(cache_critical_dns): use discourse database name and user by default (#16856) 2022-10-26 09:22:20 +10:00
Michael Fitz-Payne
924ef90eed DEV(cache_critical_dns): add SRV priority tunables
An SRV RR contains a priority value for each of the SRV targets that
are present, ranging from 0 - 65535. When caching SRV records we may want to
filter out any targets above or below a particular threshold.

This change adds support for specifying a lower and/or upper bound on
target priorities for any SRV RRs. Any targets returned when resolving
the SRV RR whose priority does not fall between the lower and upper
thresholds are ignored.

For example: Let's say we are running two Redis servers, a primary and
cold server as a backup (but not a replica). Both servers would pass health
checks, but clearly the primary should be preferred over the backup
server. In this case, we could configure our SRV RR with the primary
target as priority 1 and backup target as priority 10. The
`DISCOURSE_REDIS_HOST_SRV_LE` could then be set to 1 and the target with
priority 10 would be ignored.

See /t/66045.
2022-10-26 09:22:20 +10:00
Michael Fitz-Payne
cbf7d16d7c FIX: remove refresh seconds override on cache_critical_dns (#16572)
This removes the option to override the sleep time between caching of
DNS records. The override was invalid because `''.to_i` is 0 in Ruby,
causing a tight loop calling the `run` method.
2022-10-26 09:22:20 +10:00
Michael Fitz-Payne
8293f11f53 FIX: cache_critical_dns - add TLS support for Redis healthcheck
For Redis connections that operate over TLS, we need to ensure that we
are setting the correct arguments for the Redis client. We can utilise
the existing environment variable `DISCOURSE_REDIS_USE_SSL` to toggle
this behaviour.

No SSL verification is performed for two reasons:
- the Discourse application will perform a verification against any FQDN
  as specified for the Redis host
- the healthcheck is run against the _resolved_ IP address for the Redis
  hostname, and any SSL verification will always fail against a direct
  IP address

If no SSL arguments are provided, the IP address is never cached against
the hostname as no healthy address is ever found in the HealthyCache.
2022-10-26 09:22:20 +10:00
Michael Fitz-Payne
971409741f DEV: refactor cache_critical_dns for SRV RR awareness
Modify the cache_critical_dns script for SRV RR awareness. The new
behaviour is only enabled when one or more of the following environment
variables are present (and only for a host where the `DISCOURSE_*_HOST_SRV`
variable is present):
- `DISCOURSE_DB_HOST_SRV`
- `DISCOURSE_DB_REPLICA_HOST_SRV`
- `DISCOURSE_REDIS_HOST_SRV`
- `DISCOURSE_REDIS_REPLICA_HOST_SRV`

Some minor changes in refactor to original script behaviour:
- add Name and SRVName classes for storing resolved addresses for a hostname
- pass DNS client into main run loop instead of creating inside the loop
- ensure all times are UTC
- add environment override for system hosts file path and time between DNS
  checks mainly for testing purposes

The environment variable for `BUNDLE_GEMFILE` is set to enables Ruby to
load gems that are installed and vendored via the project's Gemfile.
This script is usually not run from the project directory as it is
configured as a system service (see
71ba9fb7b5/templates/cache-dns.template.yml (L19))
and therefore cannot load gems like `pg` or `redis` from the default
load paths. Setting this environment variable configures bundler to look
in the correct project directory during it's setup phase.

When a `DISCOURSE_*_HOST_SRV` environment variable is present, the
decision for which target to cache is as follows:
- resolve the SRV targets for the provided hostname
- lookup the addresses for all of the resolved SRV targets via the
  A and AAAA RRs for the target's hostname
- perform a protocol-aware healthcheck (PostgreSQL or Redis pings)
- pick the newest target that passes the healthcheck

From there, the resolved address for the SRV target is cached against
the hostname as specified by the original form of the environment
variable.

For example: The hostname specified by the `DISCOURSE_DB_HOST` record
is `database.example.com`, and the `DISCOURSE_DB_HOST_SRV` record is
`database._postgresql._tcp.sd.example.com`. An SRV RR lookup will return
zero or more targets. Each of the targets will be queried for A and AAAA
RRs. For each of the addresses returned, the newest address that passes
a protocol-aware healthcheck will be cached. This address is cached so
that if any newer address for the SRV target appears we can perform a
health check and prefer the newer address if the check passes.

All resolved SRV targets are cached for a minimum of 30 minutes in memory
so that we can prefer newer hosts over older hosts when more than one target
is returned. Any host in the cache that hasn't been seen for more than 30
minutes is purged.

See /t/61485.
2022-10-26 09:22:20 +10:00
David Taylor
9524c1320a DEV: Include DISCOURSE_REDIS_REPLICA_HOST in cache_critical_dns (#15877)
This is the replacement for DISCOURSE_REDIS_SLAVE_HOST
2022-10-26 09:22:20 +10:00
Alan Guo Xiang Tan
689ba22db0
DEV: Remove harded id when fabricating in tests (#18729) (#18730)
Hardcoding ids always lead to sadness for our test suite
2022-10-25 06:33:36 +08:00
Alan Guo Xiang Tan
6c97cc1834
DEV: Fabricate instead of just building topic, post and user in tests (#18698) (#18717)
Building does not persist the object in the database which is
unrealistic since we're mostly dealing with persisted objects in
production.

In theory, this will result our test suite taking longer to run since we
now have to write to the database. However, I don't expect the increase
to be significant and it is actually no different than us adding new
tests which fabricates more objects.
2022-10-24 07:28:02 +08:00
Jarek Radosz
1503ec07c5
Version bump to v2.8.9 (#18430) 2022-09-29 21:00:32 +02:00
Jarek Radosz
65017fe920
SECURITY: moderator shouldn't be able to import a theme via API (stable) (#18420)
* SECURITY: moderator shouldn't be able to import a theme via API.
* DEV: apply `AdminConstraint` for all the "themes" routes.

Co-authored-by: Vinoth Kannan <svkn.87@gmail.com>
2022-09-29 20:13:34 +02:00
Jarek Radosz
4302097b3b
SECURITY: Prevent arbitrary file write when decompressing files (stable) (#18423)
* SECURITY: Prevent arbitrary file write when decompressing files
* FIX: Allow decompressing files into symlinked directories

Co-authored-by: OsamaSayegh <asooomaasoooma90@gmail.com>
Co-authored-by: Gerhard Schlager <gerhard.schlager@discourse.org>
2022-09-29 20:07:58 +02:00
Martin Brennan
a896a69c50
SECURITY: Limit user profile field length (#18304)
Adds limits to location and website fields at model and DB level to
match the bio_raw field limits. A limit cannot be added at the DB level
for bio_raw because it is a postgres text field.

The migration here uses version `6.1` instead of `7.0` since `stable`
is not on that version of rails yet, otherwise this is the same as `beta`
apart from also removing the new tests which caused too many conflicts.

Co-authored-by: Alan Guo Xiang Tan gxtan1990@gmail.com
2022-09-21 13:49:25 +10:00
Loïc Guitaut
13517cde7e Version bump to 2.8.8 2022-08-10 15:05:39 +02:00
Krzysztof Kotlarek
4fcffd3fae SECURITY: Limit email invitations to topic 2022-08-10 11:47:14 +02:00
Roman Rizzi
7b8f74439e
Version bump to v2.8.7 (#17700) 2022-07-27 17:28:39 -03:00
Roman Rizzi
af1cb735db
SECURITY: Prevent abuse of the update_activation_email route (stable) 2022-07-27 23:09:09 +03:00
Roman Rizzi
7af25544c3
SECURITY: Do not cache error responses for static assets (stable) 2022-07-27 22:58:38 +03:00
David Taylor
f0ef186a4e
FIX: Allow Symbol objects to be deserialized in PostRevision (stable) (#17512)
Followup to bb287c6c74
2022-07-15 13:16:20 +01:00
David Taylor
5d2ecce3f6
FIX: Allow Time objects to be deserialized in PostRevision (stable) (#17502)
Followup to bb287c6c74
2022-07-15 00:17:53 +01:00
David Taylor
c75ec7335d
Version bump to v2.8.6 (#17472) 2022-07-13 12:40:16 +01:00
David Taylor
bb287c6c74
SECURITY: Bump Rails to 6.1.6.1 (stable) (#17470)
https://discuss.rubyonrails.org/t/81017
2022-07-13 11:19:55 +01:00
Gerhard Schlager
3d1bbf7446 FIX: Logout could fail due to cached user
Logging out failed when the current user was cached by an instance of `Auth::DefaultCurrentUserProvider` and `#log_off_user` was called on a different instance of that class.

Co-authored-by: Sam <sam.saffron@gmail.com>
2022-07-04 17:01:45 +02:00
Gerhard Schlager
61ed83ecfc FIX: Incorrect currentUser could be cached for requests with API key (#17279)
This happened when a middleware accessed the `currentUser` before a controller had a chance to populate the `action_dispatch.request.path_parameters` env variable. In that case Discourse would always cache `nil` as `currentUser`.
2022-07-04 17:01:45 +02:00
Penar Musaraj
61cf791929
Version bump to v2.8.5 (#17187) 2022-06-21 15:05:00 -04:00
Daniel Waterworth
7616e9b540
SECURITY: Validate email constraints when trying to redeem an invite (#17182)
In certain situations, a logged in user can redeem an invite with an email that
either doesn't match the invite's email or does not adhere to the email domain
restriction of an invite link. The impact of this flaw is aggrevated
when the invite has been configured to add the user that accepts the
invite into restricted groups.

Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>
2022-06-21 13:25:10 -05:00
Blake Erickson
cf94e52f78
Version bump to v2.8.4 (#17075) 2022-06-13 15:04:02 -06:00
Blake Erickson
918c296fe8
SECURITY: banner-info (#17071) (#17073) 2022-06-13 11:47:44 -06:00
Alan Guo Xiang Tan
036467aac3
FIX: Approves user when redeeming an invite for invites only sites (#16987)
When a site has `SiteSetting.invite_only` enabled, we create a
`ReviewableUser`record when activating a user if the user is not
approved. Therefore, we need to approve the user when redeeming an
invite.

There are some uncertainties surrounding why a `ReviewableRecord` is
created for a user in an invites only site but this commit does not seek
to address that.

Follow-up to 7c4e2d33fa
2022-06-03 14:50:58 +08:00
Alan Guo Xiang Tan
576354072e
DEV: Fix auto start for wizard qunit tests (#16988)
`run-qunit.js` does not expect QUnit tests to start automatically but
our wizard QUnit setup did not respect the `qunit_disable_auto_start`
URL param. Hence, tests would start running automatically and when a
subsequent `QUnit.start()` function call is made, we ended up getting a
`QUnit.start cannot be called inside a test context.` error.

This error can be consistently reproduced in the `discourse:discourse_test` container but not in
the local development environment. I do not know why and did not feel
like it is important at this point in time to know why.
2022-06-03 12:44:42 +08:00
Gerhard Schlager
5c91d9a629
SECURITY: Remove auto approval when redeeming an invite (#16976)
This security fix affects sites which have `SiteSetting.must_approve_users`
enabled. There are intentional and unintentional cases where invited
users can be auto approved and are deemed to have skipped the staff approval process.
Instead of trying to reason about when auto-approval should happen, we have decided that
enabling the `must_approve_users` setting going forward will just mean that all new users
must be explicitly approved by a staff user in the review queue. The only case where users are auto
approved is when the `auto_approve_email_domains` site setting is used.

Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>
2022-06-02 16:11:04 +02:00
David Taylor
a0c141d6ac
FIX: Ensure theme JavaScript cache get consistent SHA1 digest (stable backport) (#16669)
(Stable backport of 7ed899f)

There is a couple of layers of caching for theme JavaScript in Discourse:

The first layer is the `javascript_caches` table in the database. When a theme
with JavaScript files is installed, Discourse stores each one of the JavaScript
files in the `theme_fields` table, and then concatenates the files, compiles
them, computes a SHA1 digest of the compiled JavaScript and store the results
along with the SHA1 digest in the `javascript_caches` table.

Now when a request comes in, we need to render `<script>` tags for the
activated theme(s) of the site. To do this, we retrieve the `javascript_caches`
records of the activated themes and generate a `<script>` tag for each record.
The `src` attribute of these tags is a path to the `/theme-javascripts/:digest`
route which simply responds with the compiled JavaScript that has the requested
digest.

The second layer is a distributed cache whose purpose is to make rendering
`<script>` a lot more efficient. Without this cache, we'd have to query the
`javascript_caches` table to retrieve the SHA1 digests for every single
request. So we use this cache to store the `<script>` tags themselves so that
we only have to retrieve the `javascript_caches` records of the activated
themes for the first request and future requests simply get the cached
`<script>` tags.

What this commit does it ensures that the SHA1 digest in the
`javascript_caches` table stay the same across compilations by adding an order
by id clause to the query that loads the `theme_fields` records. Currently, we
specify no order when retrieving the `theme_fields` records so the order in
which they're retrieved can change across compilations and therefore cause the
SHA1 to change even though the individual records have not changed at all.

An inconsistent SHA1 digest across compilations can cause the database cache
and the distributed cache to have different digests and that causes the
JavaScript to fail to load (and if the theme heavily customizes the site, it
gives the impression that the site is broken) until the cache is cleared.

This can happen in busy sites when 2 concurrent requests recompile the
JavaScript files of a theme at the same time (this can happen when deploying a
new Discourse version) and request A updates the database cache after request B
did, and request B updates the distributed cache after request A did.

Internal ticket: t60783.

Co-authored-by: David Taylor <david@taylorhq.com>
Co-authored-by: Osama Sayegh <asooomaasoooma90@gmail.com>
2022-05-06 11:10:40 +01:00
David Taylor
d8b68e00c9
FIX: Ensure values are escaped in select-kit dropdowns (#16586)
The values in Discourse dropdown menus only come from admin-defined strings, not unsanitised end-user input, so this lack of escaping was not exploitable.
2022-04-28 16:31:41 +01:00
Penar Musaraj
bb57be95f0 DEV: Cleanup body.scrollTop usage (#16445)
All current browser treat the HTML document (not the body element) as
the scrollable document element. Hence in all current browsers,
`document.body.scrollTop` returns 0. This commit removes all usage of
this property, because it is effectively 0.

Co-authored-by: David Taylor <david@taylorhq.com>
2022-04-14 12:45:34 -04:00
Penar Musaraj
9a9a29b24b FIX: Buggy topic scrolling on iOS 12 (#16422) 2022-04-14 12:45:34 -04:00
Penar Musaraj
a9a643bcdc
Version bump to v2.8.3 2022-04-14 10:08:37 -04:00
David Taylor
b72b0dac10
SECURITY: Ensure user-agent-based responses are cached separately (stable) (#16476) 2022-04-14 14:26:00 +01:00
Alan Guo Xiang Tan
3ac1b3a5c9 SECURITY: Update Nokogiri to 1.13.4.
Nokogiri 1.13.4 updates zlib to 1.2.12 to address CVE-2018-25032.

https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-v6gp-9mmm-c6p5
https://nvd.nist.gov/vuln/detail/CVE-2018-25032
2022-04-12 15:19:46 +08:00
Jarek Radosz
6bbc822495 DEV: Don't check this.element in @afterRender (#16033)
This would allow to use the decorator in tag-less components and in controllers.
2022-04-11 13:03:54 +08:00
Alan Guo Xiang Tan
72c69a644f DEV: Add pretender endpoint for category visible groups.
This was causing our build to become flaky.
2022-04-11 13:03:54 +08:00
Alan Guo Xiang Tan
3d581ce159 SECURITY: Category group permissions leaked to normal users.
After this commit, category group permissions can only be seen by users
that are allowed to manage a category. In the past, we inadvertently
included a category's group permissions settings in `CategoriesController#show`
and `CategoriesController#find_by_slug` endpoints for normal users when
those settings are only a concern to users that can manage a category.
2022-04-08 11:04:59 +02:00
Bianca Nenciu
dcbd788412 FIX: Serialize permissions for everyone group
The permissions for the 'everyone' group were not serialized because
the list of groups a user can view did not include it. This bug was
introduced in commit dfaf9831f7.
2022-04-08 11:04:59 +02:00
Martin Brennan
f0574564c4 DEV: Fix failing share topic tests (#16309)
Since 3fd7b31a2a some tests
were failing with this error:

> Error: Unhandled request in test environment: /c/feature/find_by_slug.json
> (GET) at http://localhost:7357/assets/test-helpers.js

This commit fixes the issue by adding the missing pretender. Also
noticed while fixing this that the parameter for the translation
was incorrect -- it was `group` instead of `groupNames`, so that
is fixed here too, along with moving the onShow functions into
@afterRender decorated private functions. There is no need for the
appevent listeners.
2022-04-08 11:04:59 +02:00
Bianca Nenciu
1516dd75f5 FIX: Show restricted groups warning when necessary (#16236)
It was displayed for the "everyone" group too, but that was not
necessary.
2022-04-08 11:04:59 +02:00
Alan Guo Xiang Tan
7b5ef41a43 DEV: Restore order assertion in category serializer tests. (#16344)
Our group fabrication creates groups with name "my_group_#{n}" where n
is the sequence number of the group being created. However, this can
cause the test to be flaky if and when a group with name `my_group_10`
is created as it will be ordered before
`my_group_9`. This commits makes the group names determinstic to
eliminate any flakiness.

This reverts commit 558bc6b746.
2022-04-01 09:17:58 +08:00
David Taylor
62cde96c70 DEV: Fix flaky specs (#16340)
`group_permissions` are not serialized in a consistent order

Follow-up to dfaf9831f7
2022-04-01 09:17:58 +08:00
Alan Guo Xiang Tan
09e7dd00b8
SECURITY: Avoid leaking private group name when viewing category. (#16339)
In certain instances when viewing a category, the name of a group with
restricted visilbity may be revealed to users which do not have the
required permission.
2022-03-31 15:07:48 +08:00
Martin Brennan
bd0f10a50b
SECURITY: Hide private categories in user activity export (#16276)
In some of the user's own activity export data,
we sometimes showed a secure category's name or
exposed the existence of a secure category.
2022-03-24 15:56:50 +10:00
Neil Lalonde
74ce2fe2e7
Version bump to v2.8.2 2022-03-22 14:51:41 -04:00
Alan Guo Xiang Tan
79da89fd06
DEV: Don't load bundler when installing plugin gem. (#16176)
when bundler is loaded, it sets the `RUBYOPT` environment variable to setup bundler. However, it was causing weird errors like the following when we try to install
custom plugin gems into a specific directory.

```
/home/tgxworld/.asdf/installs/ruby/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.5/lib/bundler/source/git.rb:214:in `rescue in load_spec_files': https://github.com/discourse/mail.git is not yet checked out. Run `bundle install` first. (Bundler::GitError)
	from /home/tgxworld/.asdf/installs/ruby/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.5/lib/bundler/source/git.rb:210:in `load_spec_files'
	from /home/tgxworld/.asdf/installs/ruby/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.5/lib/bundler/source/path.rb:107:in `local_specs'
	from /home/tgxworld/.asdf/installs/ruby/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.5/lib/bundler/source/git.rb:178:in `specs'
	from /home/tgxworld/.asdf/installs/ruby/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.5/lib/bundler/lazy_specification.rb:88:in `__materialize__'
	from /home/tgxworld/.asdf/installs/ruby/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.5/lib/bundler/spec_set.rb:75:in `block in materialize'
	from /home/tgxworld/.asdf/installs/ruby/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.5/lib/bundler/spec_set.rb:72:in `map!'
	from /home/tgxworld/.asdf/installs/ruby/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.5/lib/bundler/spec_set.rb:72:in `materialize'
	from /home/tgxworld/.asdf/installs/ruby/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.5/lib/bundler/definition.rb:468:in `materialize'
	from /home/tgxworld/.asdf/installs/ruby/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.5/lib/bundler/definition.rb:190:in `specs'
	from /home/tgxworld/.asdf/installs/ruby/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.5/lib/bundler/definition.rb:238:in `specs_for'
	from /home/tgxworld/.asdf/installs/ruby/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.5/lib/bundler/runtime.rb:18:in `setup'
	from /home/tgxworld/.asdf/installs/ruby/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.5/lib/bundler.rb:151:in `setup'
	from /home/tgxworld/.asdf/installs/ruby/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.5/lib/bundler/setup.rb:20:in `block in <top (required)>'
	from /home/tgxworld/.asdf/installs/ruby/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.5/lib/bundler/ui/shell.rb:136:in `with_level'
	from /home/tgxworld/.asdf/installs/ruby/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.5/lib/bundler/ui/shell.rb:88:in `silence'
	from /home/tgxworld/.asdf/installs/ruby/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.5/lib/bundler/setup.rb:20:in `<top (required)>'
	from /home/tgxworld/.asdf/installs/ruby/2.7.5/lib/ruby/site_ruby/2.7.0/rubygems/core_ext/kernel_require.rb:85:in `require'
	from /home/tgxworld/.asdf/installs/ruby/2.7.5/lib/ruby/site_ruby/2.7.0/rubygems/core_ext/kernel_require.rb:85:in `require'
```
2022-03-18 11:27:20 +08:00
Alan Guo Xiang Tan
43c744cdc8
DEV: Pull compatible version for plugins in Github test workflow. (#16212)
We have 3 branches which we care about, main, beta and stable.
However, each of this branch has different compatibilties with plugins
and we want to respect that.
2022-03-18 10:30:43 +08:00
Alan Guo Xiang Tan
1d2654f91f
DEV: Backport Github test workflow to stable. (#16210) 2022-03-17 14:02:45 +08:00
David Taylor
d7b48d0229
FIX: Handle nil values in DistributedCache#defer_get_set (stable) (#15980)
Themes often cache `nil` values in a DistributedCache. This bug meant that we were re-calculating some values on every request, AND triggering message-bus publishing on every request.

This fix should provide a significant performance improvement for busy sites.
2022-02-18 08:51:14 +00:00
Andrei Prigorshnev
2c8f62e271
FIX: backport caret moves to a wrong position when uploading an image via toolbar (#15865)
* FIX: Caret moves to a wrong position when uploading an image via toolbar

* Skip the test
2022-02-17 13:44:21 +11:00
Bianca Nenciu
0674d07cdf
FIX: Defer upload extension check for iOS (#15890)
accept HTML attribute is not fully supported on iOS yet and can contain
only MIME types. This changes the input to allow all files and the
extension check is performed later in JavaScript.
2022-02-15 19:57:58 +02:00
communiteq
247f70f79c
Fix bug regarding Chat on stable (#15954) 2022-02-15 12:40:48 -05:00
Krzysztof Kotlarek
cb9678ed34 Version bump to v2.8.1 2022-02-14 17:17:31 +11:00
Krzysztof Kotlarek
76195216ff SECURITY: Onebox response timeout and size limit (#15927)
Validation to ensure that Onebox request is no longer than 10 seconds and response size is not bigger than 1 MB
2022-02-14 12:13:22 +11:00
Dan Ungureanu
0b4e16aa2d
FEATURE: RS512, RS384 and RS256 COSE algorithms (#15868)
* FEATURE: RS512, RS384 and RS256 COSE algorithms

These algorithms are not implemented by cose-ruby, but used in the web
authentication API and were marked as supported.

* FEATURE: Use all algorithms supported by cose-ruby

Previously only a subset of the algorithms were allowed.
2022-02-09 13:56:45 +02:00
David Taylor
1cfe5b5c26
Update translations (stable) (#15819)
Combination of 0dfaaf49a5 and 022480b461

Co-authored-by: Discourse Translator Bot <discourse.translator.bot@gmail.com>
2022-02-04 17:00:25 +00:00
Martin Brennan
7dd9dd848a
FIX: Table pasting issues with uppy (#15787) (#15812)
When changing to uppy for file uploads we forgot to add
these conditions to the paste event from 9c96511ec4

Basically, if you are pasting more than just a file (e.g. text,
html, rtf), then we should not handle the file and upload it, and
instead just paste in the text. This causes issues with spreadsheet
tools, that will copy the text representation and also an image
representation of cells to the user's clipboard.

This also moves the paste event for composer-upload-uppy to the
element found by the `editorClass` property, so it shares the paste
event with d-editor (via TextareaTextManipulation), which makes testing
this possible as the ember paste bindings are not picked up unless both
paste events are on the same element.
2022-02-04 11:44:30 +11:00
Penar Musaraj
be72ae8c49
A11Y: Switch to using autocomplete="off" (#15802) 2022-02-03 17:45:25 +01:00
Natalie Tay
2d7e2b3810
FIX: Only block domains at the final destination (#15689) (#15783)
In an earlier PR, we decided that we only want to block a domain if 
the blocked domain in the SiteSetting is the final destination (/t/59305). That 
PR used `FinalDestination#get`. `resolve` however is used several places
 but blocks domains along the redirect chain when certain options are provided.

This commit changes the default options for `resolve` to not do that. Existing
users of `FinalDestination#resolve` are
- `Oneboxer#external_onebox`
- our onebox helper `fetch_html_doc`, which is used in amazon, standard embed 
and youtube
  - these folks already go through `Oneboxer#external_onebox` which already
  blocks correctly
2022-02-03 09:42:06 +08:00
Martin Brennan
7979708f17
DEV: Remove jQuery UI vendor dependencies (#15782)
Combines 68fe6903f7 and
7b7e707fa2.

We no longer use jQuery UI for anything since getting
rid of jQuery file uploader in 667a8a6,
so we can safely remove these now.

Also removes the blueimp-file-upload and jquery.iframe-transport
dependencies that were formerly used by jQuery file uploader
2022-02-03 11:19:50 +10:00
Neil Lalonde
3a5b75435e
Version bump to v2.8.0 2022-01-27 10:22:23 -05:00
Neil Lalonde
9830b192f3
Merge diffs from main 2022-01-27 10:12:37 -05:00
Neil Lalonde
42caef4719
Merge main 2022-01-27 10:10:35 -05:00
Neil Lalonde
3a126c134e
Version bump to v2.7.13 2022-01-13 10:16:51 -05:00
Dan Ungureanu
c7a6d9bc3a
SECURITY: Do not sign in unapproved users (#15552) 2022-01-13 10:42:48 +02:00
David Taylor
909de9b36c
FIX: Bypass service worker on the SSO path (#15558) (#15560)
This is a workaround a behavior change in Chromium v97.
The following text was sent to the blink-dev mailing list:

> This change broke a SingleSignOn login on the FOSS software Discourse. We have a flow like:
>
> 1. User visits forum.siteA.com, click login
> 2. Gets redirected to idp.siteB.com
> 3. Fills login details
> 4. Gets redirected to forum.siteA.com/session/sso_login?parameters
> 5. Gets redirected to forum.siteA.com/homepage
>
> On step 4, the response includes a `set-cookie` header, with proper `HttpOnly; SameSite=Lax; Secure `and set. But if there is an active service worker, the login will fail as that cookie will be rejected by Chromium due to SameSite rules now.
>
> t=2971 [st=258]        COOKIE_INCLUSION_STATUS
>                        --> domain = "forum.siteA.com"
>                        --> name = "_t"
>                        --> operation = "store"
>                        --> path = "/"
>                        --> status = "EXCLUDE_SAMESITE_LAX, DO_NOT_WARN"
>
> The service worker is a vanilla WorkboxJS service worker that intercepts all GETs with the "Network First" strategy.
>
> Disabling the service worker or using Firefox results in a successful login. There is no warning in either DevTools network tab nor the console that the cookie was rejected.
>
> Chrome 96: login works
> Chrome 97: login does not work
> Chrome 98: login does not work
>
> Is this expected behavior? Even if the request `GET forum.siteA.com` was initiated because of a redirect from a different domain, is it expected that Chrome will silently drop same site cookies from forum.siteA.com?

Co-authored-by: Rafael dos Santos Silva <xfalcox@gmail.com>
2022-01-13 00:08:33 +00:00
David Taylor
5cfe42474a
FIX: LOAD_PLUGINS=0 in dev/prod, warn in plugin:pull_compatible_all (stable) (#15538)
The `plugin:pull_compatible_all` task is intended to take incompatible plugins and downgrade them to an earlier version. Problem is, when running the rake task in development/production environments, the plugins have already been activated. If an incompatible plugin raises an error in `plugin.rb` then the rake task will be unable to start.

This commit centralises our LOAD_PLUGINS detection, adds support for LOAD_PLUGINS=0 in dev/prod, and adds a warning to `plugin:pull_compatible_all` if it's run with plugins enabled.
2022-01-11 12:30:38 +00:00
Alan Guo Xiang Tan
a09778aba9 SECURITY: Advanced group search did not respect visiblity of groups. 2022-01-10 13:49:45 +08:00
Bianca Nenciu
9a97ce1899
SECURITY: Hide user's bio if profile is restricted (#15448)
The bio was sometimes visible in the meta tags even though it it should
not have been.
2022-01-07 14:19:48 +02:00
Arpit Jalan
75fa5ee748 SECURITY: only show user suggestions with regular post (#15436) 2022-01-03 13:56:46 +05:30
Neil Lalonde
81b398030e
Version bump to v2.7.12 2021-12-21 13:27:14 -05:00
Alan Guo Xiang Tan
7a8ec129fb SECURITY: Disable MessageBus::Diagnostics.
MessageBus::Diagnostics allows anyone with access to carry out certain
operations that may result in a denial of service. The impact of this is
greater on multisiite clusters.
2021-12-17 14:45:13 +08:00
Neil Lalonde
30bc65af70
Version bump to v2.7.11 2021-12-01 11:45:57 -05:00
David Taylor
0c6b9df77b
FIX: Validate number of votes allowed per poll per user (stable) (#15158)
Backport of 1d0faedfbc
2021-12-01 16:42:39 +00:00
David Taylor
982f23e1f2
SECURITY: Remove ember-cli specific response from application routes (stable) (#15154)
Under some conditions, these varied responses could lead to cache poisoning, hence the 'security' label.

For the stable branch, we are disabling the use of Ember CLI against production sites. A new implementation has been added to the tests-passed/beta branches
2021-12-01 16:02:45 +00:00
Natalie Tay
cdaf7f4bb3
SECURITY: Only show tags to users with permission (#15148) 2021-12-01 10:33:10 +08:00
Martin Brennan
715d4de981
SECURITY: Strip unrendered unicode bidirectional chars in code blocks (#15032)
When rendering the markdown code blocks we replace the
offending characters in the output string with spans highlighting a textual
representation of the character, along with a title attribute with
information about why the character was highlighted.

The list of characters stripped by this fix, which are the bidirectional
characters considered relevant, are:

U+202A
U+202B
U+202C
U+202D
U+202E
U+2066
U+2067
U+2068
U+2069
2021-11-22 10:46:07 +10:00
Neil Lalonde
626a0e207e
Version bump to v2.7.10 2021-11-15 11:18:57 -05:00
David Taylor
73f64b8299
SECURITY: Ensure _forum_session cookies cannot be reused between sites (stable) (#14949)
This only affects multisite Discourse instances (where multiple forums are served from a single application server). The vast majority of self-hosted Discourse forums do not fall into this category.

On affected instances, this vulnerability could allow encrypted session cookies to be re-used between sites served by the same application instance.
2021-11-15 15:50:17 +00:00
David Taylor
2da0001965
SECURITY: Disallow caching of MIME/Content-Type errors (#14939)
This will sign intermediary proxies and/or misconfigured CDNs to not
cache those error responses.

Co-authored-by: Rafael dos Santos Silva <xfalcox@gmail.com>
2021-11-15 12:02:56 +00:00
Neil Lalonde
a1dcf3a50c
Version bump to v2.7.9 2021-10-20 17:24:11 -04:00
David Taylor
fa3c46cf07
SECURITY: Improve validation of SNS subscription confirm (#14672)
An upstream validation bug in the aws-sdk-sns library could enable RCE under certain circumstances. This commit updates the upstream gem, and adds additional validation to provide defense-in-depth.
2021-10-20 22:20:35 +01:00
Bianca Nenciu
98b0621d53 SECURITY: Escape watched word in error message (#14434) 2021-09-24 13:38:05 +03:00
Neil Lalonde
18b6f4ecf6
Version bump to v2.7.8 2021-09-01 13:18:17 -04:00
Blake Erickson
7cd207761a
SECURITY: escape cat name (#14155) 2021-08-25 18:14:10 -06:00
Alan Guo Xiang Tan
c6ef6632c6 SECURITY: User's read state for topic is leaked to unauthorized clients.
A user's read state for a topic such as the last read post number and the notification level is exposed.
2021-08-12 12:44:39 +08:00
jbrw
d11b6751bb
SECURITY: Destroy EmailToken when EmailChangeRequest is destroyed (#13950) 2021-08-06 19:27:09 -04:00
Bianca Nenciu
4c748f7f54 SECURITY: Sanitize d-popover attributes (#13958) 2021-08-05 16:40:48 +03:00
Neil Lalonde
b47c5f69d8
Version bump to v2.7.7 2021-07-23 10:53:32 -04:00
Alan Guo Xiang Tan
cc7b8d5f9f
DEV: Make rubocop happy. 2021-07-23 16:39:39 +08:00
Alan Guo Xiang Tan
dbdf61196d
SECURITY: Don't leak user of previous whisper post when deleting a topic.
A topic's last poster can be incorrectly set to a user of a whisper post
if the whisper post is before the last post and the last post is
deleted.
2021-07-23 16:39:37 +08:00
Alan Guo Xiang Tan
680024f907
SECURITY: Do not reveal post whisperer in personal messages.
Prior to this fix, post whisperer in personal messages are revealed in
the topic's participants list even though non-staff users are unable to
see the whisper.
2021-07-23 16:39:29 +08:00
Neil Lalonde
ae224045a6
Version bump to v2.7.6 2021-07-15 14:37:25 -04:00
David Taylor
ad7c7f819d
SECURITY: Sanitize YouTube Onebox data (stable) (#13749)
CVE-2021-32764
2021-07-15 19:32:47 +01:00
Neil Lalonde
a94a623009
Version bump to v2.7.5 2021-07-08 09:43:45 -04:00
Arpit Jalan
d54f7c1f42 SECURITY: do not follow canonical links 2021-07-07 14:11:32 +05:30
Bianca Nenciu
6a7e628037 FIX: TL4 users cannot delete others posts (#13554) 2021-07-06 12:11:29 +03:00
Joffrey JAFFEUX
023f5ae8e0
SECURITY: prevents onebox to hang too long on connect (#13481) 2021-06-22 17:19:13 +02:00
Penar Musaraj
fe1e1903eb
Version bump to v2.7.4 2021-06-09 14:00:41 -04:00
Robin Ward
db826335e9
DEV: Add support for class properties in babel (#13189)
This allows us to start using JS classes instead of Ember's classes.
2021-06-09 13:53:43 -04:00
Penar Musaraj
cf8610cee1
DEV: Enable optional chaining in all contexts (#13180)
* Revert "FIX: We can't use `?.` yet (#13168)"
2021-06-09 13:52:30 -04:00
Neil Lalonde
859dfac6c6
Version bump to v2.7.3 2021-06-08 11:36:25 -04:00
Régis Hanol
98f92d2e23 SECURITY: XSS in bookmarks list (#13311)
We should use `fancy_title` instead of `title` when displaying a topic title to ensure only the allowed html is not escaped.
2021-06-07 16:59:12 +02:00
Neil Lalonde
81070b323f
Version bump to v2.7.2 2021-06-04 11:23:14 -04:00
Sam
5db39cce93
UX: unconditionally focus modals (#13179)
Previously auto focus would only work on modals that include buttons or
inputs.

To avoid a situation where information modals such as keyboard shortcuts
do not get focus, simply focus on the close button as a fallback.
2021-06-04 10:35:12 -04:00
Robin Ward
45dca791b0
UX: Add auto focus to hamburger and user menu dropdowns (#13165) 2021-06-04 10:35:04 -04:00
Bianca Nenciu
8170563693
FIX: Make poll options tabbable (#13159) 2021-06-04 10:34:49 -04:00
Sam
22e9acc797
UX: Improve navigation on topic lists for screen readers (#13153)
Previously we had no role set for various topic links, nor did we have any
headers.

This teaches screen readers that topic links in topic lists are to be treated
as H2. We opted for this less radical change cause a change of the element
type would probably result in many broken themes.

Confirmed on NVDA you can very quickly breeze through topic lists now. Minor
edge case is pinned topics which can be a bit annoying due to multiple links.
2021-06-04 10:34:40 -04:00
Sam
d444a8a400
UX: provide a region for various topic actions (#13152)
This makes it much easier to reply to topics / bookmark topics and so on

Previously topic buttons had no region
2021-06-04 10:34:31 -04:00
Robin Ward
16e1ea938c
FIX: Better focus support for modals (#13147) 2021-06-04 10:34:20 -04:00
Sam
873eb405cd
UX: add ARIA region role to posts (#13130)
NVDA does not detect HTML5 articles as regions. This explicitly sets a
region with an aria-label denoting post numbers making it much easier to
know where you are in a topic.

Note role: article which is more semantically correct is not respected by
NVDA d/D shortcut, hence the much more generic "region" role.
2021-06-04 10:34:13 -04:00
Kris
8e0a669aa5
A11Y: Fix post control and user-menu focus styles (#13118) 2021-06-04 10:34:05 -04:00
dependabot[bot]
2674078b97
Build(deps): Bump nokogiri from 1.11.4 to 1.11.5 (#13107)
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.11.4 to 1.11.5.
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.11.4...v1.11.5)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-06-04 10:33:57 -04:00
Kris
bb59e4ca61
UX: Fix theme upload width, remove class clash, prettier (#13071)
* UX: fix width & theme upload modal class clash

* remove unneeded class

* unprettier hbs

* add back unicode emoji

* add newline
2021-06-04 10:33:49 -04:00
dependabot[bot]
d803095451
Build(deps): Bump nokogiri from 1.11.3 to 1.11.4 (#13074)
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.11.3 to 1.11.4.
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.11.3...v1.11.4)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-06-04 10:33:40 -04:00
Neil Lalonde
8562c1d098
Version bump to v2.7.1 2021-06-03 14:55:45 -04:00
Penar Musaraj
7d06980cc5
SECURITY: Do not allow unauthorized access to category edit UI (#13252) 2021-06-03 14:35:27 -04:00
Penar Musaraj
5f5301d478
FIX: Close hyperlink modal on ESC key (#13166) 2021-06-03 14:35:00 -04:00
Penar Musaraj
f8bab65425
FIX: Disable lightboxing of animated images (#13099) 2021-06-03 14:34:36 -04:00
Neil Lalonde
ccf207f12e
Version bump to v2.7.0 2021-05-18 14:28:06 -04:00
Neil Lalonde
2c399a84fe
Merge master 2021-05-18 14:09:54 -04:00
Neil Lalonde
f73cdbbd2f
Version bump to v2.6.7 2021-05-10 10:29:43 -04:00
David Taylor
23ac6fc5e0
SECURITY: Bump Rails to 6.0.3.7 (#12965)
This includes fixes for:
- CVE-2020-8264
- CVE-2021-22881
- CVE-2021-22885
- CVE-2021-22904
- CVE-2021-22902
2021-05-06 13:37:13 +01:00
Neil Lalonde
e34c29aa7f
Version bump to v2.6.6 2021-04-29 11:26:20 -04:00
Bianca Nenciu
14e53c59b2
FIX: Gracefully handle inline images in emails (#12855) 2021-04-29 10:38:49 +03:00
Bianca Nenciu
1525653dff
FIX: Replace use of regular expression (#12838)
It used a regular expression to check if message IDs were in RFC format.
2021-04-27 17:13:13 +03:00
Neil Lalonde
f8562d8d2f
Version bump to v2.6.5 2021-04-14 11:01:26 -04:00
David Taylor
a19152f3be
SECURITY: Improve theme git import (#12695) 2021-04-14 15:32:33 +01:00
Sam
5b99cb9275
FIX: automatically timeout long running image magick commands (#12670)
Previously certain images may lead to convert / identify to run for unreasonable
amounts of time

This adds a maximum amount of time these commands can run prior to forcing
them to stop
2021-04-12 14:04:37 +03:00
Neil Lalonde
3aa9ae08c2
Version bump to v2.6.4 2021-04-07 12:22:59 -04:00
David Taylor
5dbac4e58e
FIX: Add platforms to stable Gemfile (#12479)
There are a few issues which require us to do this:
 - We install the latest version of bundler on every rebuild. Therefore we're running 2.2.15 everywhere, even for 'stable' clusters
 - Bundler has changed how gem platforms are managed. That meant that on the stable branch we were building libv8 from source via the 'ruby' package, rather than using the precompiled x86_64-linux binary
 - Building the libv8 from source is currently failing

 Together, these things mean that builds of `stable` are currently failing. Each of the above issues should likely be fixed, but this commit provides the quickest route to get things working again. Note that despite the Gemfile.lock update, no gem versions have changed.
2021-03-22 18:54:17 +00:00
Martin Brennan
3ef594b1f1
SECURITY: Fix is_private_ip for RateLimiter to cover all cases (#12464)
The regular expression to detect private IP addresses did not always detect them successfully.
Changed to use ruby's in-built IPAddr.new(ip_address).private? method instead
which does the same thing but covers all cases.
2021-03-22 14:04:55 +10:00
Neil Lalonde
7b283b5f21
Version bump to v2.6.3 2021-03-04 14:08:53 -05:00
jbrw
53f01874bd
FIX: NewPostManager should respect category_group_moderator settings (#12116)
NewPostManager’s `post_needs_approval_in_its_category` method should allow category group moderators to create topics/reply to topics that where they have appropraite permissions.

(ie, if a user has permission to moderate a post, any posts made by them shouldn’t be sent to moderation)
2021-02-24 13:54:54 -05:00
Neil Lalonde
eb9f15a94a
Version bump to v2.6.2 2021-02-18 12:53:47 -05:00
David Taylor
5489a1c4d9
SECURITY: Attach DiscourseConnect (SSO) nonce to current session (#12124) 2021-02-18 10:57:36 +00:00
Arpit Jalan
a4a37b671a FIX: process new invites when existing users are already group members (#11971)
If a list of email addresses is pasted into a group’s Add Members form
that has one or more email addresses of users who already belong to the
group and all other email addresses are for users who do not yet exist
on the forum then no invites were being sent. This commit ensures that
we send invites to new users.
2021-02-05 10:04:35 +05:30
Martin Brennan
946f4b82fa
DEV: Move logic for rate limiting user second factor to one place (#11941)
This moves all the rate limiting for user second factor (based on `params[:second_factor_token]` existing) to the one place, which rate limits by IP and also by username if a user is found.
2021-02-04 09:06:11 +10:00
Robin Ward
98f775506d
SECURITY: Rate limit MFA by login if possible (#11938)
This ensures we rate limit on logins where possible, we also normalize logins for the rate limiters centrally.
2021-02-03 10:32:08 +11:00
Neil Lalonde
d8627cf43f
Version bump to v2.6.1 2021-01-21 14:13:35 -05:00
Arpit Jalan
5130f73bad Bump onebox gem to 2.2.1
- do not show title only oneboxes
- allow oneboxes with title and image
2020-12-24 11:14:21 +05:30
Rafael dos Santos Silva
3a4bd80d8a
FIX: Autoplay videos must always be muted (#11533)
This automatically adds the muted attribute if it's missing in a video
tag.

Co-authored-by: David Taylor <david@taylorhq.com>
2020-12-21 18:09:41 -03:00
Neil Lalonde
d6121249d3
Version bump to v2.6.0 2020-11-30 16:48:47 -05:00
Neil Lalonde
a502a47197
Merge diffs from master 2020-11-30 16:42:54 -05:00
Neil Lalonde
fef0a0c429
Merge master 2020-11-30 16:41:58 -05:00
Sam
225d94d8b8
FIX: correct cdn path (#11324)
This was a typo in a118ec13
2020-11-24 14:17:55 +11:00
Sam
27440ec561
FIX: stop including GlobalPath in default context (#11323)
We do not want these method names to clash, instead encapsulate the helpers
so we do not add methods to Kernel

Correct a but exposed by Ruby 2.7
2020-11-24 14:17:50 +11:00
Neil Lalonde
8a143ebbf8
Version bump to v2.5.5 2020-11-19 10:24:50 -05:00
Dan Ungureanu
8eff1b3a13
FIX: Add dummy themes:update task (#11262) 2020-11-17 11:45:49 +02:00
David Taylor
bacf7966fe
FIX: Remove 4 month limit on IgnoredUser records (#11105)
b8c676e7 added the 'forever' option to the UI, and this is correctly stored in the database. However, we had a hard-coded limit of 4 months in the cleanup job. This commit removes the limit, so ignores can last forever.
2020-11-03 12:31:13 +00:00
Neil Lalonde
77cef20952
Version bump to v2.5.4 2020-10-30 10:28:00 -04:00
Martin Brennan
c7cefb8e08
FIX: Prevent slow bookmark first post reminder at query for topic (#11024)
On forums with a large amount of posts when a user had a bookmark in the topic, PostgreSQL was using an inefficient query plan to fetch the first post of the topic. When running this ActiveRecord query:

```
topic.posts.with_deleted.where(post_number: 1).first
```

The following query plan was produced:

```
 Limit  (cost=0.43..583.49 rows=1 width=891) (actual time=3850.515..3850.515 rows=1 loops=1)
   ->  Index Scan using posts_pkey on posts  (cost=0.43..391231.51 rows=671 width=891) (actual time=3850.514..3850.514
rows=1 loops=1)
         Filter: ((topic_id = 160918) AND (post_number = 1))
         Rows Removed by Filter: 2274520
 Planning time: 0.200 ms
 Execution time: 3850.559 ms
(6 rows)
```

The issue here is the combination of ORDER BY and LIMIT causing the ineficcient Index Scan using posts_pkey on posts to be used. When we correct the AR call to this:

```
topic.posts.with_deleted.find_by(post_number: 1)
```

We end up with a query that still has a LIMIT but no ORDER BY, which in turn creates a much more efficient query plan:

```
Limit  (cost=0.43..1.44 rows=1 width=891) (actual time=0.033..0.034 rows=1 loops=1)
   ->  Index Scan using index_posts_on_topic_id_and_post_number on posts  (cost=0.43..678.82 rows=671 width=891) (actua
l time=0.033..0.033 rows=1 loops=1)
         Index Cond: ((topic_id = 160918) AND (post_number = 1))
 Planning time: 0.167 ms
 Execution time: 0.072 ms
(5 rows)
```

This query plan uses the correct index, `Index Scan using index_posts_on_topic_id_and_post_number on posts`. Note that this is only a problem on forums with a larger amount of posts; tiny forums would not notice the difference. On large forums a query for a topic that takes 1s without a bookmark can take 8-30 seconds, and even end up with 502 errors from nginx.
2020-10-27 16:15:32 +10:00
Neil Lalonde
1829ca605e
Version bump to v2.5.3 2020-10-15 09:50:52 -04:00
Martin Brennan
f6b62919d2
FIX: Confirm new email not sent for staff if email disabled with "non-staff" option (#10794)
See https://meta.discourse.org/t/email-address-change-confirmation-email-not-sent-but-every-other-notification-emails-are/165358

In short: with disable emails set to non-staff, email address change confirmation emails (those sent to the new address) are not sent for staff or admin members.

This was happening because we were looking up the staff user with the to_address of the email, but the to address was the new email address because we are sending a confirm email change email, and thus the user could not be found. We didn't need to do this anyway because we are passing the user into the Email::Sender class anyway.
2020-10-08 14:18:33 +10:00
Roman Rizzi
b9cd5ed62a
SECURITY: Ensure users can see the topic before setting a topic timer. (#10841) 2020-10-06 17:05:45 -03:00
Robin Ward
db8b8742c4 DEV: Add support for api-initializers to reduce boilerplate.
You can now create a file in your plugin/theme in the `api-initializers`
directory which has a simpler template than previous initializers.
Example:

```
// api-initializers/my-plugin.js
import { apiInitializer } from "discourse/lib/api";

export default apiInitializer("0.8", api => {
  console.log("hello world from api initializer!");
});
```
2020-09-30 16:07:28 -04:00
jbrw
c8ed4e9868
DEV: deepMerge and deepEqual functions (#10764) 2020-09-28 13:46:48 -04:00
Neil Lalonde
3e564ff466
Version bump to v2.5.2 2020-09-24 14:30:57 -04:00
Krzysztof Kotlarek
875467c1c5 SECURITY: return error on oversized images 2020-09-14 11:31:48 +10:00
Rafael dos Santos Silva
48d161e3b1 PERF: Add partial index on reviewables for topic view (#10492)
On the topic view route we query for reviewables of each post in the stream,
using a query that filters on two unindexed columns. This results in a Parallel Seq Scan
over all rows, which can take quite some time (~20ms was seen) on forums with lots of flags

After index is added PostgreSQL planner opts for a simple Index Scan and runs in sub 1ms.

Before:

```
                                     QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Finalize GroupAggregate  (cost=11401.08..11404.87 rows=20 width=28) (actual time=19.209..19.209 rows=1 loops=1)
   Group Key: r.target_id
   ->  Gather Merge  (cost=11401.08..11404.41 rows=26 width=28) (actual time=19.202..20.419 rows=1 loops=1)
         Workers Planned: 2
         Workers Launched: 2
         ->  Partial GroupAggregate  (cost=10401.06..10401.38 rows=13 width=28) (actual time=16.958..16.958 rows=0 loops=3)
               Group Key: r.target_id
               ->  Sort  (cost=10401.06..10401.09 rows=13 width=16) (actual time=16.956..16.956 rows=0 loops=3)
                     Sort Key: r.target_id
                     Sort Method: quicksort  Memory: 25kB
                     Worker 0:  Sort Method: quicksort  Memory: 25kB
                     Worker 1:  Sort Method: quicksort  Memory: 25kB
                     ->  Nested Loop  (cost=0.42..10400.82 rows=13 width=16) (actual time=15.894..16.938 rows=0 loops=3)
                           ->  Parallel Seq Scan on reviewables r  (cost=0.00..10302.47 rows=8 width=12) (actual time=15.882..16.927 rows=0 loops=3)
                                 Filter: (((target_type)::text = 'Post'::text) AND (target_id = ANY ('{7565483,7565563,7565566,7565567,7565568,7565569,7565579,7565580,7565583,7565586,7565588,7565589,7565601,7565602,7565603,7565613,7565620,7565623,7565624,7565626}'::integer[])))
                                 Rows Removed by Filter: 49183
                           ->  Index Scan using index_reviewable_scores_on_reviewable_id on reviewable_scores s  (cost=0.42..12.27 rows=2 width=8) (actual time=0.029..0.030 rows=1 loops=1)
                                 Index Cond: (reviewable_id = r.id)
 Planning Time: 0.318 ms
 Execution Time: 20.470 ms
```

After:
```
                                                                                                          QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 GroupAggregate  (cost=0.84..342.54 rows=20 width=28) (actual time=0.038..0.038 rows=1 loops=1)
   Group Key: r.target_id
   ->  Nested Loop  (cost=0.84..341.95 rows=31 width=16) (actual time=0.020..0.033 rows=1 loops=1)
         ->  Index Scan using index_reviewables_on_target_id on reviewables r  (cost=0.42..96.07 rows=20 width=12) (actual time=0.013..0.026 rows=1 loops=1)
               Index Cond: (target_id = ANY ('{7565483,7565563,7565566,7565567,7565568,7565569,7565579,7565580,7565583,7565586,7565588,7565589,7565601,7565602,7565603,7565613,7565620,7565623,7565624,7565626}'::integer[]))
         ->  Index Scan using index_reviewable_scores_on_reviewable_id on reviewable_scores s  (cost=0.42..12.27 rows=2 width=8) (actual time=0.005..0.005 rows=1 loops=1)
               Index Cond: (reviewable_id = r.id)
 Planning Time: 0.253 ms
 Execution Time: 0.067 ms
```
2020-09-08 10:49:08 -07:00
Daniel Waterworth
356491aea8 PERF: Don't load all poll_votes for a poll 2020-09-08 10:48:27 -07:00
Guo Xiang Tan
996765562e DEV: Correct use of sanitize_sql_array in TopicQuery. 2020-09-08 10:44:35 +02:00
Guo Xiang Tan
05691b732d DEV: Address review comments for 5ed84d9885. 2020-09-08 10:44:27 +02:00
Guo Xiang Tan
aa1fb1b1b5 SECURITY: Remove indication that a group exists if user can't see it.
Minor security fix but we should not leak any hints that a group exists
even if a user does not have access to the group.
2020-09-08 10:44:09 +02:00
Guo Xiang Tan
1f6e8b642d SECURITY: Don't allow moderators to list PMs of all groups.
* Also return 404 when a user is trying to list PMs of a group that
cannot be accessed by the user.
2020-09-08 10:43:13 +02:00
Neil Lalonde
265eb1c7f9
Version bump to v2.5.1 2020-08-20 14:28:36 -04:00
Jeff Wong
3510534261 FIX: allow plugin pinning to fetch missing commits
Add update for fetching git commits if they do not exist, eg with
clone --depth 1 - only can fetch via git fetch --depth 1 {remote} {ref}
the ref needs to be a full, non-ambiguous reference.
2020-08-13 11:15:19 -07:00
Matt Palmer
e3b1c3a37b FEATURE: Allow the specification of an arbitrary unicorn listen address
Useful if you want to, say, have your unicorn listen on a Unix domain
socket, rather than a TCP port, or you want to be able to bind to a
single address other than 127.0.0.1.
2020-08-05 13:16:31 +05:30
Vinoth Kannan
c661934d41 FIX: rewrite of /my/URL should work on sub directory site too. 2020-08-05 00:56:49 +05:30
Guo Xiang Tan
d4d210eb60
Update rails_failover to 0.5.5. 2020-08-04 11:14:29 +08:00
Guo Xiang Tan
2a0af17a39
FIX: Exclude DELETE methods from invalid request with payload.
Follow-up 105d560177

Our client side code is sending params as part of the request payload so
that is going to be tricky to fix.
2020-08-03 17:05:50 +08:00
Guo Xiang Tan
4342d08edd
SECURITY: 413 for GET, HEAD or DELETE requests with payload. 2020-08-03 15:01:28 +08:00
Guo Xiang Tan
3260865697
DEV: Refactor anonymouse cache spec.
Mainly to properly categorize `Middleware::AnonymousCache` vs `Middleware::AnonymousCache::Helper` specs.
2020-08-03 15:01:19 +08:00
Sam Saffron
a0d4bc47d7 DEV: upgrade mini_racer and libv8
This pushes v8 from Chrome 73 (March 2019) -> 84 (July 14 2020)

Not expecting any user facing changes, but it is super nice to be on latest
v8 :confetti:
2020-07-23 14:31:34 +05:30
Rafael dos Santos Silva
7d30cf707d DEV: Fix search rate limit tests 2020-07-13 10:26:48 -07:00
Rafael dos Santos Silva
6aad9cd0c8 FEATURE: Add global rate limit for anon searches (#10208) 2020-07-13 10:26:42 -07:00
Martin Brennan
3f7658cc6e
SECURITY: Add content-disposition: attachment for SVG uploads
* strip out the href and xlink:href attributes from use element that
  are _not_ anchors in svgs which can be used for XSS
* adding the content-disposition: attachment ensures that
  uploaded SVGs cannot be opened and executed using the XSS exploit.
  svgs embedded using an img tag do not suffer from the same exploit
2020-07-09 13:54:45 +10:00
Jeff Wong
271d6319ce Support plugin and Theme compatibility version manifests (#9995)
Adds a new rake task `plugin:checkout_compatible_all` and
`plugin:checkout_compatible[plugin-name]` that check out compatible plugin
versions.

Supports a .discourse-compatibility file in the root of plugins and themes that
list out a plugin's compatibility with certain discourse versions:

eg: .discourse-compatibility
```
2.5.0.beta6: some-git-hash
2.4.4.beta4: some-git-tag
2.2.0: git-reference
```

This ensures older Discourse installs are able to find and install older
versions of plugins without intervention, through the manifest only.

It iterates through the versions in descending order. If the current Discourse
version matches an item in the manifest, it checks out the listed plugin target.
If the Discourse version is greater than an item in the manifest, it checks out
the next highest version listed in the manifest.

If no versions match, it makes no change.
2020-07-08 15:45:47 -07:00
Régis Hanol
c33847b30d FIX: uploading an existing image as a site setting
The previous fix (f43c0a5d85) wasn't working for images that were already uploaded.
The "metadata" (eg. 'for_*' and 'secure' attributes) were not added to existing uploads.

Also used 'Upload.get_from_url' is the admin/site_setting controller to properly retrieve
an upload from its URL.

Fixed the Upload::URL_REGEX to use the \h (hexadecimal) for the SHA

Follow-up-to: f43c0a5d85
2020-07-03 19:19:14 +02:00
Régis Hanol
08407905ba FIX: uploading an image as a site setting
When uploading an image as a site setting, we need to return the "raw" URL, otherwise
when saving the site setting, the upload won't be looked up properly.

Follow-up-to: f11363d446
2020-07-03 14:59:15 +02:00
Osama Sayegh
4a10350496 FIX: Negative limit values shouldn't cause error 500 (#10162) 2020-07-02 15:15:25 -04:00
Guo Xiang Tan
e94907eea4 FIX: Delete related search data when record has been deleted. 2020-07-02 15:14:17 -04:00
Vinoth Kannan
260bb6f073 FIX: return cdn url for uploads if available.
Currently it is displaying non-cdn urls in the composer preview.
2020-07-02 15:14:01 -04:00
Robin Ward
3a14bd6b14 FIX: Support root paths that omit the trailing slash and have QPs 2020-07-02 15:13:44 -04:00
Robin Ward
81ce3c8e50 FIX: Search was not multisite aware 2020-07-02 15:13:32 -04:00
Sam Saffron
7bfbecad7e PERF: cache all metadata for 60 seconds
Clients tend to request webmanifests and such very often.

Keep the data cached for 60 seconds so it is not requested aggresively.
2020-07-02 15:12:59 -04:00
Gerhard Schlager
f69e5a4d7e FIX: Sometimes not all output of psql was logged during restores
There was a race condition which could prevent Discourse from logging the last couple of lines of output from psql.
2020-07-02 15:12:44 -04:00
Sam Saffron
43a41f3928 FIX: emoji_autocomplete_min_chars failing when not 0
autocomplete resolving to [] was causing it to stop working.
Instead we have a special const (SKIP) which ensures it will
continue to be evaluated and only this instance is skipped.
2020-07-02 15:12:30 -04:00
Mark VanLandingham
67cc6731c6 FIX: update theme fields when updating from ThemesInstallTask (#10143) 2020-07-02 15:12:15 -04:00
Régis Hanol
3de1cf128c FIX: identify slug-less topic urls everywhere
In 91c89df6, I fixed the onebox to support local topics with a slug-less URL.
This commit fixes all the other spots (search, topic links and user badges) where we look up for a local topic.

Follow-up-to: 91c89df6
2020-07-02 15:11:36 -04:00
Dan Ungureanu
1f6f1604c9 FIX: Serialize an empty array if no suggested topics exist (#10134)
It used to return nil, which was ambiguous (empty vs absent
result).
2020-07-02 15:10:52 -04:00
Joshua Rosenfeld
8fbc41d993 FIX: Broken specs
`/u/` is no longer in robots.txt, so don't test for it
2020-07-02 15:09:50 -04:00
Joshua Rosenfeld
417bdcb53a FIX: Remove paths from robots.txt in favor of noindex header
Google no longer supports the use of robots.txt to block indexing.
See https://support.google.com/webmasters/answer/6062608 and
https://support.google.com/webmasters/answer/93710

Previous commits have added the `noindex` header to appropriate pages,
now we need to remove the paths from robots.txt so the pages can be
crawled.

Follow up to:
13f229808a
b6765aac4b
676be3a853
07b728c5e5
c94e6a9a66
2020-07-02 15:09:40 -04:00
Régis Hanol
d156b7749d FIX: match discobot triggers on cooked version
In French, the help trigger has a raw content of "afficher l'aider" which is then cooked into "afficher l’aide" (note the different quote character).
Since we were checking the raw content of the trigger against the cooked version of the post, this trigger never worked in French.

This changes so that we cook the trigger before checking in against the cooked version of the post.

DEV: new 'discobot_username' method that is used everywhere instead of 'discobot_user.username' / 'discobot_user.username_lower'
2020-07-02 15:09:22 -04:00
Sam Saffron
17182edab2 FIX: invalid urls should not break store.has_been_uploaded?
Breaking this method has wide ramification including breaking
search indexing.
2020-07-02 15:09:10 -04:00
Sam Saffron
ae520b62e4 FEATURE: allow disabling of extra term injection in search
There is a feature in search where we take over from the tokenizer
in postgres and attempt to inject more words into search.

So for example: sam.i.am will inject the words i and am.

This is not ideal cause there are many edge cases and this can
cause extreme index bloat.

This is an opening move commit to make it configurable, over the
next few weeks we will evaluate and decide if we disable this by
default or simply remove.
2020-07-02 15:08:53 -04:00
Sam Saffron
5f5dd9ea67 PERF: stop adding more topics to search when not needed
The logic of adding additional search results does not seem to be
needed anymore.

It appears to be a relic of an old implementation.

This saves an entire search query for every search made.
2020-07-02 15:08:33 -04:00
Guo Xiang Tan
f10f87cc68 FIX: Avoid marking notifications as seen in readonly mode. 2020-07-02 15:08:13 -04:00
Roman Rizzi
1b17482eab FIX: Uploads cannot be mapped due to the cook-text's element attr being null (#10136) 2020-06-30 12:07:50 -03:00
David Taylor
19db1a7d2a
FIX: Correct version comparison logic when comparing stable to beta (#10135)
* FIX: Correct version comparison logic when comparing stable to beta

For example, version 1.3.0 should be considered higher than 1.3.0.beta3. So `Discourse.has_needed_version?('1.3.0', '1.3.0.beta3')` should return true

* Switch to use Gem::Version to compare versions
2020-06-30 09:37:01 +01:00
tshenry
c271b0c394
FIX: published-page-header should be a sibling to published-page-body not a parent (#10126) 2020-06-25 14:59:33 -07:00
Neil Lalonde
6a42acbfb7
Version bump to v2.5.0 2020-06-24 13:56:53 -04:00
Neil Lalonde
eb10109c99
Merge diffs from master 2020-06-24 13:48:37 -04:00
Neil Lalonde
607d00f780
Merge master 2020-06-24 13:47:36 -04:00
Neil Lalonde
53c7d0200a
Version bump to v2.4.5 2020-06-01 14:05:48 -04:00
Jeff Wong
b6ff3b6a26 SECURITY: make find topic by slug adhere to SiteSetting.detailed_404 (#9898) 2020-05-28 13:54:10 -07:00
Blake Erickson
745d1de40c SECURITY: Use FinalDestination for topic embeds 2020-05-27 09:31:15 -06:00
Neil Lalonde
fe275c97c1
Version bump to v2.4.4 2020-05-26 10:31:32 -04:00
Blake Erickson
7f6a321fec SECURITY: ensure embed_url contains valid http(s) uri 2020-05-22 15:15:44 -06:00
Robin Ward
a55d5bd1b0 SECURITY: ERB execution in custom Email Style 2020-05-21 14:49:06 -04:00
Neil Lalonde
ec33d7e237
Version bump to v2.4.3 2020-05-04 11:31:32 -04:00
Robin Ward
7cc7baf378 SECURITY: Update onebox to add rel="noopener" 2020-04-29 10:59:06 -04:00
Neil Lalonde
10e11fd5d8
Version bump to v2.4.2 2020-04-22 10:15:37 -04:00
Blake Erickson
6b20d52338 FIX: Staged users getting user_linked and user_quoted emails
This fix ensures that if a staged user is linked to or quoted they won't
be emailed about it.

A staged user could email into a category, and another user could quote
them inside of a completely different category and we don't want a
staged user to receive an email for this.

Bug report:

https://meta.discourse.org/t/-/145202/9
2020-03-31 21:00:56 -06:00
Jeff Wong
45296a8fe9 FIX: backport reviewable topic claim not being shown correctly 2020-03-30 15:23:16 -07:00
Jeff Wong
385c3fe789 FIX: claiming topics for the review queue 2020-03-30 15:16:47 -07:00
Jeff Wong
7817d8b2ff FEATURE: Unassign the review queue topic when a flag is handled 2020-03-25 14:17:08 -07:00
Bianca Nenciu
fe15082d44 SECURITY: Ensure user can see group and group members 2020-03-24 12:23:11 +02:00
Jeff Wong
0e553f1fd1 FIX: correctly remove authentication_data cookie on oauth login flow (#9238)
Additionally correctly handle cookie path for authentication_data

There were two bugs that exposed an interesting case where two discourse
instances hosted across two subfolder installs in the same domain
with oauth may clash and cause strange redirection on first login:

Log in to example.com/forum1. authentication_data cookie is set with path /
On the first redirection, the current authentication_data cookie is not unset.
Log in to example.com/forum2. In this case, the authentication_data cookie
is already set from forum1 - the initial page load will incorrectly redirect
the user to the redirect URL from the already-stored cookie, to /forum1.

This removes this issue by:
* Setting the cookie for the correct path, and not having it on root
* Correctly removing the cookie on first login
2020-03-23 16:01:39 -07:00
Jeff Wong
e0f711960b FIX: consistency to show mute/ignore menu in user profile
Show the mute/ignore menu for another user even when the current user
cannot message them.
2020-03-23 16:01:39 -07:00
Jeff Wong
111fa7e277 FEATURE: prevent accidental canceling when drafting penalties (#9129)
Pop up a confirmation box when there is input. This prevents accidental closing
of the dialog boxes due to clicking outside.

This adds a development hook on modals in the form of a `beforeClose`
function. Modal windows can abort the close if the funtion returns false.

Additionally fixing a few issues with loop and state on the modal popups:

Escape key with bootbox is keyup.
Updating modal to close on keyup as well so escape key is working.
Fixes an issue where pressing esc will loop immediately back to the modal by:
keydown -> bootbox -> keyup -> acts as "cancel", restores modal

Needs a next call to reopenModal otherwise, keyup is handled again by the modal.
Fixes an issue where pressing esc will loop immediately back to the confirm:
esc keyup will be handled and bubble immediately back to the modal.

Additionally, only handle key events when the #discourse-modal is visible.
This resolves issues where escape or enter events were being handled by
a hidden modal window.
2020-03-23 16:01:39 -07:00
David Taylor
4e178d5c0d
SECURITY: Respect topic permissions when loading draft metadata
Co-authored-by: Sam Saffron <sam.saffron@gmail.com>
2020-03-23 11:54:36 +00:00
David Taylor
0e3dfd2925
DEV: Load plugin stylesheets before theme stylesheets (#9240)
This is a more logical order, since themes are more lightweight than plugins, and are often used to augment plugin styles
2020-03-19 19:24:06 +00:00
Martin Brennan
4eb4293e66 FIX: Ensure show_short URLs handle secure uploads using multisite (#9212)
Meta report: https://meta.discourse.org/t/short-url-secure-uploads-s3/144224
* if the show_short route is hit for an upload that is
  secure, we redirect to the secure presigned URL. however
  this was not taking into account multisite so the db name
  was left off the path which broke the presigned URL
* we now use the correct url_for method if we know the
  upload (like in the show_short case) which takes into
  account multisite
2020-03-17 11:41:51 +10:00
Joffrey JAFFEUX
c4cd864c26 FIX: throttles topic tracking shortcut and enforces topic id (#9159) 2020-03-13 12:03:55 +01:00
Joffrey JAFFEUX
b4b0443d63 FIX: ensures pinned-options header is showing correct state (#9156) 2020-03-12 07:41:17 +01:00
Robin Ward
f8c31eb1e0 Let's not log the username/password
This could easily be seen by someone who shouldn't.
2020-03-11 12:54:19 -04:00
Sam Saffron
c738d31809
FIX: last ip address could point at wrong ip
Due to unicorn env object recycling request.ip could point at the wrong
ip address by the time defer block is called. This usually would happen
under load.

This also avoids keeping the entire request object as referenced by the
closure.
2020-03-11 17:43:44 +11:00
Neil Lalonde
ea73880146
Version bump to v2.4.1 2020-03-05 12:28:17 -05:00
Gerhard Schlager
766665a287
FIX: Restoring with disable_emails: false didn't work anymore 2020-03-05 11:47:35 -05:00
Martin Brennan
f0072dd897
FIX: Stop infinite lookup-urls issue for video/audio on page (#9096)
Meta report: https://meta.discourse.org/t/excessive-requests-to-uploads-lookup-urls-leading-to-429-response/143119

* The data-orig-src attribute was not being removed from cooked
video and audio so the composer was infinitely trying to get the
URLs for them, which would never resolve to anything
* Also the code that retrieved the short URL was unscoped, and was
getting everything on the page. if running from the composer we
now scope to the preview window
* Also fixed a minor issue where the element href for the video
and audio tags was not being set when the short URL was found
2020-03-05 11:47:14 -05:00
Joffrey JAFFEUX
d5ab4776cd
FIX: prevents click on sk header to bubble (#9084) 2020-03-05 11:46:55 -05:00
Gerhard Schlager
55a49d8494
FIX: Google Groups scraper failed to login 2020-03-05 11:46:36 -05:00
Sam Saffron
980d2ed052
PERF: improve performance of category topic list
In some cases CTE caused pathologically bad query plans.
This optimises it so query runs by itself and caches for lifetime
of the topic query object.

This lightweight caching is done cause topic query will often
execute two queries (one for pinned and one for non pinned)
2020-03-05 11:46:20 -05:00
Dan Ungureanu
5f88b86ac9
FIX: Sync preload key format for category topic lists
The server and client used two different formats for preload keys. The
server was using 'topic_list_c/SLUG/l/latest', but the client was using
'topic_list_c/SLUG/ID/l/latest'.

This commit is an addition to 374534f00e.
2020-03-05 11:46:02 -05:00
Dan Ungureanu
4bb966aae6
DEV: Fix build
Follow up to 60184a290c.
2020-03-05 11:45:45 -05:00
Joffrey JAFFEUX
2cc533e26e
FIX: prevents loading to show during debouncing (#9060)
This will also fix a bug in IE11 where click event would not be triggered on row
2020-03-05 11:45:19 -05:00
Joffrey JAFFEUX
751708ba0c
FIX: prevents row click event to be caught by filter input event (#9059)
This was causing some dropdowns to not work under IE11
2020-03-05 11:44:54 -05:00
David Taylor
b8e4b5f884
FIX: Polyfill Promise for IE11 (#9057)
Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
2020-03-05 11:44:33 -05:00
Robin Ward
c7634d56f6 SECURITY: Add more restrictions on invite emails
They could be filtered and returned in some circumstances where they
shouldn't have been.
2020-03-05 09:55:54 -05:00
Robin Ward
20a8a2f396 SECURITY: Ensure the invite JSON API matches the UX
Anonymous users could query the invite json and see counts and
summaries which is not allowed in the UX of Discourse.

This commit has those endpoints return a 403 unless the user is
allowed to invite.
2020-03-05 09:55:45 -05:00
Joffrey JAFFEUX
2246fe8015 FIX: allows to select the action when agreeing with penalty (#9099)
Note this commit also fixes an issue where the edit post actions was trying to focus the edit textarea, but was using jquery functions on a DOM node.

scrollTo is not available on IE11 but that shouldn't cause much trouble.
2020-03-04 10:32:20 -05:00
Mark VanLandingham
737e8bdb2c FIX: Prettier on iframed-html component (#9062) 2020-02-27 11:57:18 -06:00
Mark VanLandingham
df70b9118e Merge pull request from GHSA-vw39-6w7q-gfx5
Co-authored-by: Robin Ward <robin.ward@gmail.com>
2020-02-27 11:57:10 -06:00
Neil Lalonde
76b9be3f19 Version bump to v2.4.0 2020-02-26 16:46:06 -05:00
Neil Lalonde
254d410d4e Merge branch 'master' into stable 2020-02-25 17:32:08 -05:00
Neil Lalonde
4d611dcaed Merge diffs from master 2020-02-25 17:23:37 -05:00
Neil Lalonde
52c10848bc Merge master 2020-02-25 17:21:37 -05:00
Neil Lalonde
632ef306e2 Version bump to v2.3.10 2020-02-13 16:26:48 -05:00
David Taylor
4b56345672 DEV: Bump omniauth-github from 1.3.0 to 1.4.0 (#8924)
This switches the github API access to use header-based authentication, rather than the deprecated parameter-based method
2020-02-11 09:47:30 +00:00
Sam Saffron
7e39f779b4 FEATURE: support MaxMind DB downloads using a license key
MaxMind now requires an account with a license key to download files.

Discourse admins can register for such an account at:

https://www.maxmind.com/en/geolite2/signup

License key generation is available in the profile section.

Once registered you can set the license key using `DISCOURSE_MAXMIND_LICENSE_KEY`

This amends it so we unconditionally skip MaxMind DB downloads if no license key exists.
2020-02-05 16:40:04 +11:00
Roman Rizzi
b231be8865 FIX: Ensure sourcemap's source is correct. Uses the full assets path this time. (#8774)
Cherry-picked from 8eb2147f1f
2020-01-24 15:54:21 -03:00
Neil Lalonde
9298132c73 Version bump to v2.3.9 2020-01-21 15:46:33 -05:00
Roman Rizzi
733143cba3 SECURITY: Do not create a notification if a staged user post gets quoted/linked inside a restricted category 2020-01-16 15:37:03 -03:00
Régis Hanol
65831f4d3e SECURITY: use strict JSON parsing when parsing backup metadata 2020-01-15 22:05:38 +01:00
Rafael dos Santos Silva
ad7a13921f
FIX: Use cached MaxMind DB for longer
Don't try to update the IP database as it's gone.

This allows users to rebuild Discourse while we work on a proper
fix / alternative database.
2019-12-31 13:07:43 -03:00
Robin Ward
a6701d8710 FIX: Gemfile bundler was breaking build
We update bundler in app.yml and the version received was too
new for our Gemfile.lock
2019-12-26 14:40:27 -05:00
Robin Ward
6e88dde635 FIX: Build was broken due to missing file
It seems a file was in the base image but .gitignored, so the
stable branch got into a weird state.
2019-12-26 14:40:13 -05:00
Neil Lalonde
d4e0eb63a2 Version bump to v2.3.8 2019-12-19 14:22:00 -05:00
David Taylor
ff4a6a37de SECURITY: Correct permission check when revoking user API keys 2019-12-17 11:07:36 +00:00
Krzysztof Kotlarek
1c49875048 SECURITY: vulnerability in WildcardUrlChecker 2019-12-13 09:55:43 -05:00
Krzysztof Kotlarek
e1e571d32c SECURITY: upgrade rack-mini-profiler to avoid possible XSS (#8537) 2019-12-12 13:23:09 +11:00
Dan Ungureanu
554b0f366d
SECURITY: Ensure only image uploads can be inlined
This prevents malicious files (for example special crafted XMLs) to be
used in XSS attacks.
2019-12-11 17:08:58 +02:00
Dan Ungureanu
43ddb6b36d
SECURITY: Remove event handlers from SVG files 2019-12-11 17:08:57 +02:00
Neil Lalonde
5b17584adb Version bump to v2.3.7 2019-12-05 13:11:05 -05:00
Joffrey JAFFEUX
5cb00d5528 DEV: s/\$redis/Discourse\.redis
With manual merge conflicts
2019-12-03 14:26:57 +01:00
Sam Saffron
14db879a31 DEV: Implement a faster Discourse.cache
This is a bottom up rewrite of Discourse cache to support faster performance
and a limited surface area.

ActiveSupport::Cache::Store accepts many options we do not use, this partial
implementation only picks the bits out that we do use and want to support.

Additionally params are named which avoids typos such as "expires_at" vs "expires_in"

This also moves a few spots in Discourse to use Discourse.cache over setex
Performance of setex and Discourse.cache.write is similar.
2019-12-03 14:03:30 +01:00
Sam Saffron
ef791a5b1f DEV: use Discourse.cache over Rails.cache
With manual merge
2019-12-03 14:03:21 +01:00
Neil Lalonde
69983297ed Version bump to v2.3.6 2019-11-06 12:46:03 -05:00
David Taylor
914e50db49 DEV: Update users controller spec following user_search update 2019-11-06 17:32:10 +00:00
Robin Ward
5f01814397 FIX: Handle nil case for avatar, just in case 2019-10-28 11:30:34 -03:00
Robin Ward
069d358c80 FIX: Allow avatar downloads to follow redirects 2019-10-28 11:30:21 -03:00
David Taylor
c38c37bcc3 SECURITY: Check permissions when autocompleting mentions 2019-10-28 12:20:26 +00:00
Robin Ward
afea20953f FIX: Broken certificates 2019-10-24 14:13:27 -03:00
Roman Rizzi
3a73f29928 FIX: Rate limit and hijack certificate generation. (#8215)
To eliminate a DDOS attack vector, we're taking the following measures:

The endpoint will be rate-limited to 3 requests every 60 seconds (per user).
A 24 hours max-age cache header is sent with the response.
The route will be hijacked to generate the certificate in the background.
2019-10-22 15:39:58 -03:00
Krzysztof Kotlarek
5bcc1c1cd5 FIX: Narrative Bot certificates are ERB templates (#8174)
There are at least two ways of rendering templates outside of the controller. The first one is Rails way enabled with Rails 5 https://evilmartians.com/chronicles/new-feature-in-rails-5-render-views-outside-of-actions
The downside of this method is that all variables need to be passed as params (I could find a way to pass the whole context)

Another way is to use instance_eval described in Erubi documentation
https://github.com/jeremyevans/erubi#usage - it works perfectly fine, however, I didn't feel very confident about using eval unless necessary.

An additional benefit of using `ApplicationController.render` is that if Rails would change the ERB engine in the future, this code should still work.

If you want to test it on your local, you need to be signed in and then that two URLs are generating certificates:
http://localhost:3000/discobot/certificate.svg?date=Oct+07+2019&type=standard&user_id=1
http://localhost:3000/discobot/certificate.svg?date=Oct+07+2019&type=advanced&user_id=1

Dev: https://dev.discourse.org/t/discourse-narrative-bot-should-not-be-storing-giant-strings/17130
2019-10-22 15:39:42 -03:00
Neil Lalonde
76f6ee501f Version bump to v2.3.5 2019-10-10 11:44:33 -04:00
Roman Rizzi
e4570ffb78 DEV: Bump uglifyjs (#7834)
* Rewrite uglifyjs command to work with 3.x

* Use ES5 syntax in plain JS files

* Use the older command if uglifyJS V2.x is installed
2019-10-09 10:36:15 -03:00
Sam Saffron
8f001bdb1b SECURITY: mini profiler enabled incorrectly for admins
We expect mini profiler only to show up on accounts that are flagged as
developer accounts.

Unfortunately there was a bypass on any controllers that mix in ApplicationHelper
2019-10-09 12:50:58 +11:00
David Taylor
68fc799380 DEV: Allow specifying button class in reviewable action definitions (#8093)
This avoids the need for using `@extend` in SCSS, which can be problematic in plugins

For context, see https://review.discourse.org/t/fix-make-compatible-with-debundled-plugin-css-assets-feature/5297/7
2019-10-08 15:06:15 -03:00
Sam Saffron
67e8fbc480 FIX: change focus when application resumes in android
Per new lifecycle https://developers.google.com/web/updates/2018/07/page-lifecycle-api

On Android and latest Chrome when an app transitions from "frozen" to
active the new "resume" event fires with no accompanying "visibilitychange"
event.

This means that often background tabs may be stuck thinking that discourse
has no focus when, indeed, it has.

This leads to cases where no posts are marked read anymore.
2019-10-08 00:04:54 +02:00
Neil Lalonde
3e73c0a34d Version bump to v2.3.4 2019-10-01 17:43:25 -04:00
romanrizzi
ba3dbcc117 Spec should not depend on aliases 2019-10-01 18:35:41 -03:00
Robin Ward
cd20d0fdfd SECURITY: Don't allow base_uri as embeddable host if none exist 2019-10-01 17:58:39 +02:00
Sam Saffron
fd0bb34001 SECURITY: update rack-mini-profiler to latest to correct XSS
This corrects an XSS in ?pp=help.

Also removes the jQuery dependency from rack-mini-profiler and restricts
memory sensitive profiling methods development only.
2019-10-01 16:56:51 +10:00
Penar Musaraj
6e04120e71 SECURITY: XSS when oneboxing user profile location field
The XSS here is only possible if CSP is disabled. Low impact since CSP is enabled by default in SiteSettings.
2019-09-17 16:36:53 -04:00
Roman Rizzi
fd1a2a4c07 FIX: Improve protection against problematic usernames (#8097) 2019-09-13 15:52:05 -03:00
Penar Musaraj
051462cbe2 FIX: IE grid layout issue on user's own activity page 2019-09-12 11:15:47 -04:00
Nick Quaranto
21c11c2bb2 Use Discourse.getURL for /clicks/track so clicks can be tracked on relative URLs (#8079) 2019-09-09 23:17:43 -07:00
Régis Hanol
39a427efce DEV: plugin API to register User custom field types 2019-09-06 12:16:59 +02:00
Roman Rizzi
24fc0aba9b FIX: :reject_user_delete action can only be handled by ReviewableUser (#8068) 2019-09-05 11:44:16 -03:00
Jeff Wong
b72dbb0be0 FEATURE: add before-topic-progress plugin outlet 2019-09-04 11:29:05 -07:00
Neil Lalonde
046b6300d1 Version bump to v2.3.3 2019-09-04 10:44:22 -04:00
Roman Rizzi
52fdc1468d Feature/Fix: Flagged posts user notifications (#8041)
* FIX: User should get notified when a post is deleted

* FEATURE: Notify posters when restoring flagged posts

* Fix typo

Co-Authored-By: Régis Hanol <regis@hanol.fr>

* Improve tests
2019-09-02 15:22:03 -03:00
David Taylor
51b7f4d900 FIX: When activating via omniauth, create tokens after password reset
Resetting a password invalidates all email tokens, so we need to create the tokens after the password reset.
2019-08-28 14:50:07 +01:00
David Taylor
3b9e8a0849 FIX: When activating a user, ensure the change is reflected immediately
When activating a user via an external provider, this would cause the "this account is not activated" message to show on the first attempt, even though the account had been activated correctly.
2019-08-28 14:09:03 +01:00
David Taylor
f80f8a34c0 SECURITY: Reset password when activating an account via auth provider
Followup to d693b4e35fe0e58c5578eae4a56c06dff4756ba2
2019-08-28 14:08:55 +01:00
Sam Saffron
a3d42e2c52 FIX: add_to_serializer not correctly accounting for inheritance chains
This is a very long standing bug we had, if a plugin attempted to amend a
serializer core was not "correcting" the situation for all descendant classes
this often only showed up in production cause production eager loads serializers
prior to plugins amending them.

This is a critical fix for various plugins
2019-08-27 18:23:32 +10:00
Sam Saffron
6477531098 SECURITY: add rate limiting to anon JS error reporting
This adds a 1 minute rate limit to all JS error reporting per IP. Previously
we would only use the global rate limit.

This also introduces DISCOURSE_ENABLE_JS_ERROR_REPORTING, if it is set to
false then no JS error reporting will be allowed on the site.
2019-08-20 11:31:58 +10:00
Arpit Jalan
aea541d037 SECURITY: don't reveal category details to users that do not have access 2019-08-19 12:51:15 +05:30
David Taylor
d237da16c5 SECURITY: Restrict message-bus access on login_required sites 2019-08-14 10:11:28 +01:00
Gerhard Schlager
ab3e18090f FIX: Disallow user self-delete when user posted in PMs
All posts created by the user are counted unless they are deleted,
belong to a PM sent between a non-human user and the user or belong
to a PM created by the user which doesn't have any other recipients.

It also makes the guardian prevent self-deletes when SSO is enabled.
2019-08-10 12:06:40 +02:00
Roman Rizzi
0be47023d4 FIX: Use unescaped title as combo-box id (#7979) 2019-08-08 12:52:34 -03:00
David Taylor
b1d2e4daf3 FIX: Composer preview on IE11 (#7970)
Add the Array.from polyfill for IE11. This is required to support the transpiled ES6 spread syntex generated by babel: https://babeljs.io/docs/en/caveats/
2019-08-05 14:44:13 +01:00
Sam Saffron
c587df7e2a Revert "FEATURE: add Noindex to robots.txt for disallowed routes"
This reverts commit d84256a876.

This is not supported by Google and causes robots.txt to be flagged as
invalid

Removing Noindex
2019-07-30 11:37:00 +10:00
David Taylor
85cdf213e1 FIX: Hide live-loaded posts from ignored users 2019-07-27 14:00:34 +01:00
David Taylor
e9c0fb0621 SECURITY: Sanitize email id for use as mutex key 2019-07-24 13:51:08 +01:00
David Taylor
c4ff66e1a5 DEV: Correct merge conflicts for 9cfe3f99 2019-07-24 13:31:16 +01:00
David Taylor
9cfe3f9948 SECURITY: Add confirmation screen when connecting associated accounts 2019-07-24 13:29:59 +01:00
Gerhard Schlager
90a1aa5536 SECURITY: Validate backup chunk identifier 2019-07-22 08:44:38 +02:00
Neil Lalonde
af192ff9d5 Version bump to v2.3.2 2019-07-15 10:00:45 -04:00
Guo Xiang Tan
3663ef6394 Fix the build.
Follow up to 4b0cf7f6dd.
2019-07-15 16:42:58 +08:00
Guo Xiang Tan
477bacb3ae SECURITY: XSS when displaying watched words in admin panel.
The XSS here is only possible if CSP is disabled. Low impact since CSP
is enabled by default in SiteSettings.
2019-07-15 10:58:52 +08:00
Robin Ward
fe8bd92f71 SECURITY: SQL injection with default categories
This is a low severity security fix because it requires a logged in
admin user to update a site setting via the API directly to an invalid
value.

The fix adds validation for the affected site settings, as well as a
secondary fix to prevent injection in the event of bad data somehow
already exists.
2019-07-11 13:53:12 -04:00
Robin Ward
2f91f88d06 SECURITY: Upgrade lodash
There is a security hole in lodash with prototype pollution. It's not
clear if Discourse is affected but to be on the safe side we will
upgrade right away.

Note that the front end Discourse does not appear to use `defaultsDeep`
in our custom build and should be protected.
2019-07-11 10:51:44 -04:00
Robin Ward
d1c12539dd SECURITY: XSS with title selector on preferences page
Note this is very low severity as the group needs to be created with a
default title that contains HTML, and group creation is restricted to
staff members right now.
2019-07-09 17:35:26 -04:00
Robin Ward
4fd470e63d SECURITY: Strip HTML from invite emails
We also strip new lines from the emails because it ruins the markdown
formatting which expects a one line message.
2019-07-05 14:58:46 -04:00
Jeff Wong
a7a7afdb27 FIX: iterate when clearing watched words cache 2019-07-04 08:59:01 -07:00
romanrizzi
2a7d270fd6 Revert "FIX: remove misplaced save button"
This reverts commit f1381a274b.
2019-07-03 10:58:33 -03:00
romanrizzi
f1381a274b FIX: remove misplaced save button 2019-07-03 10:47:54 -03:00
romanrizzi
34d548dbd3 FIX: Remove misplaced outlet 2019-07-03 10:47:43 -03:00
Arpit Jalan
867eebb55e FIX: creating new badge is failing on empty SQL query (#7837) 2019-07-02 15:17:32 +05:30
Gerhard Schlager
b549cab2ad FIX: Don't send notification email when user isn't allowed to see topic 2019-07-02 09:05:36 +10:00
Gerhard Schlager
5b91182985 DEV: Respond with error 400 to uploads requested via XHR
follow-up to 13f38055
2019-06-27 11:30:05 +02:00
Sam Saffron
467e03a2ec DEV: lint file
We no longer need that isAppleDevice require
2019-06-27 11:29:51 +02:00
Joffrey JAFFEUX
a91881280d FIX: closes search-menu on escape (#7804) 2019-06-27 09:34:34 +02:00
Joffrey JAFFEUX
690fb5c4fb FIX: prevents failure when TL was mutated on internal object (#7808) 2019-06-27 09:34:31 +02:00
Gerhard Schlager
9c8aa0a906 SECURITY: XSS in routes
Co-authored-by: Guo Xiang Tan <tgx_world@hotmail.com>
Co-authored-by: David Taylor <david@taylorhq.com>
2019-06-26 16:45:33 +02:00
Bianca Nenciu
3503271959 SECURITY: Escape email text for posts containing [details]. 2019-06-26 16:45:25 +02:00
Neil Lalonde
2c26998f86 Version bump to v2.3.1 2019-06-25 12:26:20 -04:00
Neil Lalonde
6411810630 Update translations 2019-06-25 11:50:50 -04:00
Sam Saffron
0fa02274c2 DEV: bump version on mini_scheduler
This corrects a catastrophic state that can ensue if redis becomes readonly

It also adds support for multiple queues and minor cleanup
2019-06-25 11:50:19 -04:00
Penar Musaraj
8b963bce37 FIX: Do not refresh all settings on save for all settings, limit to only a few
- Followup to 0e303c7f5d

- Automatically reloads site settings after saving only for the logo, logo_small and large_icon settings.
2019-06-25 11:49:09 -04:00
Penar Musaraj
e1822034dc FIX: use correct name for selectable_avatars_enabled site setting 2019-06-25 11:48:56 -04:00
Maja Komel
faf059e018 FIX: remove temporary hack for fixed iOS bug (#7773)
A bug where input focus is displaced on modals was fixed in iOS 11.3 update. This hack was causing problems on topic page since hiding main-outlet results in lost read position after opening and closing a modal.
2019-06-25 11:48:42 -04:00
Joffrey JAFFEUX
f2d5cde24c FIX: category-chooser search should be scoped to category (#7794) 2019-06-24 11:31:41 +02:00
Neil Lalonde
0bcb62fc2d Version bump to v2.3.0 2019-06-17 20:47:22 -04:00
Neil Lalonde
04be572a92 Merge diffs from master 2019-06-17 20:07:19 -04:00
Neil Lalonde
a4308fdd43 Merge master 2019-06-17 20:04:04 -04:00
David Taylor
40cbcc7720 SECURITY: Add confirmation screen when logging in via email link 2019-06-17 18:20:48 +01:00
Neil Lalonde
809a544786 Version bump to v2.2.6 2019-06-10 11:47:21 -04:00
Penar Musaraj
39bececaaf SECURITY: Bump Handlebars to version 4.1.2
WS-2019-0064: Versions of handlebars prior to 4.0.14 are vulnerable to Prototype Pollution. Templates may alter an Objects prototype, thus allowing an attacker to execute arbitrary code on the server.
2019-06-05 14:57:50 -04:00
Rafael dos Santos Silva
c294ff3609 Version bump to v2.2.5 2019-05-08 18:30:55 -03:00
Rafael dos Santos Silva
99dd426b12 FIX: We need a newer mini_racer for ruby 2.6.3
This is necessary because the bumped ruby version (which happens
in the discourse_docker repo) doesn't install mini_racer < 0.2.4
2019-05-08 18:08:28 -03:00
Dan Ungureanu
2a8118fb44
SECURITY: Fix tab nabbing. 2019-04-25 00:34:59 +03:00
Gerhard Schlager
b264661fe2 SECURITY: Update nokogiri 2019-04-24 16:37:47 +02:00
Joffrey JAFFEUX
922d93c1d4 SECURITY: jquery CVE-2019-11358 2019-04-24 16:31:26 +02:00
Sam Saffron
e143cc1843 FEATURE: enable NGINX brotli support unconditionally
Previously we would rely on enable brotli in the web template to turn this
on, going forward this is default on
2019-04-11 12:42:47 +10:00
Robin Ward
db63a8e468 SECURITY: Update Handlebars to 4.1
This is to address: https://www.npmjs.com/advisories/755

It is a low priority fix, as Discourse does not allow end users to input
raw handlebars templates.
2019-04-10 16:15:12 -04:00
Neil Lalonde
63dbac786f Version bump to v2.2.4 2019-03-28 11:03:05 -04:00
Sam Saffron
e073593c86 SECURITY: properly validate return URL for SSO
Previously carefully crafted URLs could redirect off site
2019-03-25 09:04:13 +11:00
Jeff Wong
8b761cded1 FIX: remove extra periods (#6998)
Periods are belong in the translation files not in our templates, if we have them in the templates sentences can not be localized properly.
2019-03-15 15:47:00 -07:00
Jeff Wong
cbfd9595c4 FEATURE: Add plugin html hook to insert html before any other scripts 2019-03-15 15:38:49 -07:00
Jeff Wong
c9fd2679e4 FIX: lightbox wrapper within open details should show. 2019-03-15 15:38:49 -07:00
Vinoth Kannan
c395755051 FIX: Add helper file for compatibility with latest stable plugin 2019-03-14 09:04:05 +05:30
Roman Rizzi
d8c3c82345 Version bumped to v2.2.3 2019-03-13 16:39:39 -03:00
Roman Rizzi
0f6d5ba4f9 SECURITY: Upgrading Rails version to 5.2.2.1 2019-03-13 16:30:49 -03:00
Neil Lalonde
760d51cab1 Version bump to v2.2.2 2019-03-01 12:27:02 -05:00
Sam
3ac5f526be SECURITY: bypass long GET requests
In some rare cases we would check URLs with very large payloads
this ensures we always bypass and do not read entire payloads
2019-02-27 21:52:40 +11:00
David Taylor
c10941bbde REFACTOR: Proxy letter avatars in rails instead of nginx
Co-authored-by: Sam Saffron <sam.saffron@gmail.com>
Co-authored-by: David Taylor <david@taylorhq.com>

This gives more control over the request. In particular we can easily
lookup DNS dynamically, instead of only upon NGINX startup.
Previously, NGINX was looking up IP for the letter avatar service and
caching the CDN IP address, this caused issues if CDN changed IP, in
which letter avatars would be broken till a container restarted.

NGINX config has been updated to add caching. This change will require
a container rebuild.

The proxy will now function in development environments, so the patch
for `letter_avatar_proxy` has been removed.
2019-02-18 08:51:58 +11:00
Kris
4325d0ffc3 UX: Reduce font size on about pages
(cherry picked from commit 3d11064a33)
2019-02-14 20:12:55 -05:00
Sam
904e5ac09c FIX: unable to create new categories
Previous attempt at 70adb940 missed the critical "everyone" group from
staff, leading to a case where staff was no longer able to create categories
2019-02-15 10:28:13 +11:00
Bianca Nenciu
8e1efe6899 DEV: Improve test. 2019-02-14 23:04:38 +02:00
Bianca Nenciu
426810fcaf FIX: Fix failing test. 2019-02-14 23:04:34 +02:00
Bianca Nenciu
37214bc3eb SECURITY: Do not leak private group names. (#7008) 2019-02-14 23:04:32 +02:00
Vinoth Kannan
2fb5271069 FIX: Bump onebox version to include imgur security fix
(cherry picked from commit 36ff971c9c)
2019-02-13 11:51:15 +05:30
Vinoth Kannan
e11ae2a5ab FIX: Bump onebox version to include imgur security fix
(cherry picked from commit fb911766ee)
2019-02-13 11:50:35 +05:30
Arpit Jalan
e1094724fb FIX: some posters were not getting added to topic_allowed_users when moving posts to a new PM
If a user posted twice in a topic then subsequent posters were not getting added as topic_allowed_users.
2019-02-11 18:25:06 +05:30
Neil Lalonde
e9d1597f81 Version bump to v2.2.1 2019-02-07 10:56:03 -05:00
Kris
3ad5f6ea4b UX: checkboxes were too close to other inputs 2019-02-07 10:09:19 -05:00
Bianca Nenciu
589187b732 FIX: Fix delete button for Tag Groups. (#6965) 2019-02-07 10:09:16 -05:00
Kris
dc43fb69d1 UX: Minor button icon color fixes 2019-02-07 10:09:13 -05:00
Bianca Nenciu
beb6e154ef FIX: in:title should work irrespective of the order. (#6968) 2019-02-07 10:09:08 -05:00
Dan Ungureanu
cc983e3b11 UX: Use translatedLabel for aria-label in buttons. 2019-02-07 10:09:05 -05:00
Maja Komel
7426c427a1 fix typo 2019-02-07 10:09:02 -05:00
David Taylor
9f49007b7b FIX: Rescue and display import errors when updating theme via git 2019-02-07 10:08:59 -05:00
Sam
bfceb29db8 DEV: update logster to stable release
This update logster to the stable 2.0.1 release instead of running a pre
release
2019-02-07 10:08:56 -05:00
Gerhard Schlager
d576a3fa57 FIX: S3 endpoint broke bucket creation in non-default region 2019-02-07 10:08:53 -05:00
Kris
12cf3320c2 UX: Turn off autocomplete on composer title 2019-02-07 10:08:50 -05:00
Régis Hanol
1e9a884244 UX: disable browser's autocomplete in search menu 2019-02-07 10:08:47 -05:00
David Taylor
f01ca1f22d FIX: Correctly process {{each}} in raw handlebars templates for themes 2019-02-07 10:08:43 -05:00
Jeff Wong
9564eac72a FIX: Register pan events for touch only
* touch events - only register touch, not pointer events
* immediately request redraw frame, do not wait for after render to fire.
2019-02-07 10:08:40 -05:00
Gerhard Schlager
8573ac0d18 FIX: Unpause Sidekiq before uploading backup to S3
No need to pause Sidekiq longer than really needed. Uploads to S3 can take a long time.
2019-02-07 10:08:37 -05:00
Kris
a36527ca77 Minor icon color fix 2019-02-07 10:08:34 -05:00
Sam
894b98685b FIX: old migration was loading up invalid model schema
Generally we should never be touching AR objects in migrations, this is
super risky as we may end up with invalid schema cache.

This code from 2013 did it unconditionally. This change amends it so:

1. We only load up schema if we have no choice
2. We flush the cache before and after

This makes this migration far less risky.
2019-02-07 10:08:29 -05:00
Kris
5ef75197da UX: Header icon color fix 2019-02-01 17:50:00 +00:00
David Taylor
78eb51f780 SECURITY: Escape HTML in dashboard report tables 2019-02-01 13:11:14 +00:00
David Taylor
94ccedb730 FIX: Login button icons should be white 2019-02-01 11:41:54 +00:00
Kris
34f120c011 Header icon focus color fix 2019-02-01 10:50:40 +00:00
Neil Lalonde
bbb4b6ccef Version bump to v2.2.0 2019-01-31 17:41:36 -05:00
Neil Lalonde
87f89e92a8 Merge diffs from master 2019-01-31 17:24:35 -05:00
Neil Lalonde
23e2a01572 Merge master 2019-01-31 17:18:47 -05:00
Neil Lalonde
a49c0b9bbd Version bump to v2.1.8 2019-01-21 14:59:14 -05:00
Joffrey JAFFEUX
6418caf700 SECURITY: fix possible XSS with badges (#6912) 2019-01-21 13:12:09 +01:00
Neil Lalonde
d72d51711e Version bump to v2.1.7 2019-01-14 17:01:44 -05:00
Sam
4810a841a0 PERF: reduce workload when optimizing images
Previously, we would initialize an ImageOptim object each time we resize.

This object init is mega expensive (170ms on a VERY fast machine):

```
[1] pry(main)> Benchmark.measure { FileHelper.image_optim   }
=> #<Benchmark::Tms:0x00007f55440c1de0
 @cstime=0.055742,
 @cutime=0.141031,
 @label="",
 @real=0.17165619300794788,
 @stime=0.0002750000000000252,
 @total=0.19890400000000008,
 @utime=0.0018560000000000798>

```

This happens cause during init it hunts for all the right binaries and sets
up internals.

We now memoize this object to avoid a huge amount of pointless work.
2019-01-09 12:50:11 +11:00
Neil Lalonde
a632f3e899 Version bump to v2.1.6 2019-01-02 15:12:36 -05:00
Guo Xiang Tan
1590387bd1 SECURITY: Users can pick non-avatar uploads.
https://meta.discourse.org/t/bug-report-idor-on-avatar-pick-function-discussions-udacity-com/103564
2018-12-18 13:57:54 +08:00
Sam
69bc8f526a SECURITY: only allow picking of avatars created by self (#6417)
* SECURITY: only allow picking of avatars created by self

Also adds origin tracking to all uploads including de-duplicated uploads
2018-12-18 13:57:49 +08:00
Neil Lalonde
f1385cf72d Version bump to v2.1.5 2018-12-14 12:20:44 -05:00
David Taylor
62ec0f92ea FIX: Only serialize group membership domains for administrators (#6771) 2018-12-14 15:49:05 +00:00
Sam
d535e1ce6d SECURITY: do not delete avatars uploads when deleting accounts
We rely on the clean up uploads job to do this safely
2018-12-13 16:32:35 +11:00
Sam
1b34a8b48a FIX: remove slow platform detection from server side
Historically due to https://meta.discourse.org/t/why-is-discourse-so-slow-on-android/8823
we decreased page sizes of both home page and topic page on android by half.

This was done on the server side and as a side effect and caused page sizes on android
to mismatch between Android and non Android.

Unfortunately about a year ago googlebot started pretending it is Android,
this cause Google to start indexing pages as what android would see. So
it saw double the amount of pages in the index as what exists on desktop.
This in turn caused double the amount of indexing work and a large amount
of broken links on long topics.

This fix removes all special behavior which is no longer needed due to
other performance work in Discourse including raw handlebars on home page
and virtual dom on topic pages.

I tested we do not need this on Blu Advance 5.0 it has 1.3 GHZ mediatec mt6580
This phone retails for around $50 USD.

If we decide long term that we want any hacks like this we will shift them
to the client side. It can just hold data in memory without rendering.
2018-12-13 16:14:37 +11:00
David Taylor
7828c1156c FIX: Do not serialize user fields unless they are specified for display (#6736) 2018-12-07 11:08:59 +00:00
Guo Xiang Tan
cffb3d7976 SECURITY: Require groups to be given when inviting to a restricted category. (#6715) 2018-12-07 15:54:53 +08:00
Neil Lalonde
e8b51feceb Version bump to v2.1.4 2018-11-29 11:16:23 -05:00
Sam
6b9b73236a SECURITY: enforce hostname to match discourse hostname
This ensures that the hostname rails uses for various helpers always matches
the Discourse hostname

# Conflicts:
#	config/application.rb
#	spec/requests/application_controller_spec.rb
2018-11-15 16:17:22 +11:00
Sam
05b2c5babf SECURITY: update rack from 2.0.5 to 2.0.6
This release contains security fixes to the underlying rack library
used by Discourse.

Impact is not too high as we do not use request.scheme in our templates
2018-11-07 10:06:24 +11:00
David Taylor
e16c1206e5 Version bump to v2.1.3 2018-11-05 11:08:19 +00:00
David Taylor
43ad60d52c SECURITY: Add CSRF protections to OpenID callback 2018-11-05 11:07:35 +00:00
Joffrey JAFFEUX
d37e8e17ef UX: bumps the user-api-key version to 3 (#6526)
* UX: bumps the user-api-key version to 3

* fix spec
2018-11-01 21:29:29 +01:00
Joffrey JAFFEUX
5a114df088 FEATURE: adds latest to user-api-key session scope 2018-11-01 21:29:19 +01:00
Joffrey JAFFEUX
b8aec7777c FEATURE: adds list#(unread|new) to user api key routes (#6494) 2018-11-01 21:29:13 +01:00
Joffrey JAFFEUX
38ad1b96cb FEATURE: adds header text/background color to site (#6462) 2018-11-01 21:29:04 +01:00
Kyle Zhao
5e054e00da SECURITY: update loofah for CVE-2018-16468 2018-10-30 11:37:35 -04:00
Neil Lalonde
caae57a496 Version bump to v2.1.2 2018-10-12 10:46:12 -04:00
Guo Xiang Tan
40559b3881 Fix UploadRecovery from S3 fails with bucket name containing sub-folder. 2018-10-01 20:22:15 +08:00
Guo Xiang Tan
05fe5c9188 Fix onceoff job in cfa7173da3 not running. 2018-10-01 18:37:05 +08:00
Guo Xiang Tan
cf60ae32ea FIX: Onceoff job to fix missing user profile backgrounds. 2018-10-01 18:31:09 +08:00
Sam
b6e7992a3d FIX: correct readonly timeout
So it only applies in readonly mode
2018-09-20 15:19:46 +10:00
Sam
abc39c492a FIX: in redis readonly raise an exception from DistributedMutex
If we detect redis is in readonly we can not correctly get a mutex
raise an exception to notify caller

When getting optimized images avoid the distributed mutex unless
for some reason it is the first call and we need to generate a thumb

In redis readonly no thumbnails will be generated
2018-09-19 15:49:18 +10:00
Sam
d7d5db257b FIX: required rbtrace upgrade
trollop gem was renamed to optimist
2018-09-19 15:29:53 +10:00
Sam
7b70a208ba SECURITY: correct XSS on long topic titles 2018-09-18 08:56:10 +10:00
Sam
c662e0918f SECURITY: remove admin memory diagnostics routes 2018-09-18 08:36:24 +10:00
Guo Xiang Tan
852026dfae Backward compatibility for dropping functions in ColumnDropper.
https://meta.discourse.org/t/launcher-rebuild-error-pg-error-schema-discourse-functions-does-not-exist/96209
2018-09-17 14:52:09 +08:00
Neil Lalonde
b5401af2dc Version bump to v2.1.1 2018-09-14 11:00:12 -04:00
Guo Xiang Tan
8ddcb6564e FIX: Onceoff job to recover missing post uploads.
This fixes the regression due to 1f636c445b
2018-09-14 10:52:33 +08:00
Guo Xiang Tan
9d81a6cc72 DEV: Avoid using send and make the method public instead. 2018-09-14 10:52:16 +08:00
Guo Xiang Tan
ea522589cf Accept custom AR relation for UploadRecovery. 2018-09-14 10:51:55 +08:00
Guo Xiang Tan
1d6597c646 FIX: Do not try to recover invalid Upload#short_url in UploadRecovery. 2018-09-14 10:51:36 +08:00
Guo Xiang Tan
692f2aa395 Fix the build. 2018-09-14 10:51:26 +08:00
Guo Xiang Tan
2176605fc4 Add basic test case for UploadRecovery. 2018-09-14 10:51:20 +08:00
Guo Xiang Tan
50f7e2be64 Rescue errors when running dry run for UploadRecovery. 2018-09-14 10:51:11 +08:00
Guo Xiang Tan
d257b4a386 Fix s3 recovery from tombstone in UploadRecovery. 2018-09-14 10:51:04 +08:00
Guo Xiang Tan
c3c42fd056 Add dry run option to UploadRecovery. 2018-09-14 10:50:53 +08:00
Guo Xiang Tan
f08e7bdbff Fix incorrect variable. 2018-09-14 10:50:46 +08:00
Guo Xiang Tan
797a259702 New rake task uploads:recover. 2018-09-14 10:50:32 +08:00
Guo Xiang Tan
0811379ab3 DEV: Print the error class in uploads:list_posts_with_broken_images. 2018-09-14 10:50:26 +08:00
Guo Xiang Tan
dffd4fa9e6 Add extra protection in Upload#get_from_url.
In case the extension goes missing from the URL.
2018-09-14 10:49:34 +08:00
Régis Hanol
39a2d92417 FIX: don't index urls to local files 2018-09-14 12:31:35 +10:00
Arpit Jalan
74eec1849d FIX: ignore and log bad json values for custom fields 2018-09-13 17:42:48 +05:30
Guo Xiang Tan
f31758cc70 FIX: Uploads not being linked correctly to posts.
Regression due to 1f636c445b.
2018-09-11 23:54:07 -07:00
Neil Lalonde
8922a91c1c Version bump to v2.1.0 2018-09-10 19:39:59 -04:00
Neil Lalonde
ea7ee8e9f7 Merge master 2018-09-10 19:39:09 -04:00
Sam
a5ae7ee8e2 SECURITY: correct edge case when SSO provides unvalidated emails 2018-09-11 08:25:19 +10:00
Neil Lalonde
65cffedc33 Version bump to v2.0.5 2018-08-30 10:49:38 -04:00
David Taylor
825dee5598 SECURITY: Prevent users from modifying custom fields 2018-08-30 13:00:51 +01:00
Vinoth Kannan
3eff6a0e9b DEV: Export Tag class to modify methods in plugin 2018-08-30 16:53:02 +08:00
Guo Xiang Tan
c4de36624f Skip imagemagick tests on Travis. 2018-08-30 16:07:00 +08:00
Guo Xiang Tan
90802053a0 Fix linting on Travis for stable. 2018-08-30 16:04:56 +08:00
Guo Xiang Tan
032f860c86 Fix brittle spec. 2018-08-28 14:29:38 +08:00
Robin Ward
52ca0893e1 FIX: Broken specs 2018-08-28 14:29:38 +08:00
Neil Lalonde
911044f8a0 Version bump to v2.0.4 2018-08-21 11:53:29 -04:00
Guo Xiang Tan
5778c33ee7 FIX: Compatibility with ImageMagick 7.
http://www.imagemagick.org/Usage/misc/

"The "-interpolate" setting of 'Catrom' (generally imprecisely known as 'BiCubic' interpolation)"
2018-08-16 09:49:52 +08:00
Neil Lalonde
37a01975e9 SECURITY: prevent use of X-Forwarded-Host to perform XSS 2018-08-13 17:10:06 -04:00
Neil Lalonde
49681b762a Version bump to v2.0.3 2018-07-26 14:14:22 -04:00
David Taylor
6f5b8f61df FIX: Remove return statement from inside block 2018-07-26 16:00:45 +01:00
Régis Hanol
aeaf6b5a7c SECURITY: force IM decoder based on file extension - part 3 2018-07-25 23:55:41 +02:00
Régis Hanol
01714e40f4 SECURITY: force IM decoder based on file extension - part 2 2018-07-25 23:08:38 +02:00
Régis Hanol
b04b7c366c SECURITY: force IM decoder based on file extension 2018-07-25 22:01:08 +02:00
David Taylor
6520697b5c FIX: Remove plugin.enabled? checks at initialization time (#6166)
Checking `plugin.enabled?` while initializing plugins causes issues in two ways:
- An application restart is required for changes to take effect. A load-balanced multi-server environment could behave very weirdly if containers restart at different times.
- In a multisite environment, it takes the `enabled?` setting from the default site. Changes on that site affect all other sites in the cluster.

Instead, `plugin.enabled?` should be checked at runtime, in the context of a request. This commit removes `plugin.enabled?` from many `instance.rb` methods.

I have added a working `plugin.enabled?` implementation for methods that actually affect security/functionality:
- `post_custom_fields_whitelist`
- `whitelist_staff_user_custom_field`
- `add_permitted_post_create_param`
2018-07-25 16:51:45 +01:00
Robin Ward
878aee965b SECURITY: Consider 0.0.0.0 a private IP 2018-07-24 11:17:13 -04:00
Sam
cf9b4a789b FIX: update mini_racer in stable
This is required due to a bundler/build bug that means it is picking the wrong
version of libv8 when compiling mini_racer
2018-07-24 12:25:45 +10:00
Vinoth Kannan
b7ebb0268f FIX: returns provider_not_enabled error even if enabled 2018-07-16 11:08:48 +01:00
Sam
297b899c68 SECURITY: extra CORS headers should be set on correct host 2018-07-11 09:29:45 +10:00
David Taylor
6f25421a06 SECURITY: Do not allow authentication with disabled plugin-supplied a… (#6071)
Do not allow authentication with disabled plugin-supplied auth providers
2018-07-09 14:26:44 +10:00
Sam
849b4b5685 SECURITY: category badges should HTML escape names 2018-06-28 18:16:12 +10:00
Joffrey JAFFEUX
aafd883466 SECURITY: prevents XSS when showing tooltip 2018-06-27 14:53:31 +02:00
Dax74
612bc4f95b
Link updated
See https://meta.discourse.org/t/wrong-link-on-manual-admin-creation/90849
2018-06-27 11:41:03 +02:00
Neil Lalonde
34ad6749db FIX: missing translations for mobile flag modal 2018-06-25 20:21:47 -04:00
Neil Lalonde
365c99cf3f Version bump to v2.0.2 2018-06-21 10:39:00 -04:00
Sam
f2cb89b0d2 SECURITY: update sprockets for CVE-2018-3760 2018-06-20 09:50:28 +10:00
Guo Xiang Tan
a90364ac6c Monkey patch in 7830a950ef 2018-06-19 10:36:20 +08:00
Neil Lalonde
8c3380791b Version bump to v2.0.1 2018-06-12 12:13:47 -04:00
Joffrey JAFFEUX
5e4a1e812a UX: reworks dashboard problems section to be in line with new style 2018-06-12 11:48:53 -04:00
Arpit Jalan
57f5f7d755 FIX: do not show SSO external_email to moderators 2018-06-12 11:48:10 -04:00
Guo Xiang Tan
ff7cbf6935 FIX: Ensure we have proper timeout for MiniRacer. 2018-06-12 11:48:08 -04:00
Joe
7c9aa82625 FIX: adjust 2FA input width in mobile login form 2018-06-12 11:48:08 -04:00
Joe
1612c28718 FIX: adjust max-width of social login buttons for non-English locals 2018-06-12 11:48:07 -04:00
Neil Lalonde
a8d2d24a49 fix indent 2018-06-12 11:48:07 -04:00
Neil Lalonde
a279e43025 FIX: broken mailto href's in emails 2018-06-12 11:48:07 -04:00
Joffrey JAFFEUX
2b3faa8d0b FIX: do not use number helper for charts Y value 2018-06-12 11:48:06 -04:00
Joffrey JAFFEUX
940c0f569f FIX: incorrect backup and update times on dashboard 2018-06-12 11:48:06 -04:00
Joffrey JAFFEUX
e66d5425e4 FIX: slightly safer rounding 2018-06-12 11:48:06 -04:00
Joffrey JAFFEUX
2f84d43bb2 FIX: makes format number round the value before using parseInt 2018-06-12 11:48:05 -04:00
Joe
134300001c FIX: user-fields layout in desktop create account form 2018-06-12 11:48:05 -04:00
Joffrey JAFFEUX
7c57cd6897 FIX: removes buggy/unnecessary local-dates margin 2018-06-12 11:48:05 -04:00
Joe
cb9753267a FIX: user-fields layout in mobile create account form 2018-06-12 11:48:04 -04:00
Vinoth Kannan
17e7d3b526 FIX: avatar_url includes upload_path twice when local storage used 2018-06-12 11:48:04 -04:00
Guo Xiang Tan
b7865bac27 FIX: Permalink route matcher should always be last. 2018-06-12 11:48:04 -04:00
Guo Xiang Tan
a74d62d618 FIX: Disconnects all connections in the pool before forking.
* We were leaking connections as a result. Connections opened
  before the fork were never closed.
2018-06-12 11:48:03 -04:00
Régis Hanol
db3f31a841 FIX: unable to add new poll to post with a public poll 2018-06-12 11:48:03 -04:00
Joffrey JAFFEUX
9334d36a23 FIX: sharing popup not showing on macos/chrome
Despite `navigator.share` being defined the call was failing with this error:

```
sharing DOMException: Internal error: could not connect to Web Share interface.
```
2018-06-12 11:48:03 -04:00
Robin Ward
e37af71f2e FIX: Protection against dangling category group records 2018-06-12 11:48:02 -04:00
Robin Ward
abbb0ece4f FIX: Keyboard shortcuts didn't work on subfolders 2018-06-12 11:48:02 -04:00
Joe
08aca35b37 FIX: alignment for instructions on change email and 2FA fields 2018-06-12 11:48:02 -04:00
Blake Erickson
afbbdfc05f FIX: Allow a user to remove their title
Somewhere there was a regression and a user couldn't remove their own
title. If they selected '(none)' in the UI it would say it was saved,
but it would not actually be updated in the db.
2018-06-12 11:48:01 -04:00
Neil Lalonde
e90f80e788 Update translations 2018-06-08 10:45:46 -04:00
Neil Lalonde
894d287a7f Version bump to v2.0.0 2018-05-31 18:24:41 -04:00
Kris
0aa8d75be1 safety so pre blocks can't break modal width 2018-05-31 18:23:32 -04:00
Kris
12ebcc325b envelope missing on invite page, long pre lines making modals wide 2018-05-31 18:19:59 -04:00
Neil Lalonde
b675f5fa6b Merge master 2018-05-31 18:19:36 -04:00
Régis Hanol
82148a168f FIX: automatically fix image orientation 2018-05-17 14:55:58 +02:00
Neil Lalonde
fc0e50b34c Version bump to v1.9.7 2018-05-03 16:55:56 -04:00
Sam
3be4982186 clean up drag on iOS handling, we need it bound earlier 2018-04-30 15:58:03 +02:00
Sam
3fee06ae59 improve prev hack 2018-04-30 15:57:58 +02:00
Sam
2e0189afe9 FIX: dragging of timeline was flaky on iOS 2018-04-30 15:57:52 +02:00
Neil Lalonde
3b220d6102 Version bump to v1.9.6 2018-04-24 10:38:53 -04:00
Arpit Jalan
8d1e8fa712 SECURITY: do not show private topic title on /unsubscribed page 2018-04-16 20:05:31 +05:30
Régis Hanol
940b3a7c74 SECURITY: prevent XSS when showing diffs 2018-04-16 15:47:48 +02:00
Arpit Jalan
3edd6622df SECURITY: santize tags when creating new topic via URL 2018-04-16 01:07:47 +05:30
Arpit Jalan
27972c1202 SECURITY: escape HTML entities from topic title 2018-04-16 01:05:56 +05:30
Arpit Jalan
411696b85e SECURITY: do not disclose topic titles on /unsubscribed page to unauthorized users 2018-04-16 01:05:56 +05:30
Neil Lalonde
0bf1c476d7 Version bump to v1.9.5 2018-04-13 10:06:17 -04:00
Guo Xiang Tan
9c2be4dcac FIX: Restorer wasn't rolling back if restore fails.
* This only applies to backup file taken with
  pg_dump 10.3+ and pg_dump 9.5.12+.
2018-04-06 09:45:42 +08:00
Guo Xiang Tan
c39167f5da Fix incorrect function name. 2018-04-05 07:22:10 +08:00
Guo Xiang Tan
f038903423 Clean up unused function left in the database. 2018-04-05 07:22:03 +08:00
Michael Brown
6307790168 backup restorer: tidy pg_dump schema portability logic, add test 2018-04-04 16:51:25 +08:00
Michael Brown
6691a400da restorer: clarify logging 2018-04-04 16:51:20 +08:00
Guo Xiang Tan
e2f6d8b5ca FIX: Restorer was not extracting the patch version in dump file. 2018-04-04 16:51:00 +08:00
Guo Xiang Tan
833314f4b4 Improve grep pattern in restorer. 2018-04-04 16:50:50 +08:00
Guo Xiang Tan
837c0b9a77 Fix version check in restorer. 2018-04-04 16:50:40 +08:00
Guo Xiang Tan
3bccd8c8f3 FIX: Restore process for dump taken with pg_dump 10.3+.
* Since we can no longer restore into a different schema,
  we will move tables in the public schema into the backup schema
  first before restoring the dump file which goes into the public
  schema. The downside to this approach is that we will increase
  the downtime experienced during the restore process. Downtime
  would equal the duration of restoring the dump file.
2018-04-04 16:50:27 +08:00
Will Jordan
ab1ca72865 single quote password in restore command
> Followup to #3283. Quotes passwords passed to shell for backup restore.
2018-04-04 16:50:08 +08:00
Sam
c2ff0f1f3c Update libv8 from 5.9 to 6.3 2018-04-04 16:44:22 +08:00
Neil Lalonde
e24d25ce01 Version bump to v1.9.4 2018-03-07 15:16:48 -05:00
Neil Lalonde
e23b8e7905 SECURITY: sanitize topic title when staff is viewing a user's past flagged posts and deleted topics 2018-03-02 11:59:36 -05:00
Sam
e7f83358aa SECURITY: ensure users have permission when moving categories 2018-03-02 12:13:53 +11:00
Neil Lalonde
a745aa4a3e Version bump to v1.9.3 2018-02-15 17:46:48 -05:00
Sam
7174b100f9 SECURITY: correct local onebox category checks 2018-02-14 10:44:06 +11:00
Robin Ward
f655936b9d SECURITY: Prevent robots from indexing more routes
These routes could contain sensitive material and should never be
indexed for content.
2018-02-04 13:27:33 -05:00
Neil Lalonde
670450bcfc Version bump to v1.9.2 2018-01-23 16:50:09 -05:00
Gerhard Schlager
0ee2c2363b SECURITY: email domain whitelist could be bypassed 2018-01-17 21:49:43 +01:00
Neil Lalonde
b9bc27e539 Version bump to v1.9.1 2018-01-11 15:09:48 -05:00
Arpit Jalan
a13b8182e9 FIX: rescue login required / broken images 2018-01-11 14:30:34 -05:00
Arpit Jalan
f752c22104 FIX: handle invalid password reset token 2018-01-11 14:30:32 -05:00
Vinoth Kannan
8875993ae1 FIX: URI must be ascii only for URI.parse command 2018-01-11 14:30:29 -05:00
Arpit Jalan
243643bf76 FIX: render error message when backup download fails 2018-01-11 14:30:26 -05:00
Joffrey JAFFEUX
253711c233 FIX: correct shushing_face name 2018-01-11 14:30:22 -05:00
Arpit Jalan
bb4eab1267 FIX: do not create duplicate topics
https://meta.discourse.org/t/duplicate-http-https-topics-are-randomly-created/77190
2018-01-11 14:30:19 -05:00
Guo Xiang Tan
7c03b31006 Make rubocop happy. 2018-01-04 09:05:22 +08:00
Neil Lalonde
eaf083f9f0 Version bump to v1.9.0 2018-01-03 16:49:31 -05:00
Neil Lalonde
f83a39f8ba Merge master 2018-01-03 16:49:06 -05:00
Neil Lalonde
c45964bbfd Version bump to v1.8.11 2017-12-20 18:49:18 -05:00
Guo Xiang Tan
c6f5df4caa SECURITY: Don't pass email backup token to sidekiq as a parameter.
* This exposes the token in the Sidekiq dashboard which can be
  viewed by an admin and defeats the purpose of using a token
  in the download backup email ink.
2017-12-18 11:32:26 +08:00
Guo Xiang Tan
56b79ff2b9 Update .travis.yml. 2017-12-14 15:46:10 +08:00
Guo Xiang Tan
fcdd8491a1 Fix broken spec. 2017-12-14 15:43:50 +08:00
Guo Xiang Tan
6d475a15a8 SECURITY: Any group can be invited into a PM. 2017-12-14 15:18:27 +08:00
Sam
5748ad6f66 SECURITY: prevent staged accounts from changing email 2017-12-14 17:27:50 +11:00
Neil Lalonde
f18f608613 Version bump to v1.8.10 2017-10-30 11:18:24 -04:00
Neil Lalonde
504bcf4550 SECURITY: signup without verified email using Google auth 2017-10-16 15:23:32 -04:00
Neil Lalonde
3fd7f69972 Version bump to v1.8.9 2017-10-13 11:29:31 -04:00
Sam
a9bcc935b7 SECURITY: verify that inviter can invite new user to a topics 2017-10-11 09:49:45 +11:00
Neil Lalonde
834eef7b67 Version bump to v1.8.8 2017-09-28 15:19:43 -04:00
Guo Xiang Tan
5137ae8704 SECURITY: Update Nokogiri. 2017-09-25 21:19:35 +08:00
Neil Lalonde
8b6e4d1867 Version bump to v1.8.7 2017-09-14 10:37:26 -04:00
David Taylor
7cd4880e24 SECURITY: Only publish PM reply messagebus notifications to allowed users 2017-09-08 17:33:10 -04:00
Arpit Jalan
d4d548a874 Version bump to v1.8.6 2017-09-01 00:34:04 +05:30
Arpit Jalan
70d4c39bcd SECURITY: do not include links from whispers in topic summary map
https://meta.discourse.org/t/staff-whispers-links-in-whispers-showing-up-publicly-in-topics-summary/69134?u=techapj
2017-09-01 00:25:49 +05:30
Rafael dos Santos Silva
75364c6286 FIX: Make .eslintrc file compatible with eslint 4 take 2 2017-08-29 14:44:46 +08:00
Rafael dos Santos Silva
3413140346 FIX: Make .eslintrc file compatible with eslint 4 2017-08-29 14:44:02 +08:00
Guo Xiang Tan
5f0351348b FIX: Group name was being reverted to non-localized version.
https://meta.discourse.org/t/localized-staff-group-names-changed/65360/16
2017-08-29 14:42:07 +08:00
Neil Lalonde
3982a8ef30 Version bump to v1.8.5 2017-08-16 12:43:22 -04:00
David Taylor
77977dd32c SECURITY: Do not show latest/top topics on 404 for login_required sites 2017-08-13 23:47:41 +05:30
Neil Lalonde
ae8bd6c825 Version bump to v1.8.4 2017-08-01 14:23:50 -04:00
Guo Xiang Tan
62afa41f83 FIX: Exclude www in topic map links.
https://meta.discourse.org/t/topic-popular-links-panel-domain-extraction-doesnt-handle-country-tlds/60156/38?u=tgxworld
2017-07-26 09:58:58 +09:00
Guo Xiang Tan
1797994a63 Revert "UX: Don't try to figure out root domain."
This reverts commit 7690cc6ca5.
2017-07-26 09:58:48 +09:00
Robin Ward
70abd2b033 FIX: Allow discourse app to link directly to wizard 2017-07-10 14:35:51 -04:00
Neil Lalonde
53f3c54e4d Version bump to v1.8.3 2017-07-10 11:43:53 -04:00
Neil Lalonde
2fdbde0253 FIX: invited user should not be able to redeem invite as admin 2017-07-10 11:30:21 -04:00
Robin Ward
7ad2703397 SECURITY: Remove disposable invite feature 2017-07-07 20:52:21 -04:00
Neil Lalonde
b0be304591 Version bump to v1.8.2 2017-07-05 12:20:23 -04:00
Arpit Jalan
6eef7417ab FIX: include canonical meta tag on category pages 2017-07-03 14:45:16 +05:30
Robin Ward
3479298a71 FIX: Topic Entrance wasn't showing up on some suggested topics 2017-06-29 12:54:45 -04:00
Régis Hanol
04bc75b521 FIX: image orientation wasn't properly working 2017-06-23 10:19:38 +02:00
Guo Xiang Tan
787e4e6894 Pin eslint to version 3.x on travis. 2017-06-15 11:44:49 +08:00
Guo Xiang Tan
33291fdec0 Switch to yarn for our travis build. 2017-06-15 11:44:28 +08:00
Guo Xiang Tan
0fc10161a5 FIX: Send request membership PM to last 5 active group owner. 2017-06-15 11:39:16 +08:00
Guo Xiang Tan
84d46bceb9 FIX: Create group membership request on behalf of user. 2017-06-14 21:10:51 +09:00
Guo Xiang Tan
69dc8188e3 UX: Don't send emails for discobot notifications. 2017-06-14 21:09:47 +09:00
Guo Xiang Tan
88dacd4f6b Avoid monkey patching which causes weird reloading error in dev. 2017-06-14 21:09:38 +09:00
Robin Ward
e3bfcbc7c9 FIX: Don't fail seed if avatar can't be downloaded 2017-06-13 10:55:20 -04:00
Robin Ward
5d04cb4b47 FIX: Always allow the host the forum is hosted on 2017-06-13 10:55:15 -04:00
Robin Ward
4324ea024c FIX: Don't use target=_blank for local oneboxes 2017-06-13 10:55:10 -04:00
Robin Ward
28b241295d FIX: Onebox wasn't using correct uri 2017-06-13 10:55:05 -04:00
Robin Ward
075d0ecacc FIX: Support for cookies in onebox redirects 2017-06-13 10:54:56 -04:00
Robin Ward
502bca2c0d FIX: If HEAD is not supported, try GET. Also set cookies 2017-06-13 10:54:27 -04:00
Neil Lalonde
a4be79d297 padding below suggested topics on mobile 2017-06-12 16:13:40 -04:00
Neil Lalonde
91a75d98c8 Version bump to v1.8.1 2017-06-12 12:47:19 -04:00
Guo Xiang Tan
7b902c18a5 FIX: Bot mentioned check should be case insensitive. 2017-06-08 19:01:59 +09:00
Guo Xiang Tan
38cc6dec84 Move the constant as well. 2017-06-06 15:39:39 +09:00
Guo Xiang Tan
b19bc887e8 FIX: Ensure that we cancel any timeout jobs when terminating a track. 2017-06-05 16:28:25 +09:00
Guo Xiang Tan
c7108e077e FIX: Bot should only respond to regular posts. 2017-06-05 15:24:40 +09:00
Régis Hanol
5cd9236f17 FIX: PNG-to-JPEG conversion should only be done to images with at least 1 megapixels 2017-06-03 21:51:33 +02:00
Régis Hanol
a64ef19e39 FIX: automatic PNG-to-JPEG conversion should use a default white background 2017-06-03 21:51:25 +02:00
Guo Xiang Tan
d1b06624ff Revert "Skip validations when Discobot creates new posts."
This reverts commit ca7e906774.

Post validations are already skipped for admin users. Skipping
validations cause polls to not work.
2017-06-03 07:20:32 +09:00
Robin Ward
b906dc4f47 FIX: Don't run in testing mode 2017-06-02 13:08:50 -04:00
Neil Lalonde
81a9137be5 fix narrative bot for subfolder in translation files 2017-06-02 10:50:31 -04:00
Neil Lalonde
3582aa68bf FIX: narrative bot on subfolder installs 2017-06-02 10:50:21 -04:00
Robin Ward
d46f98a8d5 SECURITY: Vunerability in mail gem
(see https://github.com/mikel/mail/pull/1097)
2017-06-01 14:52:38 -04:00
Guo Xiang Tan
55f73fb31f Revert "Load posts in batches while indexing problem posts."
This reverts commit ce57ff9fcf.

Limit is ignored with `find_each`.
2017-06-01 11:31:23 +09:00
Neil Lalonde
d6ec9b3582 Version bump to v1.8.0 2017-05-31 16:18:32 -04:00
Neil Lalonde
44a0ff7688 Merge master 2017-05-31 16:16:17 -04:00
Neil Lalonde
7a434d51b0 Version bump to v1.7.10 2017-05-22 13:48:38 -04:00
Robin Ward
56f5b21a90 SECURITY: Validate the entity when downloading a CSV 2017-05-19 16:01:27 -04:00
Neil Lalonde
7f9c2f75b4 Version bump to v1.7.9 2017-05-15 11:45:43 -04:00
Guo Xiang Tan
d764f76dff Disable failing JS tests first. 2017-05-05 10:01:15 +08:00
Robin Ward
067a54f0df FIX: Regression when clicking on post date 2017-05-04 13:51:24 -04:00
Guo Xiang Tan
989d52a854 FIX: Show share popup only for valid buttons. 2017-05-04 11:20:06 -04:00
Guo Xiang Tan
790acfd99f SECURITY: XSS issue in share popup if invalid link is passed in. 2017-05-04 11:07:49 -04:00
Neil Lalonde
d143cde643 Version bump to v1.7.8 2017-04-10 14:25:07 -04:00
Sam Saffron
f09ca88c47 SECURITY: prefer render plain/html to render text where possible 2017-04-10 08:09:55 -04:00
Sam Saffron
e5c6d0ea65 SECURITY: do not send push notifications to suspended users 2017-04-05 08:29:43 -04:00
Neil Lalonde
33ac94534b Version bump to v1.7.7 2017-03-28 11:32:01 -04:00
Robin Ward
6ede1887b9 FIX: Update omniauth facebook to fix facebook logins 2017-03-27 17:25:23 -04:00
Guo Xiang Tan
e6f06f020d Version bump to v1.7.6 2017-03-23 10:43:43 +08:00
Guo Xiang Tan
db41af1c3c SECURITY: CSRF vulnerabilities in Admin::BackupsController. 2017-03-23 10:42:21 +08:00
Neil Lalonde
15b0a9a16f Version bump to v1.7.5 2017-03-20 11:59:53 -04:00
Guo Xiang Tan
2daed01070 SECURITY: Disallow symlinks when restoring uploads. 2017-03-17 14:29:37 +08:00
Robin Ward
c14d98354b SECURITY: Don't use backticks for exporting your archive 2017-03-16 16:27:52 -04:00
Sam
0f6a2b912a SECURITY: always allow staff to resend activation mails 2017-03-13 10:33:21 -04:00
Guo Xiang Tan
1c44c87945 FIX: Store user's id instead for sending activation email.
* Email and username are both allowed to be used for logging in.
  Therefore, it is easier to just store the user's id rather than
  to store the username and email in the session.
2017-03-13 20:57:21 +08:00
Guo Xiang Tan
8c5e13afd6 SECURITY: Only allow users to resend activation email with a valid session.
* Improve error when an active user tries to request for an activation email.
2017-03-13 20:57:17 +08:00
Guo Xiang Tan
395f43d92f FIX: Don't mark user as active if verified email is different. 2017-03-13 20:57:02 +08:00
Neil Lalonde
f6b43f987c Version bump to v1.7.4 2017-03-08 12:18:34 -05:00
Robin Ward
2c9a43e4fd Revert "SECURITY: Ensure oAuth authenticated email is the same as created user's email."
This reverts commit 1060239e2d.
2017-02-27 13:37:08 -05:00
Guo Xiang Tan
415bad645e FIX: Mobile topic timeline broken on Chrome 56.
* See https://developers.google.com/web/updates/2017/01/scrolling-intervention.
  From Chrome 56 onwards, `touchstart` event listeners are treated as passive
  by default which does not call `preventDefault` resulting in the page
  scrolling when topic timeline handle is being dragged.
2017-02-27 13:21:41 +08:00
Guo Xiang Tan
5cd680b0be SECURITY: Ensure oAuth authenticated email is the same as created user's email. 2017-02-24 15:40:31 +08:00
Guo Xiang Tan
465660bdfc Revert "SECURITY: Ensure that user has been authenticated."
This reverts commit d1091f7f57.
2017-02-24 15:39:56 +08:00
Guo Xiang Tan
d1091f7f57 SECURITY: Ensure that user has been authenticated. 2017-02-24 11:46:59 +08:00
Sam
7912966209 SECURITY: inactive/suspended accounts should be banned from api
Also fixes edge cases around users presenting multiple credentials
2017-02-17 11:09:08 -05:00
Neil Lalonde
a86807b39b Version bump to v1.7.3 2017-02-13 16:45:01 -05:00
Sam
47b9eb6dbb new: server plugin outlet for indexable robots.txt 2017-02-13 14:05:08 -05:00
Sam
1d3f04d4bb SECURITY: correctly validate input when admin searches for screened ips 2017-02-06 16:11:48 -05:00
Sam
5fc70471be UX: less restrictive selector to allow for plugin outlets
Currently plugin outlets in LIs will generate a wrapping SPAN,
this makes an allowence in core for nave extenstions (like solved does)
2017-02-02 12:18:22 -05:00
Neil Lalonde
839a5e6e42 Version bump to v1.7.2 2017-01-26 13:32:57 -05:00
Robin Ward
2f78facb48 SECURITY: Prevent large onebox downloads, better timeout support 2017-01-25 14:59:35 -05:00
Guo Xiang Tan
d4ca8ea617 Fix broken emojis. 2017-01-24 16:18:39 +08:00
Régis Hanol
f49c9f6c43 FIX: log backups download/destroy staff action
FIX: clean up junk left by the specs
RENAME: 'backup_operation' to 'backup_create' to match other backup log types
2017-01-16 19:58:04 +01:00
Robin Ward
8f34c2332d Version bump to v1.7.1 2017-01-13 11:08:58 -05:00
Régis Hanol
9f3c38832e FIX: don't onebox to IP addresses 2017-01-12 22:36:59 +01:00
Neil Lalonde
d20cbfb2b3 Version bump to v1.7.0 2017-01-06 16:08:01 -05:00
Neil Lalonde
be2fa971df Merge master 2017-01-06 15:56:48 -05:00
Robin Ward
ad9af94ac9 SECURITY: Moderators should not be able to access customizations 2017-01-06 14:43:30 -05:00
Guo Xiang Tan
b0fe5d383e Version bump to 1.6.10. 2016-12-21 12:07:13 +08:00
Guo Xiang Tan
33a05b9406 SECURITY: Users can only bookmark posts which they can see. 2016-12-21 12:06:56 +08:00
Sam
c10dfe0d1b SECURITY: prevent reuse of password reset 2016-12-19 18:04:55 +11:00
Sam
9db22bfd3d SECURITY: update onebox gem 2016-12-19 13:21:47 +11:00
Sam
402f06de27 SECURITY: protect upload params, only allow very strict filenames 2016-12-19 10:18:32 +11:00
Neil Lalonde
8a461e6283 Version bump to v1.6.9 2016-12-14 14:56:40 -05:00
Robin Ward
edeabc81a9 SECURITY: Update to latest onebox gem 2016-12-14 12:51:32 -05:00
Neil Lalonde
af0fbb693e Version bump to v1.6.8 2016-11-28 16:05:54 -05:00
Robin Ward
f71c9758a9 Backport get-owner API so plugins can use it safely 2016-11-21 11:16:49 -05:00
Rafael dos Santos Silva
64b0a4eada Version bump to v1.6.7 2016-11-14 19:27:06 -02:00
Sam
bdbd01ce40 fix oops 2016-11-14 19:24:46 -02:00
Sam
4c226bf12d FIX: properly reset all contexts after forking
Fixes hang on backup
2016-11-14 19:24:34 -02:00
Rafael dos Santos Silva
d5ba32ab2f Version bump to v1.6.6 2016-11-03 22:01:37 -02:00
Sam
90ef577037 FIX: mini_racer will no longer Dispose forked isolates 2016-11-03 20:05:59 -02:00
Sam
98d87a3ed2 update mini_racer to latest version 2016-11-03 20:05:53 -02:00
Neil Lalonde
1d76d255d5 Version bump to v1.6.5 2016-11-02 13:46:41 -04:00
Guo Xiang Tan
2bce183581 FIX: User enabled readonly mode was not working. 2016-10-25 11:50:51 +08:00
Guo Xiang Tan
2c86c202e5 FIX: Randomly failing specs try 2. 2016-09-23 15:05:03 +08:00
Guo Xiang Tan
46732957bc Version bump to v1.6.4 2016-09-23 14:48:07 +08:00
Guo Xiang Tan
5b3cbd3c9d FIX: Make sure constant reflects the right backup extenstion. 2016-09-23 14:46:59 +08:00
Guo Xiang Tan
e4c5cb84cd Version bump to v1.6.3 2016-09-19 08:54:54 +08:00
cpradio
ef440a4381 Escape the hyphen 2016-09-19 08:54:21 +08:00
cpradio
69691fa7a6 FIX: Backup validation wasn't escaping hyphens
Conflicts:
	spec/controllers/admin/backups_controller_spec.rb
2016-09-19 08:53:54 +08:00
Neil Lalonde
cbe623aaee Version bump to v1.6.2 2016-09-16 11:37:30 -04:00
Guo Xiang Tan
82fe884a7f SECURITY: Add filename validation for backup uploads. 2016-09-16 12:50:59 +08:00
Guo Xiang Tan
49ceac26d5 SECUIRTY: Escape input made to system calls. 2016-09-16 12:50:46 +08:00
Neil Lalonde
f7a335a64e Version bump to v1.6.1 2016-08-12 11:45:46 -04:00
Arpit Jalan
746ab933a0 Update Translations 2016-08-12 10:40:41 -04:00
Robin Ward
40d91ff504 FIX: Travis failure 2016-08-11 13:49:14 +08:00
Guo Xiang Tan
adb1e2cbc8 SECURITY: Escape HTML in filename. 2016-08-11 13:48:23 +08:00
Guo Xiang Tan
515024a0ac SECURITY: Escape image title in lightbox. 2016-08-11 11:17:37 +08:00
Régis Hanol
6d2a687ec7 FIX: wasn't able to update category's settings 2016-08-09 23:57:50 +02:00
Sam
0b5c3f5a03 SECURITY: do cookie auth rate limiting earlier 2016-08-09 10:04:49 +10:00
Guo Xiang Tan
1acef41e51 Revert "UX: Centering Badge notification styles on mobile."
This reverts commit fce902ab1e.
2016-08-08 09:36:07 +08:00
Neil Lalonde
4c14894958 Version bump to v1.6.0 2016-08-05 15:15:00 -04:00
Neil Lalonde
2499b56594 Merge master 2016-08-05 15:13:33 -04:00
Robin Ward
b17908fab1 SECURITY: XSS issue on Admin users list 2016-08-05 12:48:33 -04:00
Robin Ward
a139e469a7 SECURITY: Avoid mass assignment on user create 2016-08-05 12:43:50 -04:00
Robin Ward
a1e94cb1c1 FIX: Broken test 2016-08-05 12:41:29 -04:00
Robin Ward
9adfccfad1 FIX: Regression with escaping on badge page
In this branch (stable) we can't run the sanitizer because the bundle is not
loaded. The long badge description is not sanitized, but it
has to be created by an admin so it's extremely low risk.

In the beta / tests-passed branches the text is sanitized.
2016-07-28 16:11:41 -04:00
Robin Ward
5d062206db SECURITY: Make sure uploaded_urls have corresponding upload records 2016-07-28 15:41:03 -04:00
Robin Ward
f416634ea0 SECURITY: Cross-Site Scripting in Category and Group Settings 2016-07-28 15:30:53 -04:00
Robin Ward
80834df757 SECURITY: SQL Injection in Admin List Active Users 2016-07-28 15:29:16 -04:00
Robin Ward
90a3cc7f18 SECURITY: XSS in "Account Suspended" Messages and Badge Descriptions 2016-07-28 15:29:05 -04:00
Sam
f319923753 SECURITY: limit route access when using external avatars 2016-07-28 09:04:32 +10:00
Neil Lalonde
c8081af728 Version bump to v1.5.4 2016-07-26 11:47:38 -04:00
Guo Xiang Tan
cd5842d38b SECURITY: Possible SQL injection. 2016-07-19 13:03:00 +08:00
Neil Lalonde
ba3f7936a8 Version bump to v1.5.3 2016-06-21 11:44:32 -04:00
Sam
40a4aa4313 SECURITY: update logster 2016-06-20 12:15:54 +10:00
Sam
2b81c593f5 SECURITY: restrict constantize classes in search controller 2016-06-17 13:48:15 +10:00
Robin Ward
1e241dedad SECURITY: Unapproved, active users should not receive emails 2016-06-16 13:09:47 -04:00
Neil Lalonde
77d9467818 Version bump to v1.5.2 2016-05-19 12:23:46 -04:00
Sam
416e78796b SECURITY: update rack-mini-profiler 2016-05-18 18:34:02 +10:00
Régis Hanol
6dfd8ed47e SECURITY: 2 XSSs in post gutter and local oneboxes 2016-05-14 00:09:11 +02:00
Neil Lalonde
47e932159e Version bump to v1.5.1 2016-04-07 14:07:44 -04:00
Neil Lalonde
dc71f6b9d9 Update Translations 2016-04-07 13:51:31 -04:00
Neil Lalonde
01b6bc08ba Merge fixes from master 2016-04-07 13:51:05 -04:00
Neil Lalonde
aa91e4c1ac Version bump to v1.5.0 2016-03-31 17:51:08 -04:00
Robin Ward
b32d727d95 FIX: Bad auto merge 2016-03-31 17:42:16 -04:00
Neil Lalonde
01d0aeb5a9 merge master 2016-03-31 17:40:54 -04:00
Neil Lalonde
95f2ac6535 Version bump to v1.4.7 2016-03-17 12:18:18 -04:00
Arpit Jalan
331a9c8a2f SECURITY: Backport XSS fix 2016-03-08 21:08:05 +05:30
Régis Hanol
f9710d0d7c FIX: unescape emojis in digests 2016-03-08 21:05:50 +05:30
Neil Lalonde
7376e4000c Version bump to v1.4.6 2016-02-22 11:26:15 -05:00
Robin Ward
9f56d61305 Backported PluginAPI for compatibility with plugins 2016-02-17 12:19:07 -05:00
Régis Hanol
e953c1c5a6 fix eslint 2016-02-05 16:10:49 +01:00
Régis Hanol
28e4ea3178 we still need md5 2016-02-05 16:01:23 +01:00
Sam Saffron
45a166b315 SECURITY: hoist blocks using guids, not md5 hashes 2016-02-05 16:01:15 +01:00
Neil Lalonde
2e1aee861c Version bump to v1.4.5 2016-02-04 13:42:55 -05:00
Sam Saffron
51da6676f0 SECURITY: topic titles can show up in user page unescaped when streamed in 2016-02-01 21:02:23 +11:00
Régis Hanol
9e22fa91e8 SECURITY: fix XSS in lazyYT plugin 2016-01-30 12:40:54 +01:00
Neil Lalonde
304fc70079 Version bump to v1.4.4 2016-01-25 13:39:32 -05:00
Robin Ward
b792629208 FIX: Precompiler should apply get magic too 2016-01-15 15:26:19 -05:00
Robin Ward
2ad461f218 SECURITY: Upgrade Ember to fix CVE-2015-7565. Also upgrade Handlebars 2016-01-15 15:23:58 -05:00
Robin Ward
a0ee652f2e Revert "SECURITY: Upgrade Ember to fix CVE-2015-7565"
This reverts commit 211521df4f.
2016-01-15 11:39:56 -05:00
Robin Ward
8a61393d68 SECURITY: Upgrade Ember to fix CVE-2015-7565 2016-01-15 11:31:51 -05:00
Neil Lalonde
e7e6d370e0 Version bump to v1.4.3 2015-11-25 17:16:51 -05:00
Robin Ward
189595466c SECURITY: Backported XSS fixes from Handlebars 2015-11-24 16:30:52 -05:00
Robin Ward
e9f80464b4 SECURITY: XSS Protection on Queued Posts 2015-11-20 14:28:03 -05:00
Neil Lalonde
a324c71869 Version bump to v1.4.2 2015-10-19 17:33:28 -04:00
Robin Ward
c72f0160de SECURITY: Unread post notifications should respect whispers 2015-10-19 16:32:55 -04:00
Robin Ward
7f24b601c8 FIX: Broken spec 2015-10-14 16:13:42 -04:00
Robin Ward
b7bdaac081 SECURITY: Moderators should not see API keys 2015-10-14 15:46:46 -04:00
Sam
1fef49a094 SECURITY: XSS in search results term
Thanks to Jerbi Nessim
2015-10-07 10:53:48 +11:00
Neil Lalonde
04bd7d182f Version bump to v1.4.1 2015-10-02 11:06:58 -04:00
Sam
fe786dfc64 FIX: don't use Safari hack on Windows Phone 2015-09-28 17:20:54 +10:00
Robin Ward
41c5b262b2 FIX: max_topics_per_day was not working 2015-09-25 12:47:38 -04:00
Robin Ward
68a92e6656 FIX: Allow mods/admins to search whispers 2015-09-25 12:47:38 -04:00
Robin Ward
52ad4259d4 FIX: Replies to whispers *must* be whispers 2015-09-25 12:47:38 -04:00
Régis Hanol
e13906d5fb FIX: replaceMarkdown should be smart about current caret position 2015-09-25 12:47:38 -04:00
Sam
be8a20db67 FIX: disable cloaked view while running ios positioning hack 2015-09-25 12:47:38 -04:00
Sam
2f3bc60e59 FIX: whispers should not be revealed in reply to, or reply expansion
FEATURE: mark whisper as experimental
FIX: badges should never apply to whispers
2015-09-25 12:47:38 -04:00
Jeff Atwood
b1c81179f5 tweaks to readme 2015-09-25 12:47:38 -04:00
Jeff Atwood
241315ddd1 update readme images for 1.4 2015-09-25 12:47:37 -04:00
Jeff Atwood
3fa5180025 minor install guide tweaks 2015-09-25 12:47:37 -04:00
Jeff Atwood
64f6e41164 minor install guide tweaks 2015-09-25 12:47:37 -04:00
Sam
d7f2933743 FIX: when replying to a expanded reply, correctly attribute author 2015-09-25 12:47:37 -04:00
Jeff Atwood
80893a69ba FIX: 1.4 welcome PM images needed update 2015-09-25 12:47:37 -04:00
Robin Ward
7a155710dd FIX: Category Logo preview should not repeat 2015-09-25 12:47:37 -04:00
Régis Hanol
931812ce69 FIX: only disable the composer grip when the device is touch-only 2015-09-25 12:47:37 -04:00
Régis Hanol
33f689357a FIX: pikaday wasn't working when using the mouse with a touch-enabled monitor 2015-09-25 12:47:37 -04:00
Jeff Atwood
831223d815 emphasize reading the admin quick start guide 2015-09-25 12:47:37 -04:00
Jeff Atwood
5922e2cf26 simplify install guide a tiny bit 2015-09-25 12:47:37 -04:00
Jeff Atwood
49b4b503e3 update install guide for Discourse 1.4 2015-09-25 12:47:36 -04:00
Sam
b2e3703ae7 Revert "UX: always show logout link in user menu, use CSS to hide"
oops was on wrong branch

This reverts commit 2cbb49baec.
2015-09-25 12:16:17 +10:00
Sam
2cbb49baec UX: always show logout link in user menu, use CSS to hide
.menu-panel .logout-link {display: none}
2015-09-25 12:14:20 +10:00
Sam
60a8e203db Revert "FIX: properly filter badges when they're on a whisper"
This reverts commit 584a170534.
2015-09-25 10:22:08 +10:00
Régis Hanol
584a170534 FIX: properly filter badges when they're on a whisper 2015-09-25 00:39:39 +02:00
Régis Hanol
62b493281e FIX: notifications & messages were missing from user profile 2015-09-24 19:17:06 +02:00
Robin Ward
4236317f69 FIX: Double load sometimes on topic lists 2015-09-23 16:41:01 -04:00
Neil Lalonde
8be92d4de9 Version bump to v1.4.0 2015-09-22 15:08:51 -04:00
Neil Lalonde
65e159b073 Merge master 2015-09-22 15:00:32 -04:00
Neil Lalonde
a4c7f55a48 Version bump to v1.3.5 2015-09-09 11:38:13 -04:00
Sam
7bf12891f7 SECURITY: fix possible XSS expanding quotes 2015-09-08 15:27:48 +10:00
Neil Lalonde
30e2b579c1 Version bump to v1.3.4 2015-07-30 15:45:05 -04:00
Robin Ward
a716f9857b SECURITY: Make sure export CSV is generated via a POST 2015-07-24 12:38:58 -04:00
Neil Lalonde
e180e55c4e Version bump to v1.3.3 2015-07-17 11:21:48 -04:00
Sam
f8ba5346c4 SECURITY: Remove email validation check bypass
- Increase size of email column to varchar(513)
 - Give error message on signup when email is too large

Overall impact: Low, allows signups from blocked domains. Main risk is increased spam.
2015-07-14 09:46:00 +10:00
Neil Lalonde
bffaf5a117 Version bump to v1.3.2 2015-06-11 15:57:56 -04:00
Robin Ward
c2dde1ae88 PERF: Debounce mention lookup, enforce minimum username 2015-06-11 15:15:54 -04:00
Arpit Jalan
0083697dff FIX: fix category badge and link in email digest 2015-06-11 13:22:52 -04:00
Sam Saffron
32b17c628a SECURITY: Query @usernames in bulk
Otherwise you could add many requests at once while composing.
2015-06-11 13:12:01 -04:00
Sam Saffron
098b292c0f PERF: production assets not minified
source url post processor forcing all scripts into an eval,
  minifier can not minify such files
2015-06-11 10:06:11 -04:00
Sam Saffron
62e260c69c FEATURE: improve no-js topic list information
- Provide links to pages
- Provied link to last topic
2015-06-10 16:41:45 -04:00
Sam Saffron
51f9e3fc45 Attempt micro data using old vocubulary
Seeing weird results on Google
2015-06-10 16:41:39 -04:00
Arpit Jalan
0393aa63d4 FIX: when sending private message emails do not check email_direct setting 2015-06-10 16:41:33 -04:00
Robin Ward
ccaf525e8d FIX: Bad page title for categories view by google crawler 2015-06-10 16:41:27 -04:00
Arpit Jalan
ce0830b23f FIX: send 404 error when unauthorized user tries to download user archive 2015-06-10 16:41:23 -04:00
Régis Hanol
03fcf99039 FIX: missing emoji autocomplete 2015-06-10 16:40:39 -04:00
Régis Hanol
28d219dfed new 'uploads:migrate_to_new_pattern' task 2015-06-10 16:39:07 -04:00
Robin Ward
7302f6b60b Simple "cook" for email imports from mailing lists 2015-06-10 16:39:01 -04:00
cpradio
2c05e447c3 FEATURE: Use created_at to remove an ip if its last_match_at is null 2015-06-10 16:38:53 -04:00
Sam Saffron
e5d2b49119 correct specs 2015-06-10 16:38:47 -04:00
Sam Saffron
2c883833eb FEATURE: we need admin login always 2015-06-10 16:38:42 -04:00
Arpit Jalan
10c44763aa FIX: staff should be immune to max_invites_per_day setting 2015-06-10 16:38:37 -04:00
Neil Lalonde
f2353fa430 FEATURE: plugins can register a custom admin quick start topic that will be seeded into new sites 2015-06-10 16:38:22 -04:00
Régis Hanol
38090b0b94 we don't care about convert output/errors 2015-06-10 16:38:18 -04:00
Sam Saffron
7f35538bfc update memory profiler, oj and lru redux 2015-06-10 16:38:12 -04:00
Jeff Atwood
28c261238e lighter quote controls 2015-06-10 16:37:58 -04:00
Jeff Atwood
3a78783574 fix minor alignment issues with expanded posts 2015-06-10 16:37:52 -04:00
Sam Saffron
59ab3a7b2b SECURITY: expire all existing email tokens on password reset 2015-06-05 14:15:41 -04:00
Sam Saffron
3151192626 SECURITY: expire all existing sessions if user changes passwords 2015-06-05 13:18:59 -04:00
Robin Ward
ec88c08f24 Never enqueue posts from staff 2015-06-05 12:35:45 -04:00
Neil Lalonde
85b4e5fb0d Version bump to v1.3.1 (skip 1.3.0) 2015-06-03 17:03:29 -04:00
Neil Lalonde
4b0f33cc80 Version bump to v1.3.0 2015-06-03 16:52:09 -04:00
Neil Lalonde
8fec29ab32 Merge master 2015-06-03 16:51:28 -04:00
Neil Lalonde
1ca1c0d146 Revert "Version bump to v1.3.0" 2015-06-01 16:54:15 -04:00
Neil Lalonde
327781660f Version bump to v1.3.0 2015-06-01 15:28:01 -04:00
Neil Lalonde
3e317b40da Merge master 2015-06-01 15:27:35 -04:00
Neil Lalonde
4e187334b3 Version bump to v1.2.4 2015-05-11 18:52:22 -04:00
Sam
27b1e173fd Revert "S3 deprecation warning"
This reverts commit 1095e165d5.
2015-05-12 08:34:17 +10:00
Sam
e31e8ba0de Revert "add global notice for S3 deprecation warning"
This reverts commit d97d1d7438.
2015-05-12 08:34:04 +10:00
Neil Lalonde
dac7d92c75 Version bump to v1.2.3 2015-04-22 11:10:12 -04:00
Sam
34c3b2966c SECURITY: log off all existing sessions when resetting password 2015-04-15 09:05:18 +10:00
Neil Lalonde
9cb6ba0f8f Version bump to v1.2.2 2015-04-13 14:57:32 -04:00
Régis Hanol
d97d1d7438 add global notice for S3 deprecation warning 2015-03-30 11:29:48 +02:00
Neil Lalonde
ddaba0a148 add classes to global-notices so they can be found with selectors 2015-03-30 11:29:38 +02:00
Régis Hanol
1095e165d5 S3 deprecation warning 2015-03-25 18:35:48 +01:00
Neil Lalonde
590b73e25e Version bump to v1.2.1 2015-03-12 17:24:06 -04:00
Robin Ward
d57c5fc950 FIX: 6to5 was renamed to Babel
I can't believe they just pulled the old gem and broke people deploying
our site to production. I get it, your name changed, but don't break
other people's apps with no deprecations.
2015-03-05 13:37:30 -05:00
Sam
faad2c9013 Revert "FIX: when allow uncategorized was off we were still showing uncat for admins/mods"
This reverts commit e8ca1f9818.
2015-02-20 17:40:27 +11:00
Sam
e8ca1f9818 FIX: when allow uncategorized was off we were still showing uncat for admins/mods 2015-02-20 17:30:31 +11:00
Sam
b6bbf36c03 URGENT: commit snuck in twice when merging master 2015-02-20 11:15:12 +11:00
Neil Lalonde
f6e9293840 Version bump to v1.2.0 2015-02-19 16:19:48 -05:00
Neil Lalonde
16bea87fd3 Merge master 2015-02-19 16:17:51 -05:00
Robin Ward
980e97ec28 Merge pull request #3192 from riking/patch-xss
SECURITY: missed html escaping
2015-02-10 17:21:59 -05:00
Arpit Jalan
8205f65573 FIX: full user names were showing up in crawlers and rss feeds in spite enables_names setting being disabled 2015-01-22 12:38:00 -05:00
Robin Ward
f5e0cf63f6 SECURITY: The SSO return_path was an open redirect
This security fix needs SSO to be configured, and the user has to go
through the entire auth process before being redirected to the wrong host so
it is probably lower priority for most installs.
2015-01-22 12:33:07 -05:00
Robin Ward
f7f2e83cfb SECURITY: Don't whitelist codepen as it is a potential vector for abuse 2015-01-21 14:02:22 -05:00
Neil Lalonde
603108cd54 Version bump to v1.1.3 2014-12-12 14:37:30 -05:00
Régis Hanol
0138ecc99a SECURITY: prevent direct download of backups 2014-12-03 13:02:42 +01:00
Neil Lalonde
89f5ea02f6 Version bump to v1.1.2 2014-11-21 11:26:26 -05:00
Sam
abff1e88d4 FIX: PM title not editable 2014-11-21 11:09:35 +11:00
Régis Hanol
e0a4a7a9cd FEATURE: don't limit registration from an IP address if a staff member has that IP address 2014-11-21 00:34:31 +01:00
Jeff Atwood
4d1ac30233 fix pop up composer tips display for mobile 2014-11-21 00:34:24 +01:00
Neil Lalonde
6e0152ab94 Version bump to v1.1.1 2014-11-18 15:57:50 -05:00
Neil Lalonde
e210e08e95 Version bump to v1.1.0 2014-11-06 15:35:56 -05:00
Neil Lalonde
361aca1156 merge master 2014-11-06 15:26:38 -05:00
Neil Lalonde
35628c709b Version bump to v1.0.4 2014-10-30 16:55:05 -04:00
Robin Ward
013e3312ad SECURITY: Don't allow redirects with periods in case you don't control
other tlds on the same domain.
2014-10-30 11:32:26 -04:00
Régis Hanol
38e0c6645e FIX: prevent iframe in expended quote 2014-10-28 23:18:08 +01:00
Neil Lalonde
a412c3016e Version bump to v1.0.3 2014-10-03 11:00:33 -04:00
Robin Ward
59c1215e3b SECURITY: RegExp engine loopwith improperly formatted URLs. 2014-09-26 13:51:34 -04:00
Sam
48145e8e23 SECURITY: rate limit user/password login 2014-09-25 10:13:13 +10:00
Neil Lalonde
f02898f834 Version bump to v1.0.2 2014-09-23 13:17:32 -04:00
Neil Lalonde
6fe364e7ae SECURITY: rate limit change email requests 2014-09-18 10:49:43 -04:00
Robin Ward
570e3b3e79 SECURITY: Stripping links could unescape html fragments 2014-09-17 12:09:06 -04:00
Robin Ward
e4287d9de9 FIX: Resend activation email was busted 2014-09-16 10:24:02 -04:00
Sam Saffron
6646b23569 SECURITY: Escape strings in logs 2014-09-16 07:54:46 +10:00
Robin Ward
344991adb7 SECURITY: Malformed URL could crash V8 2014-09-12 13:21:04 -04:00
riking
3d3313d5ee SECURITY: Limit passwords to 200 characters
Prevents layer 8 attack.
2014-09-12 12:21:06 -04:00
Neil Lalonde
1f797d5d31 Version bump to v1.0.1 2014-09-05 12:29:45 -04:00
Sam
d7a2a65f1f SECURITY: GitHub authenticator returning unverified emails 2014-09-03 12:56:02 +10:00
Robin Ward
8ced44a766 SECURITY: User action route was returning too much data 2014-08-29 13:57:47 -04:00
Robin Ward
9ad246affe SECURITY: Only redirect to our host by path on the login action 2014-08-28 17:57:38 -04:00
8502 changed files with 343911 additions and 531734 deletions

View File

@ -1,16 +1,13 @@
{
"name": "Discourse",
"image": "discourse/discourse_dev:release",
"workspaceMount": "source=${localWorkspaceFolder}/../..,target=/var/www/discourse,type=bind",
"workspaceFolder": "/var/www/discourse",
"settings": {
"search.followSymlinks": false
},
"postStartCommand": "sudo /sbin/boot",
"extensions": ["rebornix.Ruby"],
"forwardPorts": [9292],
"remoteUser": "discourse",
"remoteEnv": {
"DISCOURSE_DEV_HOSTS": ".githubpreview.dev"
}
}
"name": "Discourse",
"image": "discourse/discourse_dev:release",
"workspaceMount": "source=${localWorkspaceFolder}/../..,target=/var/www/discourse,type=bind",
"workspaceFolder": "/var/www/discourse",
"settings": {
"terminal.integrated.shell.linux": "/bin/bash"
},
"postCreateCommand": "sudo /sbin/boot",
"extensions": ["rebornix.Ruby"],
"forwardPorts": [9292],
"remoteUser": "discourse"
}

View File

@ -12,6 +12,3 @@ indent_size = 2
[*.md]
trim_trailing_whitespace = false
[*.hbs]
insert_final_newline = false

View File

@ -1,15 +1,18 @@
app/assets/javascripts/browser-update.js
app/assets/javascripts/discourse-loader.js
app/assets/javascripts/env.js
app/assets/javascripts/main_include_admin.js
app/assets/javascripts/vendor.js
app/assets/javascripts/locales/i18n.js
app/assets/javascripts/ember-addons/
app/assets/javascripts/discourse/lib/autosize.js
lib/javascripts/locale/
lib/javascripts/messageformat.js
lib/javascripts/messageformat-lookup.js
lib/pretty_text/
lib/highlight_js/
plugins/**/lib/javascripts/locale
public/
vendor/
app/assets/javascripts/discourse/tests/test-boot-rails.js
app/assets/javascripts/discourse/tests/fixtures
node_modules/
spec/
dist/
tmp/
documentation/

View File

@ -2,8 +2,7 @@
"extends": "eslint-config-discourse",
"rules": {
"discourse-ember/global-ember": 2,
"eol-last": 2,
"no-restricted-globals": 0
"eol-last": 2
},
"globals": {
"_": "off",
@ -17,12 +16,10 @@
"currentURL": "off",
"currentUser": "off",
"Discourse": "off",
"Ember": "off",
"exists": "off",
"fillIn": "off",
"find": "off",
"getSettledState": "off",
"globalThis": "readonly",
"hasModule": "off",
"invisible": "off",
"jQuery": "off",

View File

@ -53,21 +53,5 @@ ce3fe2f4c4ddf166949ee3cec3d9ecbf9108ab52
# DEV: Tidy up imports. (#11364)
1c2358ba162eb9f9ba9095c9afe30cf51dd85e04
# DEV: Sort imports alphabetically (#11382)
# DEV: Sort imports alphabetically (#11382)
bbe5d8d5cf1220165842985c0e2cd4c454d501cd
# DEV: Template colocation for sidebar files
95c7cdab941a56686ac5831d2a5c5eca38d780c5
# DEV: Apply prettier to hbs files
c8e2e37fa77d3c3c69c7572866017e9bb92befa3
# DEV: Apply syntax_tree to...
5a003715d366e1d871f9fcb0656dc9e23e9c2259
64171730827c58df26a7ad75f0e58f17c2add118
b0fda61a8e75c81e3458c8af9d2afe9d32183457
cb932d6ee1b3b3571e4d4d9118635e2dbf58f0ef
0cf6421716d0908da57ad7743a2decb08588b48a
7c77cc6a580d7cb49f8c19ceee8cfdd08862259d
436b3b392b9c917510d4ff0d73a5167cd3eb936c
055310cea496519a996b9c3bf4dc7e716cfe62ba

View File

@ -1,50 +1,42 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: bundler
directory: "/"
schedule:
interval: daily
time: "08:00"
timezone: Australia/Sydney
open-pull-requests-limit: 20
versioning-strategy: lockfile-only
allow:
- dependency-type: direct
- dependency-type: indirect
ignore:
- dependency-name: aws-partitions
versions:
- "> 1.329.0"
- "< 2"
- dependency-name: aws-sdk-core
versions:
- "> 3.99.1"
- "< 4"
- dependency-name: aws-sdk-kms
versions:
- "> 1.31.0"
- "< 2"
- dependency-name: aws-sdk-s3
versions:
- "> 1.66.0"
- "< 2"
- dependency-name: aws-sdk-sns
versions:
- "> 1.25.1"
- "< 2"
- dependency-name: aws-sigv4
versions:
- "> 1.2.0"
- "< 2"
- package-ecosystem: "npm"
directory: "/app/assets/javascripts/"
schedule:
interval: daily
time: "08:00"
timezone: Australia/Sydney
open-pull-requests-limit: 20
versioning-strategy: increase
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: bundler
directory: "/"
schedule:
interval: daily
time: "08:00"
timezone: Australia/Sydney
open-pull-requests-limit: 10
versioning-strategy: lockfile-only
allow:
- dependency-type: direct
- dependency-type: indirect
ignore:
- dependency-name: aws-partitions
versions:
- "> 1.329.0"
- "< 2"
- dependency-name: aws-sdk-core
versions:
- "> 3.99.1"
- "< 4"
- dependency-name: aws-sdk-kms
versions:
- "> 1.31.0"
- "< 2"
- dependency-name: aws-sdk-s3
versions:
- "> 1.66.0"
- "< 2"
- dependency-name: aws-sdk-sns
versions:
- "> 1.25.1"
- "< 2"
- dependency-name: aws-sigv4
versions:
- "> 1.2.0"
- "< 2"

2
.github/labeler.yml vendored
View File

@ -1,2 +0,0 @@
chat:
- plugins/chat/**/*

View File

@ -0,0 +1,49 @@
name: (experimental) Ember CLI tests (plugins)
on:
schedule:
- cron: "0 0 * * *"
jobs:
build:
name: run
runs-on: ubuntu-latest
container: discourse/discourse_test:slim-browsers
timeout-minutes: 60
steps:
- uses: actions/checkout@master
with:
fetch-depth: 1
- name: Setup Git
run: |
git config --global user.email "ci@ci.invalid"
git config --global user.name "Discourse CI"
- name: Get yarn cache directory
id: yarn-cache-dir
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Yarn cache
uses: actions/cache@v2
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Official Plugins Install
run: |
bundle config --local path vendor/bundle
bundle config --local deployment true
bundle config --local without development
bundle install --jobs 4
bundle clean
bundle exec rake plugin:install_all_official
- name: QUnit
working-directory: ./app/assets/javascripts/discourse
run: QUNIT_EMBER_CLI=1 sudo -E -u discourse -H rake plugin:qunit
timeout-minutes: 60

View File

@ -1,14 +0,0 @@
name: "Pull Request Labeler"
on:
- pull_request_target
jobs:
triage:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v4
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"

View File

@ -1,87 +0,0 @@
name: Licenses
on:
pull_request:
push:
branches:
- main
concurrency:
group: licenses-${{ format('{0}-{1}', github.head_ref || github.run_number, github.job) }}
cancel-in-progress: true
permissions:
contents: read
jobs:
build:
if: "!(github.event_name == 'push' && github.repository == 'discourse/discourse-private-mirror')"
name: run
runs-on: ubuntu-latest
container: discourse/discourse_test:slim
timeout-minutes: 10
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Setup Git
run: |
git config --global user.email "ci@ci.invalid"
git config --global user.name "Discourse CI"
- name: Bundler cache
uses: actions/cache@v3
with:
path: vendor/bundle
key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gem-
- name: Setup gems
run: |
bundle config --local path vendor/bundle
bundle config --local deployment true
bundle config --local without development
bundle install --jobs 4
bundle clean
- name: Setup licensed
run: |
gem install licensed
- name: Get yarn cache directory
id: yarn-cache-dir
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
- name: Yarn cache
uses: actions/cache@v3
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Check RubyGems Licenses
if: ${{ !cancelled() }}
run: |
licensed cache
licensed status
- name: Yarn install
run: yarn install
- name: Check Yarn Licenses
if: ${{ !cancelled() }}
run: |
yarn global add licensee
yarn global upgrade licensee
licensee --errors-only
- name: Check Ember CLI Workspace Licenses
if: ${{ !cancelled() }}
working-directory: ./app/assets/javascripts
run: |
licensee --errors-only

View File

@ -10,22 +10,15 @@ concurrency:
group: linting-${{ format('{0}-{1}', github.head_ref || github.run_number, github.job) }}
cancel-in-progress: true
permissions:
contents: read
jobs:
build:
if: "!(github.event_name == 'push' && github.repository == 'discourse/discourse-private-mirror')"
name: run
runs-on: ubuntu-latest
container: discourse/discourse_test:slim
timeout-minutes: 30
steps:
- name: Set working directory owner
run: chown root:root .
- uses: actions/checkout@v3
- uses: actions/checkout@master
with:
fetch-depth: 1
@ -35,7 +28,7 @@ jobs:
git config --global user.name "Discourse CI"
- name: Bundler cache
uses: actions/cache@v3
uses: actions/cache@v2
with:
path: vendor/bundle
key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
@ -53,10 +46,10 @@ jobs:
- name: Get yarn cache directory
id: yarn-cache-dir
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Yarn cache
uses: actions/cache@v3
uses: actions/cache@v2
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir.outputs.dir }}
@ -68,47 +61,38 @@ jobs:
run: yarn install
- name: Rubocop
if: ${{ !cancelled() }}
run: bundle exec rubocop --parallel .
- name: syntax_tree
if: ${{ !cancelled() }}
run: |
set -E
bundle exec stree check Gemfile $(git ls-files '*.rb') $(git ls-files '*.rake')
if: ${{ always() }}
run: bundle exec rubocop .
- name: ESLint (core)
if: ${{ !cancelled() }}
if: ${{ always() }}
run: yarn eslint app/assets/javascripts
- name: ESLint (core plugins)
if: ${{ !cancelled() }}
if: ${{ always() }}
run: yarn eslint plugins
- name: Prettier
if: ${{ !cancelled() }}
if: ${{ always() }}
run: |
yarn prettier -v
yarn pprettier --list-different \
yarn prettier --list-different \
"app/assets/stylesheets/**/*.scss" \
"app/assets/javascripts/**/*.js" \
"app/assets/javascripts/**/*.hbs" \
"plugins/**/assets/stylesheets/**/*.scss" \
"plugins/**/assets/javascripts/**/*.js" \
"plugins/**/assets/javascripts/**/*.hbs" \
"plugins/**/assets/javascripts/**/*.js"
- name: Ember template lint
if: ${{ !cancelled() }}
if: ${{ always() }}
run: |
yarn ember-template-lint \
--no-error-on-unmatched-pattern \
"app/assets/javascripts/**/*.hbs" \
"plugins/**/assets/javascripts/**/*.hbs"
app/assets/javascripts \
plugins/**/assets/javascripts
- name: English locale lint (core)
if: ${{ !cancelled() }}
if: ${{ always() }}
run: bundle exec ruby script/i18n_lint.rb "config/**/locales/{client,server}.en.yml"
- name: English locale lint (core plugins)
if: ${{ !cancelled() }}
if: ${{ always() }}
run: bundle exec ruby script/i18n_lint.rb "plugins/**/locales/{client,server}.en.yml"

View File

@ -12,16 +12,12 @@ concurrency:
group: tests-${{ format('{0}-{1}', github.head_ref || github.run_number, github.job) }}
cancel-in-progress: true
permissions:
contents: read
jobs:
build:
if: "!(github.event_name == 'push' && github.repository == 'discourse/discourse-private-mirror')"
name: ${{ matrix.target }} ${{ matrix.build_type }} ${{ matrix.ruby }}
runs-on: ${{ (matrix.build_type == 'annotations') && 'ubuntu-latest' || 'ubuntu-20.04-8core' }}
container: discourse/discourse_test:slim${{ (matrix.build_type == 'frontend' || matrix.build_type == 'system') && '-browsers' || '' }}${{ (matrix.ruby == '3.1') && '-ruby-3.1.0' || '' }}
timeout-minutes: 20
name: ${{ matrix.target }} ${{ matrix.build_type }}
runs-on: ubuntu-latest
container: discourse/discourse_test:2.0.20220818-0047-slim${{ startsWith(matrix.build_type, 'frontend') && '-browsers' || '' }}
timeout-minutes: 60
env:
DISCOURSE_HOSTNAME: www.example.com
@ -29,27 +25,25 @@ jobs:
RAILS_ENV: test
PGUSER: discourse
PGPASSWORD: discourse
USES_PARALLEL_DATABASES: ${{ matrix.build_type == 'backend' || matrix.build_type == 'system' }}
CAPBYARA_DEFAULT_MAX_WAIT_TIME: 4
USES_PARALLEL_DATABASES: ${{ matrix.build_type == 'backend' && matrix.target == 'core' }}
strategy:
fail-fast: false
matrix:
build_type: [backend, frontend, system, annotations]
build_type: [backend, frontend, frontend-legacy, annotations]
target: [core, plugins]
ruby: ['3.2']
exclude:
- build_type: annotations
target: plugins
- build_type: frontend
target: core # Handled by core_frontend_tests job (below)
include:
- build_type: frontend
target: core-plugins
steps:
- name: Set working directory owner
run: chown root:root .
- uses: actions/checkout@v3
- uses: actions/checkout@master
with:
fetch-depth: 1
@ -69,12 +63,12 @@ jobs:
sudo -u postgres psql -c "CREATE ROLE $PGUSER LOGIN SUPERUSER PASSWORD '$PGPASSWORD';"
- name: Bundler cache
uses: actions/cache@v3
uses: actions/cache@v2
with:
path: vendor/bundle
key: ${{ runner.os }}-${{ matrix.ruby }}-gem-${{ hashFiles('**/Gemfile.lock') }}
key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-${{ matrix.ruby }}-gem-
${{ runner.os }}-gem-
- name: Setup gems
run: |
@ -87,10 +81,10 @@ jobs:
- name: Get yarn cache directory
id: yarn-cache-dir
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Yarn cache
uses: actions/cache@v3
uses: actions/cache@v2
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir.outputs.dir }}
@ -110,7 +104,7 @@ jobs:
run: bin/rake plugin:pull_compatible_all
- name: Fetch app state cache
uses: actions/cache@v3
uses: actions/cache@v2
id: app-cache
with:
path: tmp/app-cache
@ -151,65 +145,33 @@ jobs:
if: steps.app-cache.outputs.cache-hit != 'true'
run: rm -rf tmp/app-cache/uploads && cp -r public/uploads tmp/app-cache/uploads
- name: Fetch turbo_rspec_runtime.log cache
uses: actions/cache@v3
id: test-runtime-cache
if: matrix.build_type == 'backend' && matrix.target == 'core'
with:
path: tmp/turbo_rspec_runtime.log
key: rspec-runtime-backend-core
- name: Run Zeitwerk check
if: matrix.build_type == 'backend'
env:
LOAD_PLUGINS: ${{ (matrix.target == 'plugins') && '1' || '0' }}
run: |
if ! bin/rails zeitwerk:check --trace; then
echo
echo "---------------------------------------------"
echo
echo "::error::'bin/rails zeitwerk:check' failed - the app will fail to boot with 'eager_load=true' (e.g. in production)."
echo "To reproduce locally, run 'bin/rails zeitwerk:check'."
echo "Alternatively, you can run your local server/tests with the 'DISCOURSE_ZEITWERK_EAGER_LOAD=1' environment variable."
echo
exit 1
fi
- name: Core RSpec
if: matrix.build_type == 'backend' && matrix.target == 'core'
run: bin/turbo_rspec --verbose
- name: Plugin RSpec
if: matrix.build_type == 'backend' && matrix.target == 'plugins'
run: bin/rake plugin:turbo_spec
run: bin/rake plugin:spec
- name: Plugin QUnit
if: matrix.build_type == 'frontend' && matrix.target == 'plugins'
run: QUNIT_PARALLEL=3 bin/rake plugin:qunit['*','1200000']
- name: Core QUnit (Legacy)
if: matrix.build_type == 'frontend-legacy' && matrix.target == 'core'
run: QUNIT_EMBER_CLI=0 bin/rake qunit:test['1200000']
timeout-minutes: 30
- name: Ember Build for System Tests
if: matrix.build_type == 'system'
run: bin/ember-cli --build
- name: Wizard QUnit (Legacy)
if: matrix.build_type == 'frontend-legacy' && matrix.target == 'core'
run: QUNIT_EMBER_CLI=0 bin/rake qunit:test['600000','/wizard/qunit']
timeout-minutes: 10
- name: Setup Webdriver
if: matrix.build_type == 'system'
run: bin/rails runner "require 'webdrivers'; Webdrivers::Chromedriver.update"
- name: Plugin QUnit (Legacy)
if: matrix.build_type == 'frontend-legacy' && matrix.target == 'plugins'
run: QUNIT_EMBER_CLI=0 bin/rake plugin:qunit['*','1200000']
timeout-minutes: 30
- name: Core System Tests
if: matrix.build_type == 'system' && matrix.target == 'core'
run: bin/rspec spec/system
- name: Plugin System Tests
if: matrix.build_type == 'system' && matrix.target == 'plugins'
run: LOAD_PLUGINS=1 bin/rspec plugins/*/spec/system
- name: Upload failed system test screenshots
uses: actions/upload-artifact@v3
if: matrix.build_type == 'system' && failure()
with:
name: failed-system-test-screenshots
path: tmp/capybara/*.png
# - name: Plugin QUnit (Ember CLI)
# if: matrix.build_type == 'frontend' && (matrix.target == 'plugins' || matrix.target == 'core-plugins')
# run: QUNIT_EMBER_CLI=1 bin/rake plugin:qunit['*','1200000']
# timeout-minutes: 30
- name: Check Annotations
if: matrix.build_type == 'annotations'
@ -228,65 +190,61 @@ jobs:
fi
timeout-minutes: 30
core_frontend_tests:
if: "!(github.event_name == 'push' && github.repository == 'discourse/discourse-private-mirror')"
name: core frontend (${{ matrix.browser }})
runs-on: ubuntu-20.04-8core
container:
image: discourse/discourse_test:slim-browsers
options: --user discourse
# core_frontend_tests:
# name: core frontend (${{ matrix.browser }})
# runs-on: ubuntu-latest
# container: discourse/discourse_test:slim-browsers
# timeout-minutes: 30
timeout-minutes: 35
# strategy:
# fail-fast: false
# matrix:
# browser: ["Chrome", "Firefox", "Headless Firefox"]
strategy:
fail-fast: false
matrix:
browser: ["Chrome", "Firefox ESR", "Firefox Evergreen"]
# steps:
# - uses: actions/checkout@v2
# with:
# fetch-depth: 1
env:
TESTEM_BROWSER: ${{ (startsWith(matrix.browser, 'Firefox') && 'Firefox') || matrix.browser }}
TESTEM_FIREFOX_PATH: ${{ (matrix.browser == 'Firefox Evergreen') && '/opt/firefox-evergreen/firefox' }}
# - name: Setup Git
# run: |
# git config --global user.email "ci@ci.invalid"
# git config --global user.name "Discourse CI"
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 1
# - name: Get yarn cache directory
# id: yarn-cache-dir
# run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup Git
run: |
git config --global user.email "ci@ci.invalid"
git config --global user.name "Discourse CI"
# - name: Yarn cache
# uses: actions/cache@v2
# id: yarn-cache
# with:
# path: ${{ steps.yarn-cache-dir.outputs.dir }}
# key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
# restore-keys: |
# ${{ runner.os }}-yarn-
- name: Get yarn cache directory
id: yarn-cache-dir
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
# - name: Yarn install
# working-directory: ./app/assets/javascripts/discourse
# run: yarn install
- name: Yarn cache
uses: actions/cache@v3
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
# - name: Ember Build
# working-directory: ./app/assets/javascripts/discourse
# run: |
# sudo -E -u discourse mkdir /tmp/emberbuild
# sudo -E -u discourse -H yarn ember build --environment=test -o /tmp/emberbuild
- name: Yarn install
working-directory: ./app/assets/javascripts/discourse
run: yarn install
# - name: Core QUnit 1
# working-directory: ./app/assets/javascripts/discourse
# run: sudo -E -u discourse -H yarn ember exam --path /tmp/emberbuild --split=3 --partition=1 --launch "${{ matrix.browser }}" --random
# timeout-minutes: 20
- name: Ember Build
working-directory: ./app/assets/javascripts/discourse
run: |
mkdir /tmp/emberbuild
yarn ember build --environment=test -o /tmp/emberbuild
# - name: Core QUnit 2
# working-directory: ./app/assets/javascripts/discourse
# run: sudo -E -u discourse -H yarn ember exam --path /tmp/emberbuild --split=3 --partition=2 --launch "${{ matrix.browser }}" --random
# timeout-minutes: 20
- name: Core QUnit
working-directory: ./app/assets/javascripts/discourse
run: yarn ember exam --path /tmp/emberbuild --load-balance --parallel=5 --launch "${{ env.TESTEM_BROWSER }}" --write-execution-file --random
timeout-minutes: 15
- uses: actions/upload-artifact@v3
if: ${{ always() }}
with:
name: ember-exam-execution-${{matrix.browser}}
path: ./app/assets/javascripts/discourse/test-execution-*.json
# - name: Core QUnit 3
# working-directory: ./app/assets/javascripts/discourse
# run: sudo -E -u discourse -H yarn ember exam --path /tmp/emberbuild --split=3 --partition=3 --launch "${{ matrix.browser }}" --random
# timeout-minutes: 20

7
.gitignore vendored
View File

@ -39,7 +39,6 @@
!/plugins/discourse-narrative-bot
!/plugins/discourse-presence
!/plugins/lazy-yt/
!/plugins/chat/
!/plugins/poll/
!/plugins/styleguide
/plugins/*/auto_generated/
@ -50,9 +49,6 @@
/vendor/data/GeoLite2-City.mmdb
/vendor/data/GeoLite2-ASN.mmdb
# We provide a .sample but people can use newer versions if they want to
.ruby-version
# Front-end
dist
node_modules
@ -63,6 +59,3 @@ yarn-error.log
# Generated API documentation files
openapi/*
# Cached License Data Files
/.licenses

21
.jsdoc
View File

@ -1,21 +0,0 @@
// jsdoc doesn't accept paths starting with _ (which is the case on github runners)
// so we need to alter the default config
{
"source": {
"excludePattern": ""
},
"templates": {
"default": {
"includeDate": false
}
},
"opts": {
"template": "./node_modules/tidy-jsdoc",
"prism-theme": "prism-custom",
"encoding": "utf8",
"recurse": true
},
"metadata": {
"title": "Discourse"
}
}

View File

@ -1,62 +1,12 @@
sources:
yarn: true
bundler: true
allowed:
- 0bsd
- mit
- apache-2.0
- bsd-2-clause
- bsd-3-clause
- cc0-1.0
- isc
- mit
- ruby
ignored:
bundler:
- cgi # Ruby (default gem)
- date # Ruby (default gem)
- digest # Ruby (default gem)
- io-wait # Ruby (default gem)
- json # Ruby (default gem)
- net-http # Ruby (default gem)
- net-protocol # Ruby (default gem)
- openssl # Ruby (default gem)
- racc # Ruby (default gem)
- rchardet # LGPL
- ruby2_keywords # Ruby (default gem)
- strscan # Ruby (default gem)
- timeout # Ruby (default gem)
- uri # Ruby (default gem)
reviewed:
bundler:
- activerecord # MIT
- coderay # MIT
- concurrent-ruby # MIT
- css_parser # MIT
- excon # MIT
- faraday-em_http # MIT
- faraday-em_synchrony # MIT
- faraday-excon # MIT
- faraday-httpclient # MIT
- faraday-net_http # MIT
- faraday-patron # MIT
- faraday-rack # MIT
- highline # Ruby or GPL-2.0
- htmlentities # MIT
- image_size # MIT
- jwt # MIT
- kgio # LGPL-2.1+
- logstash-event # Apache-2.0
- net-imap # Ruby (bundled gem)
- net-pop # Ruby (bundled gem)
- net-smtp # Ruby (bundled gem)
- omniauth # MIT
- pg # Ruby
- r2 # Apache-2.0 (Twitter)
- raindrops # LGPL-2.1+
- rubyzip # Ruby
- sidekiq # LGPL (Sidekiq)
- tilt # MIT
- unf # BSD-2-Clause
- unicorn # Ruby or GPLv2/GPLv3
- other
- none

View File

@ -1,18 +0,0 @@
{
"licenses": {
"blueOak": "bronze",
"spdx": [
"CC0-1.0",
"CC-BY-3.0",
"CC-BY-4.0",
"Apache-2.0 WITH LLVM-exception"
]
},
"packages": {
"@fortawesome/fontawesome-free": "*",
"ember-template-lint-plugin-discourse": "*",
"squoosh": "2.0.0",
"taffydb": "2.6.2"
},
"corrections": true
}

View File

@ -3,13 +3,16 @@ plugins/**/assets/stylesheets/vendor/
plugins/**/assets/javascripts/vendor/
plugins/**/config/locales/**/*.yml
plugins/**/config/*.yml
documentation/
package.json
config/locales/**/*.yml
!config/locales/**/*.en*.yml
script/import_scripts/**/*.yml
app/assets/javascripts/browser-update.js
app/assets/javascripts/discourse-loader.js
app/assets/javascripts/env.js
app/assets/javascripts/main_include_admin.js
app/assets/javascripts/vendor.js
app/assets/javascripts/locales/i18n.js
app/assets/javascripts/ember-addons/
app/assets/javascripts/discourse/lib/autosize.js
@ -18,15 +21,9 @@ lib/javascripts/messageformat.js
lib/highlight_js/
plugins/**/lib/javascripts/locale
public/
!/app/assets/javascripts/discourse/public
vendor/
app/assets/javascripts/discourse/tests/test-boot-rails.js
app/assets/javascripts/discourse/tests/fixtures
spec/
node_modules/
dist/
tmp/
**/*.rb
**/*.html
**/*.json
**/*.md

2
.rspec
View File

@ -1 +1 @@
--require 'rails_helper'
--colour

View File

@ -1,5 +1,5 @@
inherit_gem:
rubocop-discourse: stree-compat.yml
rubocop-discourse: default.yml
# Still work to do in ensuring we don't link old files
Discourse/NoAddReferenceOrAliasesActiveRecordMigration:
@ -7,7 +7,3 @@ Discourse/NoAddReferenceOrAliasesActiveRecordMigration:
Discourse/NoResetColumnInformationInMigrations:
Enabled: true
Lint/Debugger:
Exclude:
- script/**/*

View File

@ -1 +1 @@
3.2.1
2.7.2

View File

@ -1,2 +0,0 @@
--print-width=100
--plugins=plugin/trailing_comma,disable_ternary

View File

@ -1,31 +1,53 @@
module.exports = {
plugins: ["ember-template-lint-plugin-discourse"],
extends: "discourse:recommended",
extends: "recommended",
ignore: ["**/*.raw"],
rules: {
"no-action-modifiers": true,
"block-indentation": true,
"deprecated-render-helper": true,
"eol-last": "always",
"linebreak-style": true,
"link-rel-noopener": "strict",
"no-abstract-roles": true,
"no-args-paths": true,
"no-attrs-in-components": true,
"no-capital-arguments": false, // TODO: we extensively use `args` argument name
"no-curly-component-invocation": {
allow: [
// These are helpers, not components
"directory-item-header-title",
"directory-item-user-field-value",
"directory-item-value",
"directory-table-header-title",
"loading-spinner",
"directory-item-label",
],
},
"no-implicit-this": {
allow: ["loading-spinner"],
},
// Begin prettier compatibility
"eol-last": false,
"self-closing-void-elements": false,
"block-indentation": false,
quotes: false,
// End prettier compatibility
"no-debugger": true,
"no-duplicate-attributes": true,
"no-extra-mut-helper-argument": true,
"no-html-comments": true,
"no-index-component-invocation": true,
"no-inline-styles": false,
"no-input-block": true,
"no-input-tagname": true,
"no-implicit-this": false,
"no-invalid-interactive": true,
"no-invalid-link-text": true,
"no-invalid-meta": true,
"no-invalid-role": true,
"no-log": true,
"no-negated-condition": true,
"no-nested-interactive": true,
"no-multiple-empty-lines": true,
"no-obsolete-elements": true,
"no-outlet-outside-routes": true,
"no-partial": true,
"no-positive-tabindex": false,
"no-quoteless-attributes": true,
"no-shadowed-elements": true,
"no-trailing-spaces": true,
"no-triple-curlies": true,
"no-unbound": true,
"no-unnecessary-concat": true,
"no-unnecessary-component-helper": true,
"no-unused-block-params": true,
quotes: "double",
"require-button-type": true,
"require-iframe-title": true,
"require-valid-alt-text": false,
"self-closing-void-elements": true,
"simple-unless": true,
"style-concatenation": true,
"table-groups": true,
"link-href-attributes": false,
},
};

312
Gemfile
View File

@ -1,51 +1,51 @@
# frozen_string_literal: true
source "https://rubygems.org"
source 'https://rubygems.org'
# if there is a super emergency and rubygems is playing up, try
#source 'http://production.cf.rubygems.org'
gem "bootsnap", require: false, platform: :mri
gem 'bootsnap', require: false, platform: :mri
def rails_master?
ENV["RAILS_MASTER"] == "1"
ENV["RAILS_MASTER"] == '1'
end
if rails_master?
gem "arel", git: "https://github.com/rails/arel.git"
gem "rails", git: "https://github.com/rails/rails.git"
gem 'arel', git: 'https://github.com/rails/arel.git'
gem 'rails', git: 'https://github.com/rails/rails.git'
else
# NOTE: Until rubygems gives us optional dependencies we are stuck with this needing to be explicit
# this allows us to include the bits of rails we use without pieces we do not.
#
# To issue a rails update bump the version number here
rails_version = "7.0.4.3"
gem "actionmailer", rails_version
gem "actionpack", rails_version
gem "actionview", rails_version
gem "activemodel", rails_version
gem "activerecord", rails_version
gem "activesupport", rails_version
gem "railties", rails_version
gem "sprockets-rails"
rails_version = '6.1.7.1'
gem 'actionmailer', rails_version
gem 'actionpack', rails_version
gem 'actionview', rails_version
gem 'activemodel', rails_version
gem 'activerecord', rails_version
gem 'activesupport', rails_version
gem 'railties', rails_version
gem 'sprockets-rails'
end
gem "json"
gem 'json'
# TODO: At the moment Discourse does not work with Sprockets 4, we would need to correct internals
# We intend to drop sprockets rather than upgrade to 4.x
gem "sprockets", git: "https://github.com/rails/sprockets", branch: "3.x"
# This is a desired upgrade we should get to.
gem 'sprockets', '3.7.2'
# this will eventually be added to rails,
# allows us to precompile all our templates in the unicorn master
gem "actionview_precompiler", require: false
gem 'actionview_precompiler', require: false
gem "discourse-seed-fu"
gem 'seed-fu'
gem "mail", git: "https://github.com/discourse/mail.git"
gem "mini_mime"
gem "mini_suffix"
gem 'mail', git: 'https://github.com/discourse/mail.git', require: false
gem 'mini_mime'
gem 'mini_suffix'
gem "redis"
gem 'redis'
# This is explicitly used by Sidekiq and is an optional dependency.
# We tell Sidekiq to use the namespace "sidekiq" which triggers this
@ -53,231 +53,215 @@ gem "redis"
# redis namespace support is optional
# We already namespace stuff in DiscourseRedis, so we should consider
# just using a single implementation in core vs having 2 namespace implementations
gem "redis-namespace"
gem 'redis-namespace'
# NOTE: AM serializer gets a lot slower with recent updates
# we used an old branch which is the fastest one out there
# are long term goal here is to fork this gem so we have a
# better maintained living fork
gem "active_model_serializers", "~> 0.8.3"
gem 'active_model_serializers', '~> 0.8.3'
gem "http_accept_language", require: false
gem 'http_accept_language', require: false
gem "discourse-fonts", require: "discourse_fonts"
# Ember related gems need to be pinned cause they control client side
# behavior, we will push these versions up when upgrading ember
gem 'discourse-ember-rails', '0.18.6', require: 'ember-rails'
gem 'discourse-ember-source', '~> 3.12.2'
gem 'ember-handlebars-template', '0.8.0'
gem 'discourse-fonts'
gem "message_bus"
gem 'barber'
gem "rails_multisite"
gem 'message_bus'
gem "fast_xs", platform: :ruby
gem 'rails_multisite'
gem "xorcist"
gem 'fast_xs', platform: :ruby
gem "fastimage"
gem 'xorcist'
gem "aws-sdk-s3", require: false
gem "aws-sdk-sns", require: false
gem "excon", require: false
gem "unf", require: false
gem 'fastimage'
gem "email_reply_trimmer"
gem 'aws-sdk-s3', require: false
gem 'aws-sdk-sns', require: false
gem 'excon', require: false
gem 'unf', require: false
gem "image_optim"
gem "multi_json"
gem "mustache"
gem "nokogiri"
gem "loofah"
gem "css_parser", require: false
gem 'email_reply_trimmer'
gem "omniauth"
gem "omniauth-facebook"
gem "omniauth-twitter"
gem "omniauth-github"
gem 'image_optim'
gem 'multi_json'
gem 'mustache'
gem 'nokogiri'
gem 'loofah'
gem 'css_parser', require: false
gem "omniauth-oauth2", require: false
gem 'omniauth'
gem 'omniauth-facebook'
gem 'omniauth-twitter'
gem 'omniauth-github'
gem "omniauth-google-oauth2"
gem 'omniauth-oauth2', require: false
# pending: https://github.com/ohler55/oj/issues/789
gem "oj", "3.13.14"
gem 'omniauth-google-oauth2'
gem "pg"
gem "mini_sql"
gem "pry-rails", require: false
gem "pry-byebug", require: false
gem "rtlcss", require: false
gem "rake"
# Pinning oj until https://github.com/ohler55/oj/issues/699 is resolved.
# Segfaults and stuck processes after upgrading.
gem 'oj', '3.13.2'
gem "thor", require: false
gem "diffy", require: false
gem "rinku"
gem "sidekiq"
gem "mini_scheduler"
gem 'pg'
gem 'mini_sql'
gem 'pry-rails', require: false
gem 'pry-byebug', require: false
gem 'r2', require: false
gem 'rake'
gem "execjs", require: false
gem "mini_racer"
gem 'thor', require: false
gem 'diffy', require: false
gem 'rinku'
gem 'sidekiq'
gem 'mini_scheduler'
gem "highline", require: false
gem 'execjs', require: false
gem 'mini_racer'
gem "rack"
gem 'highline', require: false
gem "rack-protection" # security
gem "cbor", require: false
gem "cose", require: false
gem "addressable"
gem "json_schemer"
gem 'rack'
gem "net-smtp", require: false
gem "net-imap", require: false
gem "net-pop", require: false
gem "digest", require: false
gem 'rack-protection' # security
gem 'cbor', require: false
gem 'cose', require: false
gem 'addressable'
gem 'json_schemer'
# Gems used only for assets and not required in production environments by default.
# Allow everywhere for now cause we are allowing asset debugging in production
group :assets do
gem "uglifier"
gem 'uglifier'
gem 'rtlit', require: false # for css rtling
end
group :test do
gem "capybara", require: false
gem "webmock", require: false
gem "fakeweb", require: false
gem "minitest", require: false
gem "simplecov", require: false
gem "selenium-webdriver", require: false
gem 'webmock', require: false
gem 'fakeweb', require: false
gem 'minitest', require: false
gem 'simplecov', require: false
gem "test-prof"
gem "webdrivers", require: false
end
group :test, :development do
gem "rspec"
gem "listen", require: false
gem "certified", require: false
gem "fabrication", require: false
gem "mocha", require: false
gem 'rspec'
gem 'mock_redis'
gem 'listen', require: false
gem 'certified', require: false
gem 'fabrication', require: false
gem 'mocha', require: false
gem "rb-fsevent", require: RUBY_PLATFORM =~ /darwin/i ? "rb-fsevent" : false
gem 'rb-fsevent', require: RUBY_PLATFORM =~ /darwin/i ? 'rb-fsevent' : false
gem "rspec-rails"
gem 'rspec-rails'
gem "shoulda-matchers", require: false
gem "rspec-html-matchers"
gem "byebug", require: ENV["RM_INFO"].nil?, platform: :mri
gem 'shoulda-matchers', require: false
gem 'rspec-html-matchers'
gem 'byebug', require: ENV['RM_INFO'].nil?, platform: :mri
gem "rubocop-discourse", require: false
gem "parallel_tests"
gem 'parallel_tests'
gem "rswag-specs"
gem 'rswag-specs'
gem "annotate"
gem "syntax_tree"
gem "syntax_tree-disable_ternary"
gem 'annotate'
end
group :development do
gem "ruby-prof", require: false, platform: :mri
gem "bullet", require: !!ENV["BULLET"]
gem "better_errors", platform: :mri, require: !!ENV["BETTER_ERRORS"]
gem "binding_of_caller"
gem "yaml-lint"
gem "yard"
gem 'ruby-prof', require: false, platform: :mri
gem 'bullet', require: !!ENV['BULLET']
gem 'better_errors', platform: :mri, require: !!ENV['BETTER_ERRORS']
gem 'binding_of_caller'
gem 'yaml-lint'
end
if ENV["ALLOW_DEV_POPULATE"] == "1"
gem "discourse_dev_assets"
gem "faker", "~> 2.16"
gem 'discourse_dev_assets'
gem 'faker', "~> 2.16"
else
group :development, :test do
gem "discourse_dev_assets"
gem "faker", "~> 2.16"
group :development do
gem 'discourse_dev_assets'
gem 'faker', "~> 2.16"
end
end
# this is an optional gem, it provides a high performance replacement
# to String#blank? a method that is called quite frequently in current
# ActiveRecord, this may change in the future
gem "fast_blank", platform: :ruby
gem 'fast_blank', platform: :ruby
# this provides a very efficient lru cache
gem "lru_redux"
gem 'lru_redux'
gem "htmlentities", require: false
gem 'htmlentities', require: false
# IMPORTANT: mini profiler monkey patches, so it better be required last
# If you want to amend mini profiler to do the monkey patches in the railties
# we are open to it. by deferring require to the initializer we can configure discourse installs without it
gem "rack-mini-profiler", require: ["enable_rails_patches"]
gem 'rack-mini-profiler', require: ['enable_rails_patches']
gem "unicorn", require: false, platform: :ruby
gem "puma", require: false
gem "rbtrace", require: false, platform: :mri
gem "gc_tracer", require: false, platform: :mri
gem 'unicorn', require: false, platform: :ruby
gem 'puma', require: false
gem 'rbtrace', require: false, platform: :mri
gem 'gc_tracer', require: false, platform: :mri
# required for feed importing and embedding
gem "ruby-readability", require: false
gem 'ruby-readability', require: false
# rss gem is a bundled gem from Ruby 3 onwards
gem "rss", require: false
gem 'rss', require: false
gem "stackprof", require: false, platform: :mri
gem "memory_profiler", require: false, platform: :mri
gem 'stackprof', require: false, platform: :mri
gem 'memory_profiler', require: false, platform: :mri
gem "cppjieba_rb", require: false
gem 'cppjieba_rb', require: false
gem "lograge", require: false
gem "logstash-event", require: false
gem "logstash-logger", require: false
gem "logster"
gem 'lograge', require: false
gem 'logstash-event', require: false
gem 'logstash-logger', require: false
gem 'logster'
# These are forks of sassc and sassc-rails with dart-sass support
gem "dartsass-ruby"
gem "dartsass-sprockets"
# NOTE: later versions of sassc are causing a segfault, possibly dependent on processer architecture
# and until resolved should be locked at 2.0.1
gem 'sassc', '2.0.1', require: false
gem "sassc-rails"
gem "rotp", require: false
gem 'rotp', require: false
gem "rqrcode"
gem 'rqrcode'
gem "rubyzip", require: false
gem 'rubyzip', require: false
gem "sshkey", require: false
gem 'sshkey', require: false
gem "rchardet", require: false
gem "lz4-ruby", require: false, platform: :ruby
gem 'rchardet', require: false
gem 'lz4-ruby', require: false, platform: :ruby
gem "sanitize"
gem 'sanitize'
if ENV["IMPORT"] == "1"
gem "mysql2"
gem "redcarpet"
gem 'mysql2'
gem 'redcarpet'
# NOTE: in import mode the version of sqlite can matter a lot, so we stick it to a specific one
gem "sqlite3", "~> 1.3", ">= 1.3.13"
gem "ruby-bbcode-to-md", git: "https://github.com/nlalonde/ruby-bbcode-to-md"
gem "reverse_markdown"
gem "tiny_tds"
gem "csv"
gem "parallel", require: false
gem 'sqlite3', '~> 1.3', '>= 1.3.13'
gem 'ruby-bbcode-to-md', git: 'https://github.com/nlalonde/ruby-bbcode-to-md'
gem 'reverse_markdown'
gem 'tiny_tds'
gem 'csv'
end
gem "web-push"
gem "colored2", require: false
gem "maxminddb"
gem 'webpush', require: false
gem 'colored2', require: false
gem 'maxminddb'
gem "rails_failover", require: false
gem 'rails_failover', require: false
gem "faraday"
gem "faraday-retry"
# workaround for faraday-net_http, see
# https://github.com/ruby/net-imap/issues/16#issuecomment-803086765
gem "net-http"
# workaround for prometheus-client
gem "webrick", require: false
# Workaround until Ruby ships with cgi version 0.3.6 or higher.
gem "cgi", ">= 0.3.6", require: false
gem "tzinfo-data"
gem 'net-http'

View File

@ -5,37 +5,25 @@ GIT
mail (2.8.0.edge)
mini_mime (>= 0.1.1)
GIT
remote: https://github.com/rails/sprockets
revision: f4d3dae71ef29c44b75a49cfbf8032cce07b423a
branch: 3.x
specs:
sprockets (3.7.2)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
GEM
remote: https://rubygems.org/
specs:
actionmailer (7.0.4.3)
actionpack (= 7.0.4.3)
actionview (= 7.0.4.3)
activejob (= 7.0.4.3)
activesupport (= 7.0.4.3)
actionmailer (6.1.7.1)
actionpack (= 6.1.7.1)
actionview (= 6.1.7.1)
activejob (= 6.1.7.1)
activesupport (= 6.1.7.1)
mail (~> 2.5, >= 2.5.4)
net-imap
net-pop
net-smtp
rails-dom-testing (~> 2.0)
actionpack (7.0.4.3)
actionview (= 7.0.4.3)
activesupport (= 7.0.4.3)
rack (~> 2.0, >= 2.2.0)
actionpack (6.1.7.1)
actionview (= 6.1.7.1)
activesupport (= 6.1.7.1)
rack (~> 2.0, >= 2.0.9)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actionview (7.0.4.3)
activesupport (= 7.0.4.3)
actionview (6.1.7.1)
activesupport (= 6.1.7.1)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
@ -44,162 +32,174 @@ GEM
actionview (>= 6.0.a)
active_model_serializers (0.8.4)
activemodel (>= 3.0)
activejob (7.0.4.3)
activesupport (= 7.0.4.3)
activejob (6.1.7.1)
activesupport (= 6.1.7.1)
globalid (>= 0.3.6)
activemodel (7.0.4.3)
activesupport (= 7.0.4.3)
activerecord (7.0.4.3)
activemodel (= 7.0.4.3)
activesupport (= 7.0.4.3)
activesupport (7.0.4.3)
activemodel (6.1.7.1)
activesupport (= 6.1.7.1)
activerecord (6.1.7.1)
activemodel (= 6.1.7.1)
activesupport (= 6.1.7.1)
activesupport (6.1.7.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
addressable (2.8.1)
public_suffix (>= 2.0.2, < 6.0)
annotate (3.2.0)
activerecord (>= 3.2, < 8.0)
zeitwerk (~> 2.3)
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
annotate (3.1.1)
activerecord (>= 3.2, < 7.0)
rake (>= 10.4, < 14.0)
ast (2.4.2)
aws-eventstream (1.2.0)
aws-partitions (1.583.0)
aws-sdk-core (3.130.2)
aws-partitions (1.516.0)
aws-sdk-core (3.121.2)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.525.0)
aws-partitions (~> 1, >= 1.239.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1.0)
aws-sdk-kms (1.56.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sdk-kms (1.44.0)
aws-sdk-core (~> 3, >= 3.112.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.114.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sdk-s3 (1.96.1)
aws-sdk-core (~> 3, >= 3.112.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
aws-sdk-sns (1.53.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.5.0)
aws-sdk-sns (1.46.0)
aws-sdk-core (~> 3, >= 3.121.2)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.4.0)
aws-eventstream (~> 1, >= 1.0.2)
barber (0.12.2)
ember-source (>= 1.0, < 3.1)
execjs (>= 1.2, < 3)
better_errors (2.9.1)
coderay (>= 1.0.0)
erubi (>= 1.0.0)
rack (>= 0.9.0)
binding_of_caller (1.0.0)
debug_inspector (>= 0.0.1)
bootsnap (1.16.0)
msgpack (~> 1.2)
bootsnap (1.9.4)
msgpack (~> 1.0)
builder (3.2.4)
bullet (7.0.7)
bullet (7.0.1)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.11)
byebug (11.1.3)
capybara (3.38.0)
addressable
matrix
mini_mime (>= 0.1.3)
nokogiri (~> 1.8)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
cbor (0.5.9.6)
certified (1.0.0)
cgi (0.3.6)
chunky_png (1.4.0)
coderay (1.1.3)
colored2 (3.1.2)
concurrent-ruby (1.2.2)
connection_pool (2.3.0)
cose (1.3.0)
concurrent-ruby (1.1.9)
connection_pool (2.2.5)
cose (1.2.0)
cbor (~> 0.5.9)
openssl-signature_algorithm (~> 1.0)
cppjieba_rb (0.4.2)
cppjieba_rb (0.3.3)
crack (0.4.5)
rexml
crass (1.0.6)
css_parser (1.14.0)
css_parser (1.11.0)
addressable
dartsass-ruby (3.0.1)
sass-embedded (~> 1.54)
dartsass-sprockets (3.0.0)
dartsass-ruby (~> 3.0)
railties (>= 4.0.0)
sprockets (> 3.0)
sprockets-rails
tilt
date (3.3.3)
debug_inspector (1.1.0)
diff-lcs (1.5.0)
diffy (3.4.2)
digest (3.1.1)
diffy (3.4.0)
discourse-ember-rails (0.18.6)
active_model_serializers
ember-data-source (>= 1.0.0.beta.5)
ember-handlebars-template (>= 0.1.1, < 1.0)
ember-source (>= 1.1.0)
jquery-rails (>= 1.0.17)
railties (>= 3.1)
discourse-ember-source (3.12.2.3)
discourse-fonts (0.0.9)
discourse-seed-fu (2.3.12)
activerecord (>= 3.1)
activesupport (>= 3.1)
discourse_dev_assets (0.0.4)
discourse_dev_assets (0.0.3)
faker (~> 2.16)
literate_randomizer
docile (1.4.0)
ecma-re-validator (0.4.0)
regexp_parser (~> 2.2)
email_reply_trimmer (0.1.13)
erubi (1.12.0)
excon (0.99.0)
ember-data-source (3.0.2)
ember-source (>= 2, < 3.0)
ember-handlebars-template (0.8.0)
barber (>= 0.11.0)
sprockets (>= 3.3, < 4.1)
ember-source (2.18.2)
erubi (1.10.0)
excon (0.93.0)
execjs (2.8.1)
exifr (1.3.10)
fabrication (2.30.0)
faker (2.23.0)
i18n (>= 1.8.11, < 2)
exifr (1.3.9)
fabrication (2.24.0)
faker (2.19.0)
i18n (>= 1.6, < 2)
fakeweb (1.3.0)
faraday (2.7.4)
faraday-net_http (>= 2.0, < 3.1)
faraday (1.9.3)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0)
faraday-multipart (~> 1.0)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.0)
faraday-patron (~> 1.0)
faraday-rack (~> 1.0)
faraday-retry (~> 1.0)
ruby2_keywords (>= 0.0.4)
faraday-net_http (3.0.2)
faraday-retry (2.1.0)
faraday (~> 2.0)
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-multipart (1.0.3)
multipart-post (>= 1.2, < 3)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday-rack (1.0.0)
faraday-retry (1.0.3)
fast_blank (1.0.1)
fast_xs (0.8.0)
fastimage (2.2.6)
ffi (1.15.5)
fspath (3.1.2)
gc_tracer (1.5.1)
globalid (1.1.0)
globalid (1.0.1)
activesupport (>= 5.0)
google-protobuf (3.22.2)
google-protobuf (3.22.2-aarch64-linux)
google-protobuf (3.22.2-arm64-darwin)
google-protobuf (3.22.2-x86_64-darwin)
google-protobuf (3.22.2-x86_64-linux)
guess_html_encoding (0.0.11)
hana (1.3.7)
hashdiff (1.0.1)
hashie (5.0.0)
highline (2.1.0)
hkdf (1.0.0)
highline (2.0.3)
hkdf (0.3.0)
htmlentities (4.3.4)
http_accept_language (2.1.1)
i18n (1.12.0)
i18n (1.8.11)
concurrent-ruby (~> 1.0)
image_optim (0.31.3)
image_optim (0.31.1)
exifr (~> 1.2, >= 1.2.2)
fspath (~> 3.0)
image_size (>= 1.5, < 4)
in_threads (~> 1.3)
progress (~> 3.0, >= 3.0.1)
image_size (3.2.0)
in_threads (1.6.0)
jmespath (1.6.2)
json (2.6.3)
json-schema (3.0.0)
addressable (>= 2.8)
json_schemer (0.2.23)
image_size (3.0.1)
in_threads (1.5.4)
ipaddr (1.2.3)
jmespath (1.5.0)
jquery-rails (4.4.0)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
json (2.6.1)
json-schema (2.8.1)
addressable (>= 2.4)
json_schemer (0.2.18)
ecma-re-validator (~> 0.3)
hana (~> 1.3)
regexp_parser (~> 2.0)
uri_template (~> 0.7)
jwt (2.7.0)
jwt (2.3.0)
kgio (2.11.4)
libv8-node (16.10.0.0)
libv8-node (16.10.0.0-aarch64-linux)
@ -207,11 +207,11 @@ GEM
libv8-node (16.10.0.0-x86_64-darwin)
libv8-node (16.10.0.0-x86_64-darwin-19)
libv8-node (16.10.0.0-x86_64-linux)
listen (3.8.0)
listen (3.7.1)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
literate_randomizer (0.4.0)
lograge (0.12.0)
lograge (0.11.2)
actionpack (>= 4)
activesupport (>= 4)
railties (>= 4)
@ -219,71 +219,58 @@ GEM
logstash-event (1.2.02)
logstash-logger (0.26.1)
logstash-event (~> 1.2)
logster (2.12.2)
loofah (2.19.1)
logster (2.10.1)
loofah (2.13.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
lru_redux (1.1.0)
lz4-ruby (0.3.3)
matrix (0.4.2)
maxminddb (0.1.22)
memory_profiler (1.0.1)
message_bus (4.3.2)
memory_profiler (1.0.0)
message_bus (4.0.0)
rack (>= 1.1.3)
method_source (1.0.0)
mini_mime (1.1.2)
mini_portile2 (2.8.1)
mini_racer (0.6.3)
mini_portile2 (2.8.0)
mini_racer (0.6.1)
libv8-node (~> 16.10.0.0)
mini_scheduler (0.15.0)
sidekiq (>= 4.2.3, < 7.0)
mini_sql (1.4.0)
mini_scheduler (0.13.0)
sidekiq (>= 4.2.3)
mini_sql (1.1.3)
mini_suffix (0.3.3)
ffi (~> 1.9)
minitest (5.18.0)
mocha (2.0.2)
ruby2_keywords (>= 0.0.5)
msgpack (1.6.1)
minitest (5.15.0)
mocha (1.13.0)
mock_redis (0.29.0)
ruby2_keywords
msgpack (1.4.2)
multi_json (1.15.0)
multi_xml (0.6.0)
multipart-post (2.1.1)
mustache (1.1.1)
net-http (0.3.2)
net-http (0.2.2)
uri
net-imap (0.3.4)
date
net-protocol
net-pop (0.1.2)
net-protocol
net-protocol (0.2.1)
timeout
net-smtp (0.3.3)
net-protocol
nio4r (2.5.8)
nokogiri (1.14.2)
nokogiri (1.13.4)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
nokogiri (1.14.2-aarch64-linux)
nokogiri (1.13.4-aarch64-linux)
racc (~> 1.4)
nokogiri (1.14.2-arm64-darwin)
nokogiri (1.13.4-arm64-darwin)
racc (~> 1.4)
nokogiri (1.14.2-x86_64-darwin)
nokogiri (1.13.4-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.14.2-x86_64-linux)
nokogiri (1.13.4-x86_64-linux)
racc (~> 1.4)
oauth (1.1.0)
oauth-tty (~> 1.0, >= 1.0.1)
snaky_hash (~> 2.0)
version_gem (~> 1.1)
oauth-tty (1.0.5)
version_gem (~> 1.1, >= 1.1.1)
oauth2 (1.4.11)
faraday (>= 0.17.3, < 3.0)
oauth (0.5.8)
oauth2 (1.4.7)
faraday (>= 0.8, < 2.0)
jwt (>= 1.0, < 3.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 4)
oj (3.13.14)
omniauth (1.9.2)
rack (>= 1.2, < 3)
oj (3.13.2)
omniauth (1.9.1)
hashie (>= 3.4.6)
rack (>= 1.6.2, < 3)
omniauth-facebook (9.0.0)
@ -299,66 +286,66 @@ GEM
omniauth-oauth (1.2.0)
oauth
omniauth (>= 1.0, < 3)
omniauth-oauth2 (1.7.3)
oauth2 (>= 1.4, < 3)
omniauth-oauth2 (1.7.2)
oauth2 (~> 1.4)
omniauth (>= 1.9, < 3)
omniauth-twitter (1.4.0)
omniauth-oauth (~> 1.1)
rack
openssl (3.1.0)
openssl-signature_algorithm (1.3.0)
openssl (> 2.0)
openssl (2.2.1)
ipaddr
openssl-signature_algorithm (1.1.1)
openssl (~> 2.0)
optimist (3.0.1)
parallel (1.22.1)
parallel_tests (4.2.0)
parallel (1.21.0)
parallel_tests (3.7.3)
parallel
parser (3.2.1.1)
parser (3.1.0.0)
ast (~> 2.4.1)
pg (1.4.6)
prettier_print (1.2.1)
pg (1.2.3)
progress (3.6.0)
pry (0.14.2)
pry (0.13.1)
coderay (~> 1.1)
method_source (~> 1.0)
pry-byebug (3.10.1)
pry-byebug (3.9.0)
byebug (~> 11.0)
pry (>= 0.13, < 0.15)
pry (~> 0.13.0)
pry-rails (0.3.9)
pry (>= 0.10.4)
public_suffix (5.0.1)
puma (6.1.1)
public_suffix (4.0.6)
puma (5.5.2)
nio4r (~> 2.0)
racc (1.6.2)
rack (2.2.6.4)
rack-mini-profiler (3.0.0)
r2 (0.2.7)
racc (1.6.0)
rack (2.2.3)
rack-mini-profiler (2.3.3)
rack (>= 1.2.0)
rack-protection (3.0.5)
rack-protection (2.1.0)
rack
rack-test (2.1.0)
rack-test (2.0.2)
rack (>= 1.3)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.5.0)
loofah (~> 2.19, >= 2.19.1)
rails_failover (0.8.1)
activerecord (> 6.0, < 7.1)
rails-html-sanitizer (1.4.3)
loofah (~> 2.3)
rails_failover (0.7.3)
activerecord (~> 6.0)
concurrent-ruby
railties (> 6.0, < 7.1)
rails_multisite (4.0.1)
activerecord (> 5.0, < 7.1)
railties (> 5.0, < 7.1)
railties (7.0.4.3)
actionpack (= 7.0.4.3)
activesupport (= 7.0.4.3)
railties (~> 6.0)
rails_multisite (4.0.0)
activerecord (> 5.0, < 7)
railties (> 5.0, < 7)
railties (6.1.7.1)
actionpack (= 6.1.7.1)
activesupport (= 6.1.7.1)
method_source
rake (>= 12.2)
thor (~> 1.0)
zeitwerk (~> 2.5)
rainbow (3.1.1)
raindrops (0.20.1)
raindrops (0.20.0)
rake (13.0.6)
rb-fsevent (0.11.2)
rb-fsevent (0.11.0)
rb-inotify (0.10.1)
ffi (~> 1.0)
rbtrace (0.4.14)
@ -366,163 +353,136 @@ GEM
msgpack (>= 0.4.3)
optimist (>= 3.0.0)
rchardet (1.8.0)
redis (4.8.1)
redis-namespace (1.10.0)
redis (>= 4)
regexp_parser (2.7.0)
request_store (1.5.1)
redis (4.5.1)
redis-namespace (1.8.1)
redis (>= 3.0.4)
regexp_parser (2.2.0)
request_store (1.5.0)
rack (>= 1.4)
rexml (3.2.5)
rinku (2.0.6)
rotp (6.2.2)
rqrcode (2.1.2)
rotp (6.2.0)
rqrcode (2.1.0)
chunky_png (~> 1.0)
rqrcode_core (~> 1.0)
rqrcode_core (1.2.0)
rspec (3.12.0)
rspec-core (~> 3.12.0)
rspec-expectations (~> 3.12.0)
rspec-mocks (~> 3.12.0)
rspec-core (3.12.1)
rspec-support (~> 3.12.0)
rspec-expectations (3.12.2)
rspec (3.10.0)
rspec-core (~> 3.10.0)
rspec-expectations (~> 3.10.0)
rspec-mocks (~> 3.10.0)
rspec-core (3.10.1)
rspec-support (~> 3.10.0)
rspec-expectations (3.10.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-html-matchers (0.10.0)
rspec-support (~> 3.10.0)
rspec-html-matchers (0.9.4)
nokogiri (~> 1)
rspec (>= 3.0.0.a)
rspec-mocks (3.12.4)
rspec (>= 3.0.0.a, < 4)
rspec-mocks (3.10.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-rails (6.0.1)
actionpack (>= 6.1)
activesupport (>= 6.1)
railties (>= 6.1)
rspec-core (~> 3.11)
rspec-expectations (~> 3.11)
rspec-mocks (~> 3.11)
rspec-support (~> 3.11)
rspec-support (3.12.0)
rspec-support (~> 3.10.0)
rspec-rails (5.0.2)
actionpack (>= 5.2)
activesupport (>= 5.2)
railties (>= 5.2)
rspec-core (~> 3.10)
rspec-expectations (~> 3.10)
rspec-mocks (~> 3.10)
rspec-support (~> 3.10)
rspec-support (3.10.3)
rss (0.2.9)
rexml
rswag-specs (2.8.0)
activesupport (>= 3.1, < 7.1)
json-schema (>= 2.2, < 4.0)
railties (>= 3.1, < 7.1)
rspec-core (>= 2.14)
rtlcss (0.2.0)
mini_racer (~> 0.6.3)
rubocop (1.48.1)
json (~> 2.3)
rswag-specs (2.4.0)
activesupport (>= 3.1, < 7.0)
json-schema (~> 2.2)
railties (>= 3.1, < 7.0)
rtlit (0.0.5)
rubocop (1.25.0)
parallel (~> 1.10)
parser (>= 3.2.0.0)
parser (>= 3.1.0.0)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.26.0, < 2.0)
rexml
rubocop-ast (>= 1.15.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.27.0)
parser (>= 3.2.1.0)
rubocop-capybara (2.17.1)
rubocop (~> 1.41)
rubocop-discourse (3.2.0)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.15.1)
parser (>= 3.0.1.1)
rubocop-discourse (2.5.0)
rubocop (>= 1.1.0)
rubocop-rspec (>= 2.0.0)
rubocop-rspec (2.19.0)
rubocop (~> 1.33)
rubocop-capybara (~> 2.17)
ruby-prof (1.6.1)
ruby-progressbar (1.13.0)
rubocop-rspec (2.7.0)
rubocop (~> 1.19)
ruby-prof (1.4.3)
ruby-progressbar (1.11.0)
ruby-readability (0.7.0)
guess_html_encoding (>= 0.0.4)
nokogiri (>= 1.6.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
sanitize (6.0.1)
sanitize (6.0.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
sass-embedded (1.59.2)
google-protobuf (~> 3.21)
rake (>= 10.0.0)
sass-embedded (1.59.2-aarch64-linux-gnu)
google-protobuf (~> 3.21)
sass-embedded (1.59.2-arm64-darwin)
google-protobuf (~> 3.21)
sass-embedded (1.59.2-x86_64-darwin)
google-protobuf (~> 3.21)
sass-embedded (1.59.2-x86_64-linux-gnu)
google-protobuf (~> 3.21)
selenium-webdriver (4.8.1)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
shoulda-matchers (5.3.0)
sassc (2.0.1)
ffi (~> 1.9)
rake
sassc-rails (2.1.2)
railties (>= 4.0.0)
sassc (>= 2.0)
sprockets (> 3.0)
sprockets-rails
tilt
seed-fu (2.3.9)
activerecord (>= 3.1)
activesupport (>= 3.1)
shoulda-matchers (5.1.0)
activesupport (>= 5.2.0)
sidekiq (6.5.8)
connection_pool (>= 2.2.5, < 3)
sidekiq (6.3.1)
connection_pool (>= 2.2.2)
rack (~> 2.0)
redis (>= 4.5.0, < 5)
simplecov (0.22.0)
redis (>= 4.2.0)
simplecov (0.21.2)
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)
simplecov-html (0.12.3)
simplecov_json_formatter (0.1.4)
snaky_hash (2.0.1)
hashie
version_gem (~> 1.1, >= 1.1.1)
simplecov_json_formatter (0.1.3)
sprockets (3.7.2)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.4.2)
actionpack (>= 5.2)
activesupport (>= 5.2)
sprockets (>= 3.0.0)
sshkey (2.0.0)
stackprof (0.2.23)
syntax_tree (6.0.2)
prettier_print (>= 1.2.0)
syntax_tree-disable_ternary (1.0.0)
test-prof (1.2.0)
stackprof (0.2.17)
test-prof (1.0.7)
thor (1.2.1)
tilt (2.1.0)
timeout (0.3.2)
tzinfo (2.0.6)
tilt (2.0.10)
tzinfo (2.0.5)
concurrent-ruby (~> 1.0)
tzinfo-data (1.2022.7)
tzinfo (>= 1.0.0)
uglifier (4.2.0)
execjs (>= 0.3.0, < 3)
unf (0.1.4)
unf_ext
unf_ext (0.0.8.2)
unicode-display_width (2.4.2)
unf_ext (0.0.8)
unicode-display_width (2.1.0)
unicorn (6.1.0)
kgio (~> 2.6)
raindrops (~> 0.7)
uniform_notifier (1.16.0)
uri (0.12.0)
uniform_notifier (1.14.2)
uri (0.11.0)
uri_template (0.7.0)
version_gem (1.1.1)
web-push (3.0.0)
hkdf (~> 1.0)
jwt (~> 2.0)
openssl (~> 3.0)
webdrivers (5.2.0)
nokogiri (~> 1.6)
rubyzip (>= 1.3.0)
selenium-webdriver (~> 4.0)
webmock (3.18.1)
webmock (3.14.0)
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webrick (1.7.0)
websocket (1.2.9)
xorcist (1.1.3)
xpath (3.2.0)
nokogiri (~> 1.8)
yaml-lint (0.1.2)
yard (0.9.28)
webrick (~> 1.7.0)
zeitwerk (2.6.7)
webpush (1.1.0)
hkdf (~> 0.2)
jwt (~> 2.0)
xorcist (1.1.2)
yaml-lint (0.0.10)
zeitwerk (2.6.6)
PLATFORMS
aarch64-linux
@ -534,46 +494,42 @@ PLATFORMS
x86_64-linux
DEPENDENCIES
actionmailer (= 7.0.4.3)
actionpack (= 7.0.4.3)
actionview (= 7.0.4.3)
actionmailer (= 6.1.7.1)
actionpack (= 6.1.7.1)
actionview (= 6.1.7.1)
actionview_precompiler
active_model_serializers (~> 0.8.3)
activemodel (= 7.0.4.3)
activerecord (= 7.0.4.3)
activesupport (= 7.0.4.3)
activemodel (= 6.1.7.1)
activerecord (= 6.1.7.1)
activesupport (= 6.1.7.1)
addressable
annotate
aws-sdk-s3
aws-sdk-sns
barber
better_errors
binding_of_caller
bootsnap
bullet
byebug
capybara
cbor
certified
cgi (>= 0.3.6)
colored2
cose
cppjieba_rb
css_parser
dartsass-ruby
dartsass-sprockets
diffy
digest
discourse-ember-rails (= 0.18.6)
discourse-ember-source (~> 3.12.2)
discourse-fonts
discourse-seed-fu
discourse_dev_assets
email_reply_trimmer
ember-handlebars-template (= 0.8.0)
excon
execjs
fabrication
faker (~> 2.16)
fakeweb
faraday
faraday-retry
fast_blank
fast_xs
fastimage
@ -603,14 +559,12 @@ DEPENDENCIES
mini_suffix
minitest
mocha
mock_redis
multi_json
mustache
net-http
net-imap
net-pop
net-smtp
nokogiri
oj (= 3.13.14)
oj (= 3.13.2)
omniauth
omniauth-facebook
omniauth-github
@ -622,12 +576,13 @@ DEPENDENCIES
pry-byebug
pry-rails
puma
r2
rack
rack-mini-profiler
rack-protection
rails_failover
rails_multisite
railties (= 7.0.4.3)
railties (= 6.1.7.1)
rake
rb-fsevent
rbtrace
@ -642,35 +597,31 @@ DEPENDENCIES
rspec-rails
rss
rswag-specs
rtlcss
rtlit
rubocop-discourse
ruby-prof
ruby-readability
rubyzip
sanitize
selenium-webdriver
sassc (= 2.0.1)
sassc-rails
seed-fu
shoulda-matchers
sidekiq
simplecov
sprockets!
sprockets (= 3.7.2)
sprockets-rails
sshkey
stackprof
syntax_tree
syntax_tree-disable_ternary
test-prof
thor
tzinfo-data
uglifier
unf
unicorn
web-push
webdrivers
webmock
webrick
webpush
xorcist
yaml-lint
yard
BUNDLED WITH
2.4.4
2.3.16

View File

@ -12,9 +12,11 @@ To learn more about the philosophy and goals of the project, [visit **discourse.
## Screenshots
<a href="https://bbs.boingboing.net"><img alt="Boing Boing" src="https://user-images.githubusercontent.com/1681963/52239245-04ad8280-289c-11e9-9c88-8c173d4a0422.png" width="720px"></a>
<a href="https://twittercommunity.com/"><img src="https://user-images.githubusercontent.com/1681963/52239250-04ad8280-289c-11e9-9e42-574f6eaab9d7.png" width="720px"></a>
<a href="https://forums.gearboxsoftware.com/"><img src="https://user-images.githubusercontent.com/1681963/89088042-68ffb400-d364-11ea-93be-161ea04d8b29.png" width="720px"></a>
<img src="https://user-images.githubusercontent.com/1681963/52239118-b304f800-289b-11e9-9904-16450680d9ec.jpg" alt="Mobile" width="414">
@ -30,7 +32,7 @@ To get your environment setup, follow the community setup guide for your operati
If you're familiar with how Rails works and are comfortable setting up your own environment, you can also try out the [**Discourse Advanced Developer Guide**](docs/DEVELOPER-ADVANCED.md), which is aimed primarily at Ubuntu and macOS environments.
Before you get started, ensure you have the following minimum versions: [Ruby 3.2+](https://www.ruby-lang.org/en/downloads/), [PostgreSQL 13](https://www.postgresql.org/download/), [Redis 7](https://redis.io/download). If you're having trouble, please see our [**TROUBLESHOOTING GUIDE**](docs/TROUBLESHOOTING.md) first!
Before you get started, ensure you have the following minimum versions: [Ruby 2.7+](https://www.ruby-lang.org/en/downloads/), [PostgreSQL 13+](https://www.postgresql.org/download/), [Redis 6.0+](https://redis.io/download). If you're having trouble, please see our [**TROUBLESHOOTING GUIDE**](docs/TROUBLESHOOTING.md) first!
## Setting up Discourse
@ -38,6 +40,8 @@ If you want to set up a Discourse forum for production use, see our [**Discourse
If you're looking for business class hosting, see [discourse.org/buy](https://www.discourse.org/buy/).
If you're looking for our remote work solution, see [teams.discourse.com](https://teams.discourse.com/).
## Requirements
Discourse is built for the *next* 10 years of the Internet, so our requirements are high.
@ -51,8 +55,6 @@ Discourse supports the **latest, stable releases** of all major browsers and pla
| Microsoft Edge | | |
| Mozilla Firefox | | |
Additionally, we aim to support Safari on iOS 15.7+.
## Built With
- [Ruby on Rails](https://github.com/rails/rails) &mdash; Our back end API is a Rails app. It responds to requests RESTfully in JSON.
@ -91,7 +93,7 @@ The original Discourse code contributors can be found in [**AUTHORS.MD**](docs/A
## Copyright / License
Copyright 2014 - 2023 Civilized Discourse Construction Kit, Inc.
Copyright 2014 - 2021 Civilized Discourse Construction Kit, Inc.
Licensed under the GNU General Public License Version 2.0 (or later);
you may not use this work except in compliance with the License.
@ -107,10 +109,6 @@ limitations under the License.
Discourse logo and “Discourse Forum” ®, Civilized Discourse Construction Kit, Inc.
## Accessibility
To guide our ongoing effort to build accessible software we follow the [W3Cs Web Content Accessibility Guidelines (WCAG)](https://www.w3.org/TR/WCAG21/). If you'd like to report an accessibility issue that makes it difficult for you to use Discourse, email accessibility@discourse.org. For more information visit [discourse.org/accessibility](https://discourse.org/accessibility).
## Dedication
Discourse is built with [love, Internet style.](https://www.youtube.com/watch?v=Xe1TZaElTAs)

1
adminjs Symbolic link
View File

@ -0,0 +1 @@
app/assets/javascripts/admin

View File

@ -1 +0,0 @@
Images created in https://fa2png.app/ using 150px size and #919191 color.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 947 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -1,32 +0,0 @@
{
"licenses": {
"blueOak": "bronze",
"spdx": [
"CC0-1.0",
"CC-BY-3.0",
"CC-BY-4.0",
"Apache-2.0 WITH LLVM-exception",
"ISC"
]
},
"packages": {
"component-bind": "1.0.0",
"component-inherit": "0.0.3",
"duplex": "1.0.0",
"glob": "3.1.21",
"indexof": "0.0.1",
"inherits": "1.0.2",
"jsonify": "0.0.0",
"messageformat": "0.1.5",
"line-stream": "0.0.0",
"regenerator-transform": "0.10.1",
"source-map": "0.1.43",
"sourcemap-validator": "1.1.1"
},
"corrections": true,
"ignore": [
{
"author": "Discourse"
}
]
}

View File

@ -0,0 +1,20 @@
// discourse-skip-module
(function () {
setTimeout(function () {
const $activateButton = $("#activate-account-button");
$activateButton.on("click", function () {
$activateButton.prop("disabled", true);
const hpPath = document.getElementById("data-activate-account").dataset
.path;
$.ajax(hpPath)
.then(function (hp) {
$("#password_confirmation").val(hp.value);
$("#challenge").val(hp.challenge.split("").reverse().join(""));
$("#activate-account-form").submit();
})
.fail(function () {
$activateButton.prop("disabled", false);
});
});
}, 50);
})();

View File

@ -0,0 +1,13 @@
<%
require_asset("main_include_admin.js")
DiscoursePluginRegistry.admin_javascripts.each { |js| require_asset(js) }
DiscoursePluginRegistry.each_globbed_asset(admin: true) do |f|
if File.directory?(f)
depend_on(f)
else
require_asset(f)
end
end
%>

View File

@ -1,13 +1,13 @@
import RestAdapter from "discourse/adapters/rest";
import RESTAdapter from "discourse/adapters/rest";
export default class ApiKey extends RestAdapter {
jsonMode = true;
export default RESTAdapter.extend({
jsonMode: true,
basePath() {
return "/admin/api/";
}
},
apiNameFor() {
return "key";
}
}
},
});

View File

@ -1,11 +1,11 @@
import RestAdapter from "discourse/adapters/rest";
export default function buildPluginAdapter(pluginName) {
return class extends RestAdapter {
return RestAdapter.extend({
pathFor(store, type, findArgs) {
return (
"/admin/plugins/" + pluginName + super.pathFor(store, type, findArgs)
"/admin/plugins/" + pluginName + this._super(store, type, findArgs)
);
}
};
},
});
}

View File

@ -1,7 +1,7 @@
import RestAdapter from "discourse/adapters/rest";
export default class CustomizationBase extends RestAdapter {
export default RestAdapter.extend({
basePath() {
return "/admin/customize/";
}
}
},
});

View File

@ -1,7 +1,7 @@
import RestAdapter from "discourse/adapters/rest";
export default class EmailStyle extends RestAdapter {
export default RestAdapter.extend({
pathFor() {
return "/admin/customize/email_style";
}
}
},
});

View File

@ -1,7 +1,7 @@
import RestAdapter from "discourse/adapters/rest";
export default class Embedding extends RestAdapter {
export default RestAdapter.extend({
pathFor() {
return "/admin/customize/embedding";
}
}
},
});

View File

@ -1,7 +1,7 @@
import RestAdapter from "discourse/adapters/rest";
export default class StaffActionLog extends RestAdapter {
export default RestAdapter.extend({
basePath() {
return "/admin/logs/";
}
}
},
});

View File

@ -1,5 +1,5 @@
import RestAdapter from "discourse/adapters/rest";
export default class TagGroup extends RestAdapter {
jsonMode = true;
}
export default RestAdapter.extend({
jsonMode: true,
});

View File

@ -1,10 +1,9 @@
import RestAdapter from "discourse/adapters/rest";
export default class Theme extends RestAdapter {
jsonMode = true;
export default RestAdapter.extend({
basePath() {
return "/admin/";
}
},
afterFindAll(results) {
let map = {};
@ -21,5 +20,7 @@ export default class Theme extends RestAdapter {
theme.set("parentThemes", mappedParents);
});
return results;
}
}
},
jsonMode: true,
});

View File

@ -1,7 +1,7 @@
import RestAdapter from "discourse/adapters/rest";
import RESTAdapter from "discourse/adapters/rest";
export default class WebHookEvent extends RestAdapter {
export default RESTAdapter.extend({
basePath() {
return "/admin/api/";
}
}
},
});

View File

@ -1,7 +1,7 @@
import RestAdapter from "discourse/adapters/rest";
import RESTAdapter from "discourse/adapters/rest";
export default class WebHook extends RestAdapter {
export default RESTAdapter.extend({
basePath() {
return "/admin/api/";
}
}
},
});

View File

@ -1 +0,0 @@
<div class="ace">{{this.content}}</div>

View File

@ -1,33 +1,30 @@
import { action } from "@ember/object";
import { classNames } from "@ember-decorators/component";
import { observes, on } from "@ember-decorators/object";
import Component from "@ember/component";
import getURL from "discourse-common/lib/get-url";
import loadScript from "discourse/lib/load-script";
import I18n from "I18n";
import { bind } from "discourse-common/utils/decorators";
import { bind, observes } from "discourse-common/utils/decorators";
import { on } from "@ember/object/evented";
const COLOR_VARS_REGEX =
/\$(primary|secondary|tertiary|quaternary|header_background|header_primary|highlight|danger|success|love)(\s|;|-(low|medium|high))/g;
const COLOR_VARS_REGEX = /\$(primary|secondary|tertiary|quaternary|header_background|header_primary|highlight|danger|success|love)(\s|;|-(low|medium|high))/g;
@classNames("ace-wrapper")
export default class AceEditor extends Component {
mode = "css";
disabled = false;
htmlPlaceholder = false;
_editor = null;
_skipContentChangeEvent = null;
export default Component.extend({
mode: "css",
classNames: ["ace-wrapper"],
_editor: null,
_skipContentChangeEvent: null,
disabled: false,
htmlPlaceholder: false,
@observes("editorId")
editorIdChanged() {
if (this.autofocus) {
this.send("focus");
}
}
},
didRender() {
this._skipContentChangeEvent = false;
}
},
@observes("content")
contentChanged() {
@ -35,14 +32,14 @@ export default class AceEditor extends Component {
if (this._editor && !this._skipContentChangeEvent) {
this._editor.getSession().setValue(content);
}
}
},
@observes("mode")
modeChanged() {
if (this._editor && !this._skipContentChangeEvent) {
this._editor.getSession().setMode("ace/mode/" + this.mode);
}
}
},
@observes("placeholder")
placeholderChanged() {
@ -51,12 +48,12 @@ export default class AceEditor extends Component {
placeholder: this.placeholder,
});
}
}
},
@observes("disabled")
disabledStateChanged() {
this.changeDisabledState();
}
},
changeDisabledState() {
const editor = this._editor;
@ -69,10 +66,9 @@ export default class AceEditor extends Component {
});
editor.container.parentNode.setAttribute("data-disabled", disabled);
}
}
},
@on("willDestroyElement")
_destroyEditor() {
_destroyEditor: on("willDestroyElement", function () {
if (this._editor) {
this._editor.destroy();
this._editor = null;
@ -83,16 +79,16 @@ export default class AceEditor extends Component {
}
$(window).off("ace:resize");
}
}),
resize() {
if (this._editor) {
this._editor.resize();
}
}
},
didInsertElement() {
super.didInsertElement(...arguments);
this._super(...arguments);
loadScript("/javascripts/ace/ace.js").then(() => {
window.ace.require(["ace/ace"], (loadedAce) => {
loadedAce.config.set("loadWorkerFromBlob", false);
@ -156,13 +152,11 @@ export default class AceEditor extends Component {
this._darkModeListener.addListener(this.setAceTheme);
});
});
}
},
willDestroyElement() {
if (this._darkModeListener) {
this._darkModeListener.removeListener(this.setAceTheme);
}
}
this._darkModeListener.removeListener(this.setAceTheme);
},
@bind
setAceTheme() {
@ -173,7 +167,7 @@ export default class AceEditor extends Component {
this._editor.setTheme(
`ace/theme/${schemeType === "dark" ? "chaos" : "chrome"}`
);
}
},
warnSCSSDeprecations() {
if (
@ -200,20 +194,21 @@ export default class AceEditor extends Component {
this._editor.getSession().setAnnotations(warnings);
this.setWarning?.(
this.setWarning(
warnings.length
? I18n.t("admin.customize.theme.scss_color_variables_warning")
: false
);
}
},
@action
focus() {
if (this._editor) {
this._editor.focus();
this._editor.navigateFileEnd();
}
}
actions: {
focus() {
if (this._editor) {
this._editor.focus();
this._editor.navigateFileEnd();
}
},
},
_overridePlaceholder(loadedAce) {
const originalPlaceholderSetter =
@ -241,5 +236,5 @@ export default class AceEditor extends Component {
this.$updatePlaceholder();
};
}
}
},
});

View File

@ -1,8 +0,0 @@
{{#if this.hasFormattedLogs}}
<pre>{{this.formattedLogs}}</pre>
{{else}}
<p>{{this.noLogsMessage}}</p>
{{/if}}
{{#if this.showLoadingSpinner}}
<div class="spinner small"></div>
{{/if}}

View File

@ -1,26 +1,28 @@
import { classNames } from "@ember-decorators/component";
import { observes, on } from "@ember-decorators/object";
import { observes, on } from "discourse-common/utils/decorators";
import Component from "@ember/component";
import I18n from "I18n";
import discourseDebounce from "discourse-common/lib/debounce";
import { scheduleOnce } from "@ember/runloop";
@classNames("admin-backups-logs")
export default class AdminBackupsLogs extends Component {
showLoadingSpinner = false;
hasFormattedLogs = false;
noLogsMessage = I18n.t("admin.backups.logs.none");
formattedLogs = "";
index = 0;
export default Component.extend({
classNames: ["admin-backups-logs"],
showLoadingSpinner: false,
hasFormattedLogs: false,
noLogsMessage: I18n.t("admin.backups.logs.none"),
init() {
this._super(...arguments);
this._reset();
},
_reset() {
this.setProperties({ formattedLogs: "", index: 0 });
}
},
_scrollDown() {
const div = this.element;
div.scrollTop = div.scrollHeight;
}
},
@on("init")
@observes("logs.[]")
@ -29,7 +31,7 @@ export default class AdminBackupsLogs extends Component {
this._reset(); // reset the cached logs whenever the model is reset
this.renderLogs();
}
}
},
_updateFormattedLogsFunc() {
const logs = this.logs;
@ -53,13 +55,13 @@ export default class AdminBackupsLogs extends Component {
this.renderLogs();
scheduleOnce("afterRender", this, this._scrollDown);
}
},
@on("init")
@observes("logs.[]")
_updateFormattedLogs() {
discourseDebounce(this, this._updateFormattedLogsFunc, 150);
}
},
renderLogs() {
const formattedLogs = this.formattedLogs;
@ -74,5 +76,5 @@ export default class AdminBackupsLogs extends Component {
} else {
this.set("showLoadingSpinner", false);
}
}
}
},
});

View File

@ -1,30 +0,0 @@
<div class="field">{{i18n this.name}}</div>
<div class="value">
{{#if this.editing}}
<TextField
@value={{this.buffer}}
@autofocus="autofocus"
@autocomplete="off"
/>
{{else}}
<a href {{on "click" this.edit}} class="inline-editable-field">
<span>{{this.value}}</span>
</a>
{{/if}}
</div>
<div class="controls">
{{#if this.editing}}
<DButton
@class="btn-default"
@action={{action "save"}}
@label="admin.user_fields.save"
/>
<a href {{on "click" this.edit}}>{{i18n "cancel"}}</a>
{{else}}
<DButton
@class="btn-default"
@action={{action "edit"}}
@icon="pencil-alt"
/>
{{/if}}
</div>

View File

@ -1,22 +1,24 @@
import { tagName } from "@ember-decorators/component";
import Component from "@ember/component";
import { action } from "@ember/object";
export default Component.extend({
tagName: "",
@tagName("")
export default class AdminEditableField extends Component {
buffer = "";
editing = false;
buffer: "",
editing: false,
@action
edit(event) {
event?.preventDefault();
this.set("buffer", this.value);
this.toggleProperty("editing");
}
init() {
this._super(...arguments);
this.set("editing", false);
},
@action
save() {
// Action has to toggle 'editing' property.
this.action(this.buffer);
}
}
actions: {
edit() {
this.set("buffer", this.value);
this.toggleProperty("editing");
},
save() {
// Action has to toggle 'editing' property.
this.action(this.buffer);
},
},
});

View File

@ -1,14 +0,0 @@
<div class="form-element label-area">
{{#if this.label}}
<label>{{i18n this.label}}</label>
{{else}}
&nbsp;
{{/if}}
</div>
<div class="form-element input-area">
{{#if this.wrapLabel}}
<label>{{yield}}</label>
{{else}}
{{yield}}
{{/if}}
</div>

View File

@ -1,5 +1,4 @@
import { classNames } from "@ember-decorators/component";
import Component from "@ember/component";
@classNames("row")
export default class AdminFormRow extends Component {}
export default Component.extend({
classNames: ["row"],
});

View File

@ -1,10 +1,9 @@
import { tagName } from "@ember-decorators/component";
import Component from "@ember/component";
import loadScript from "discourse/lib/load-script";
@tagName("canvas")
export default class AdminGraph extends Component {
type = "line";
export default Component.extend({
tagName: "canvas",
type: "line",
refreshChart() {
const ctx = this.element.getContext("2d");
@ -50,11 +49,11 @@ export default class AdminGraph extends Component {
};
this._chart = new window.Chart(ctx, config);
}
},
didInsertElement() {
loadScript("/javascripts/Chart.min.js").then(() =>
this.refreshChart.apply(this)
);
}
}
},
});

View File

@ -1,7 +0,0 @@
<div class="admin-controls">
<nav>
<ul class="nav nav-pills">
{{yield}}
</ul>
</nav>
</div>

View File

@ -1,5 +1,4 @@
import { tagName } from "@ember-decorators/component";
import Component from "@ember/component";
@tagName("")
export default class AdminNav extends Component {}
export default Component.extend({
tagName: "",
});

View File

@ -1,14 +0,0 @@
<div
class="suspended-count {{this.suspendedCountClass}}"
title={{i18n "admin.user.last_six_months"}}
>
<label>{{i18n "admin.user.suspended_count"}}</label>
<span>{{this.user.penalty_counts.suspended}}</span>
</div>
<div
class="silenced-count {{this.silencedCountClass}}"
title={{i18n "admin.user.last_six_months"}}
>
<label>{{i18n "admin.user.silenced_count"}}</label>
<span>{{this.user.penalty_counts.silenced}}</span>
</div>

View File

@ -1,16 +1,16 @@
import { classNames } from "@ember-decorators/component";
import Component from "@ember/component";
import discourseComputed from "discourse-common/utils/decorators";
@classNames("penalty-history")
export default class AdminPenaltyHistory extends Component {
export default Component.extend({
classNames: ["penalty-history"],
@discourseComputed("user.penalty_counts.suspended")
suspendedCountClass(count) {
if (count > 0) {
return "danger";
}
return "";
}
},
@discourseComputed("user.penalty_counts.silenced")
silencedCountClass(count) {
@ -18,5 +18,5 @@ export default class AdminPenaltyHistory extends Component {
return "danger";
}
return "";
}
}
},
});

View File

@ -1,18 +0,0 @@
<div class="penalty-post-controls">
<label>
<div class="penalty-post-label">
{{html-safe (i18n "admin.user.penalty_post_actions")}}
</div>
</label>
<ComboBox
@value={{this.postAction}}
@content={{this.penaltyActions}}
@onChange={{action "penaltyChanged"}}
/>
</div>
{{#if this.editing}}
<div class="penalty-post-edit">
<Textarea @value={{this.postEdit}} class="post-editor" />
</div>
{{/if}}

View File

@ -1,41 +0,0 @@
import { action } from "@ember/object";
import { equal } from "@ember/object/computed";
import Component from "@ember/component";
import discourseComputed, {
afterRender,
} from "discourse-common/utils/decorators";
import I18n from "I18n";
const ACTIONS = ["delete", "delete_replies", "edit", "none"];
export default class AdminPenaltyPostAction extends Component {
postId = null;
postAction = null;
postEdit = null;
@equal("postAction", "edit") editing;
@discourseComputed
penaltyActions() {
return ACTIONS.map((id) => {
return { id, name: I18n.t(`admin.user.penalty_post_${id}`) };
});
}
@action
penaltyChanged(postAction) {
this.set("postAction", postAction);
// If we switch to edit mode, jump to the edit textarea
if (postAction === "edit") {
this._focusEditTextarea();
}
}
@afterRender
_focusEditTextarea() {
const elem = this.element;
const body = elem.closest(".modal-body");
body.scrollTo(0, body.clientHeight);
elem.querySelector(".post-editor").focus();
}
}

View File

@ -1,40 +0,0 @@
<div class="penalty-reason-controls">
{{#if (eq @penaltyType "suspend")}}
<label class="suspend-reason-title">{{i18n
"admin.user.suspend_reason_title"
}}</label>
<ComboBox
@content={{this.reasons}}
@value={{this.selectedReason}}
@class="suspend-reason"
@onChange={{this.setSelectedReason}}
/>
{{#if this.isCustomReason}}
<TextField
@value={{this.customReason}}
@class="suspend-reason"
@onChange={{this.setCustomReason}}
/>
{{/if}}
{{else if (eq @penaltyType "silence")}}
<label class="silence-reason-title">{{html-safe
(i18n "admin.user.silence_reason_label")
}}</label>
<TextField
@value={{this.customReason}}
@class="silence-reason"
@onChange={{this.setCustomReason}}
@placeholderKey="admin.user.silence_reason_placeholder"
/>
{{/if}}
</div>
<div class="penalty-message-controls">
<label>{{i18n "admin.user.suspend_message"}}</label>
<Textarea
@value={{this.message}}
class="suspend-message"
placeholder={{i18n "admin.user.suspend_message_placeholder"}}
/>
</div>

View File

@ -1,55 +0,0 @@
import { tagName } from "@ember-decorators/component";
import { equal } from "@ember/object/computed";
import Component from "@ember/component";
import { action } from "@ember/object";
import discourseComputed from "discourse-common/utils/decorators";
import I18n from "I18n";
const CUSTOM_REASON_KEY = "custom";
@tagName("")
export default class AdminPenaltyReason extends Component {
selectedReason = CUSTOM_REASON_KEY;
customReason = "";
reasonKeys = [
"not_listening_to_staff",
"consuming_staff_time",
"combative",
"in_wrong_place",
"no_constructive_purpose",
CUSTOM_REASON_KEY,
];
@equal("selectedReason", CUSTOM_REASON_KEY) isCustomReason;
@discourseComputed("reasonKeys")
reasons(keys) {
return keys.map((key) => {
return { id: key, name: I18n.t(`admin.user.suspend_reasons.${key}`) };
});
}
@action
setSelectedReason(value) {
this.set("selectedReason", value);
this.setReason();
}
@action
setCustomReason(value) {
this.set("customReason", value);
this.setReason();
}
setReason() {
if (this.isCustomReason) {
this.set("reason", this.customReason);
} else {
this.set(
"reason",
I18n.t(`admin.user.suspend_reasons.${this.selectedReason}`)
);
}
}
}

View File

@ -1,44 +0,0 @@
<div class="penalty-similar-users">
<p class="alert alert-warning">
{{html-safe
(i18n
"admin.user.other_matches"
(hash count=this.user.similar_users_count username=this.user.username)
)
}}
</p>
<table class="table">
<thead>
<tr>
<th></th>
<th>{{i18n "username"}}</th>
<th>{{i18n "last_seen"}}</th>
<th>{{i18n "admin.user.topics_entered"}}</th>
<th>{{i18n "admin.user.posts_read_count"}}</th>
<th>{{i18n "admin.user.time_read"}}</th>
<th>{{i18n "created"}}</th>
</tr>
</thead>
<tbody>
{{#each this.user.similar_users as |user|}}
<tr>
<td>
<Input
@type="checkbox"
disabled={{not (get user this.penaltyField)}}
{{on "click" (action "selectUserId" user.id)}}
/>
</td>
<td>{{avatar user imageSize="small"}} {{user.username}}</td>
<td>{{format-duration user.last_seen_age}}</td>
<td>{{number user.topics_entered}}</td>
<td>{{number user.posts_read_count}}</td>
<td>{{format-duration user.time_read}}</td>
<td>{{format-duration user.created_at_age}}</td>
</tr>
{{/each}}
</tbody>
</table>
</div>

View File

@ -1,29 +0,0 @@
import { tagName } from "@ember-decorators/component";
import Component from "@ember/component";
import { action } from "@ember/object";
import discourseComputed from "discourse-common/utils/decorators";
@tagName("")
export default class AdminPenaltySimilarUsers extends Component {
@discourseComputed("penaltyType")
penaltyField(penaltyType) {
if (penaltyType === "suspend") {
return "can_be_suspended";
} else if (penaltyType === "silence") {
return "can_be_silenced";
}
}
@action
selectUserId(userId, event) {
if (!this.selectedUserIds) {
return;
}
if (event.target.checked) {
this.selectedUserIds.pushObject(userId);
} else {
this.selectedUserIds.removeObject(userId);
}
}
}

View File

@ -1,3 +0,0 @@
<div class="chart-canvas-container">
<canvas class="chart-canvas"></canvas>
</div>

View File

@ -1,4 +1,3 @@
import { classNames } from "@ember-decorators/component";
import Report from "admin/models/report";
import Component from "@ember/component";
import discourseDebounce from "discourse-common/lib/debounce";
@ -8,31 +7,31 @@ import { number } from "discourse/lib/formatter";
import { schedule } from "@ember/runloop";
import { bind } from "discourse-common/utils/decorators";
@classNames("admin-report-chart")
export default class AdminReportChart extends Component {
limit = 8;
total = 0;
options = null;
export default Component.extend({
classNames: ["admin-report-chart"],
limit: 8,
total: 0,
options: null,
didInsertElement() {
super.didInsertElement(...arguments);
this._super(...arguments);
window.addEventListener("resize", this._resizeHandler);
}
},
willDestroyElement() {
super.willDestroyElement(...arguments);
this._super(...arguments);
window.removeEventListener("resize", this._resizeHandler);
this._resetChart();
}
},
didReceiveAttrs() {
super.didReceiveAttrs(...arguments);
this._super(...arguments);
discourseDebounce(this, this._scheduleChartRendering, 100);
}
},
_scheduleChartRendering() {
schedule("afterRender", () => {
@ -41,7 +40,7 @@ export default class AdminReportChart extends Component {
this.element && this.element.querySelector(".chart-canvas")
);
});
}
},
_renderChart(model, chartCanvas) {
if (!chartCanvas) {
@ -100,7 +99,7 @@ export default class AdminReportChart extends Component {
this._buildChartConfig(data, this.options)
);
});
}
},
_buildChartConfig(data, options) {
return {
@ -162,21 +161,21 @@ export default class AdminReportChart extends Component {
},
},
};
}
},
_resetChart() {
if (this._chart) {
this._chart.destroy();
this._chart = null;
}
}
},
_applyChartGrouping(model, data, options) {
return Report.collapse(model, data, options.chartGrouping);
}
},
@bind
_resizeHandler() {
discourseDebounce(this, this._scheduleChartRendering, 500);
}
}
},
});

View File

@ -1,35 +0,0 @@
<div class="cell title">
{{#if this.model.icon}}
{{d-icon this.model.icon}}
{{/if}}
<a href={{this.model.reportUrl}}>{{this.model.title}}</a>
</div>
<div class="cell value today-count">{{number this.model.todayCount}}</div>
<div
class="cell value yesterday-count {{this.model.yesterdayTrend}}"
title={{this.model.yesterdayCountTitle}}
>
{{number this.model.yesterdayCount}}
{{d-icon this.model.yesterdayTrendIcon}}
</div>
<div
class="cell value sevendays-count {{this.model.sevenDaysTrend}}"
title={{this.model.sevenDaysCountTitle}}
>
{{number this.model.lastSevenDaysCount}}
{{d-icon this.model.sevenDaysTrendIcon}}
</div>
<div
class="cell value thirty-days-count {{this.model.thirtyDaysTrend}}"
title={{this.model.thirtyDaysCountTitle}}
>
{{number this.model.lastThirtyDaysCount}}
{{#if this.model.canDisplayTrendIcon}}
{{d-icon this.model.thirtyDaysTrendIcon}}
{{/if}}
</div>

View File

@ -1,6 +1,6 @@
import { attributeBindings, classNames } from "@ember-decorators/component";
import Component from "@ember/component";
export default Component.extend({
classNames: ["admin-report-counters"],
@classNames("admin-report-counters")
@attributeBindings("model.description:title")
export default class AdminReportCounters extends Component {}
attributeBindings: ["model.description:title"],
});

View File

@ -1,36 +0,0 @@
<td class="title">
{{#if this.report.icon}}
{{d-icon this.report.icon}}
{{/if}}
<a href={{this.report.reportUrl}}>{{this.report.title}}</a>
</td>
<td class="value">{{number this.report.todayCount}}</td>
<td
class="value {{this.report.yesterdayTrend}}"
title={{this.report.yesterdayCountTitle}}
>
{{number this.report.yesterdayCount}}
{{d-icon this.report.yesterdayTrendIcon}}
</td>
<td
class="value {{this.report.sevenDaysTrend}}"
title={{this.report.sevenDaysCountTitle}}
>
{{number this.report.lastSevenDaysCount}}
{{d-icon this.report.sevenDaysTrendIcon}}
</td>
<td
class="value {{this.report.thirtyDaysTrend}}"
title={{this.report.thirtyDaysCountTitle}}
>
{{number this.report.lastThirtyDaysCount}}
{{d-icon this.report.thirtyDaysTrendIcon}}
</td>
{{#if this.allTime}}
<td class="value">{{number this.report.total}}</td>
{{/if}}

View File

@ -1,12 +1,11 @@
import { classNameBindings, tagName } from "@ember-decorators/component";
import { match } from "@ember/object/computed";
import Component from "@ember/component";
@tagName("tr")
@classNameBindings("reverseColors")
export default class AdminReportCounts extends Component {
allTime = true;
@match("report.type", /^(time_to_first_response|topics_with_no_response)$/)
reverseColors;
}
import { match } from "@ember/object/computed";
export default Component.extend({
allTime: true,
tagName: "tr",
reverseColors: match(
"report.type",
/^(time_to_first_response|topics_with_no_response)$/
),
classNameBindings: ["reverseColors"],
});

View File

@ -1,15 +0,0 @@
<div class="table-container">
{{#each this.model.data as |data|}}
<a class="table-cell user-{{data.key}}" href={{data.url}}>
<span class="label">
{{#if data.icon}}
{{d-icon data.icon}}
{{/if}}
{{data.x}}
</span>
<span class="value">
{{number data.y}}
</span>
</a>
{{/each}}
</div>

View File

@ -1,5 +1,4 @@
import { classNames } from "@ember-decorators/component";
import Component from "@ember/component";
@classNames("admin-report-inline-table")
export default class AdminReportInlineTable extends Component {}
export default Component.extend({
classNames: ["admin-report-inline-table"],
});

View File

@ -1,8 +0,0 @@
<td class="title"><a
href={{this.report.reportUrl}}
>{{this.report.title}}</a></td>
<td class="value">{{this.report.todayCount}}</td>
<td class="value">{{this.report.yesterdayCount}}</td>
<td class="value">{{this.report.sevenDaysAgoCount}}</td>
<td class="value">{{this.report.thirtyDaysAgoCount}}</td>
<td class="value"></td>

View File

@ -1,5 +1,4 @@
import { tagName } from "@ember-decorators/component";
import Component from "@ember/component";
@tagName("tr")
export default class AdminReportPerDayCounts extends Component {}
export default Component.extend({
tagName: "tr",
});

View File

@ -1,3 +0,0 @@
<div class="chart-canvas-container">
<canvas class="chart-canvas"></canvas>
</div>

View File

@ -1,4 +1,3 @@
import { classNames } from "@ember-decorators/component";
import Report from "admin/models/report";
import Component from "@ember/component";
import discourseDebounce from "discourse-common/lib/debounce";
@ -8,31 +7,32 @@ import { number } from "discourse/lib/formatter";
import { schedule } from "@ember/runloop";
import { bind } from "discourse-common/utils/decorators";
@classNames("admin-report-chart", "admin-report-stacked-chart")
export default class AdminReportStackedChart extends Component {
export default Component.extend({
classNames: ["admin-report-chart", "admin-report-stacked-chart"],
didInsertElement() {
super.didInsertElement(...arguments);
this._super(...arguments);
window.addEventListener("resize", this._resizeHandler);
}
},
willDestroyElement() {
super.willDestroyElement(...arguments);
this._super(...arguments);
window.removeEventListener("resize", this._resizeHandler);
this._resetChart();
}
},
didReceiveAttrs() {
super.didReceiveAttrs(...arguments);
this._super(...arguments);
discourseDebounce(this, this._scheduleChartRendering, 100);
}
},
@bind
_resizeHandler() {
discourseDebounce(this, this._scheduleChartRendering, 500);
}
},
_scheduleChartRendering() {
schedule("afterRender", () => {
@ -45,7 +45,7 @@ export default class AdminReportStackedChart extends Component {
this.element.querySelector(".chart-canvas")
);
});
}
},
_renderChart(model, chartCanvas) {
if (!chartCanvas) {
@ -54,13 +54,7 @@ export default class AdminReportStackedChart extends Component {
const context = chartCanvas.getContext("2d");
const chartData = makeArray(model.chartData || model.data).map((cd) => {
return {
label: cd.label,
color: cd.color,
data: Report.collapse(model, cd.data),
};
});
const chartData = makeArray(model.get("chartData") || model.get("data"));
const data = {
labels: chartData[0].data.mapBy("x"),
@ -68,7 +62,7 @@ export default class AdminReportStackedChart extends Component {
return {
label: cd.label,
stack: "pageviews-stack",
data: cd.data,
data: Report.collapse(model, cd.data),
backgroundColor: cd.color,
};
}),
@ -79,7 +73,7 @@ export default class AdminReportStackedChart extends Component {
this._chart = new window.Chart(context, this._buildChartConfig(data));
});
}
},
_buildChartConfig(data) {
return {
@ -150,10 +144,10 @@ export default class AdminReportStackedChart extends Component {
},
},
};
}
},
_resetChart() {
this._chart?.destroy();
this._chart = null;
}
}
},
});

View File

@ -1,54 +0,0 @@
{{#if this.showBackupStats}}
<div class="backups">
<h3 class="storage-stats-title">
<a href={{get-url "/admin/backups"}}>{{d-icon "archive"}}
{{i18n "admin.dashboard.backups"}}</a>
</h3>
<p>
{{#if this.backupStats.free_bytes}}
{{i18n
"admin.dashboard.space_used_and_free"
usedSize=this.usedBackupSpace
freeSize=this.freeBackupSpace
}}
{{else}}
{{i18n "admin.dashboard.space_used" usedSize=this.usedBackupSpace}}
{{/if}}
<br />
{{i18n
"admin.dashboard.backup_count"
count=this.backupStats.count
location=this.backupLocationName
}}
{{#if this.backupStats.last_backup_taken_at}}
<br />
{{html-safe
(i18n
"admin.dashboard.lastest_backup"
date=(format-date
this.backupStats.last_backup_taken_at leaveAgo="true"
)
)
}}
{{/if}}
</p>
</div>
{{/if}}
<div class="uploads">
<h3 class="storage-stats-title">{{d-icon "upload"}}
{{i18n "admin.dashboard.uploads"}}</h3>
<p>
{{#if this.uploadStats.free_bytes}}
{{i18n
"admin.dashboard.space_used_and_free"
usedSize=this.usedUploadSpace
freeSize=this.freeUploadSpace
}}
{{else}}
{{i18n "admin.dashboard.space_used" usedSize=this.usedUploadSpace}}
{{/if}}
</p>
</div>

View File

@ -1,45 +1,43 @@
import { classNames } from "@ember-decorators/component";
import { alias } from "@ember/object/computed";
import Component from "@ember/component";
import I18n from "I18n";
import { alias } from "@ember/object/computed";
import discourseComputed from "discourse-common/utils/decorators";
import { setting } from "discourse/lib/computed";
@classNames("admin-report-storage-stats")
export default class AdminReportStorageStats extends Component {
@setting("backup_location") backupLocation;
export default Component.extend({
classNames: ["admin-report-storage-stats"],
@alias("model.data.backups") backupStats;
@alias("model.data.uploads") uploadStats;
backupLocation: setting("backup_location"),
backupStats: alias("model.data.backups"),
uploadStats: alias("model.data.uploads"),
@discourseComputed("backupStats")
showBackupStats(stats) {
return stats && this.currentUser.admin;
}
},
@discourseComputed("backupLocation")
backupLocationName(backupLocation) {
return I18n.t(`admin.backups.location.${backupLocation}`);
}
},
@discourseComputed("backupStats.used_bytes")
usedBackupSpace(bytes) {
return I18n.toHumanSize(bytes);
}
},
@discourseComputed("backupStats.free_bytes")
freeBackupSpace(bytes) {
return I18n.toHumanSize(bytes);
}
},
@discourseComputed("uploadStats.used_bytes")
usedUploadSpace(bytes) {
return I18n.toHumanSize(bytes);
}
},
@discourseComputed("uploadStats.free_bytes")
freeUploadSpace(bytes) {
return I18n.toHumanSize(bytes);
}
}
},
});

View File

@ -1 +0,0 @@
{{html-safe this.formattedValue}}

View File

@ -1,27 +1,21 @@
import {
attributeBindings,
classNameBindings,
classNames,
tagName,
} from "@ember-decorators/component";
import { alias } from "@ember/object/computed";
import Component from "@ember/component";
import { alias } from "@ember/object/computed";
import discourseComputed from "discourse-common/utils/decorators";
@tagName("td")
@classNames("admin-report-table-cell")
@classNameBindings("type", "property")
@attributeBindings("value:title")
export default class AdminReportTableCell extends Component {
options = null;
@alias("label.type") type;
@alias("label.mainProperty") property;
@alias("computedLabel.formattedValue") formattedValue;
@alias("computedLabel.value") value;
export default Component.extend({
tagName: "td",
classNames: ["admin-report-table-cell"],
classNameBindings: ["type", "property"],
attributeBindings: ["value:title"],
options: null,
@discourseComputed("label", "data", "options")
computedLabel(label, data, options) {
return label.compute(data, options || {});
}
}
},
type: alias("label.type"),
property: alias("label.mainProperty"),
formatedValue: alias("computedLabel.formatedValue"),
value: alias("computedLabel.value"),
});

View File

@ -1,13 +0,0 @@
{{#if this.showSortingUI}}
<DButton
@action={{this.sortByLabel}}
@icon={{this.sortIcon}}
@class="sort-btn"
/>
{{/if}}
{{#if this.label.htmlTitle}}
<span class="title">{{html-safe this.label.htmlTitle}}</span>
{{else}}
<span class="title">{{this.label.title}}</span>
{{/if}}

View File

@ -1,24 +1,19 @@
import {
attributeBindings,
classNameBindings,
classNames,
tagName,
} from "@ember-decorators/component";
import Component from "@ember/component";
import discourseComputed from "discourse-common/utils/decorators";
@tagName("th")
@classNames("admin-report-table-header")
@classNameBindings("label.mainProperty", "label.type", "isCurrentSort")
@attributeBindings("label.title:title")
export default class AdminReportTableHeader extends Component {
export default Component.extend({
tagName: "th",
classNames: ["admin-report-table-header"],
classNameBindings: ["label.mainProperty", "label.type", "isCurrentSort"],
attributeBindings: ["label.title:title"],
@discourseComputed("currentSortLabel.sortProperty", "label.sortProperty")
isCurrentSort(currentSortField, labelSortField) {
return currentSortField === labelSortField;
}
},
@discourseComputed("currentSortDirection")
sortIcon(currentSortDirection) {
return currentSortDirection === 1 ? "caret-up" : "caret-down";
}
}
},
});

View File

@ -1,7 +0,0 @@
{{#each this.labels as |label|}}
<AdminReportTableCell
@label={{label}}
@data={{this.data}}
@options={{this.options}}
/>
{{/each}}

View File

@ -1,8 +1,6 @@
import { classNames, tagName } from "@ember-decorators/component";
import Component from "@ember/component";
@tagName("tr")
@classNames("admin-report-table-row")
export default class AdminReportTableRow extends Component {
options = null;
}
export default Component.extend({
tagName: "tr",
classNames: ["admin-report-table-row"],
options: null,
});

View File

@ -1,84 +0,0 @@
<table class="table">
<thead>
<tr>
{{#if this.model.computedLabels}}
{{#each this.model.computedLabels as |label|}}
<AdminReportTableHeader
@showSortingUI={{this.showSortingUI}}
@currentSortDirection={{this.sortDirection}}
@currentSortLabel={{this.sortLabel}}
@label={{label}}
@sortByLabel={{action "sortByLabel" label}}
/>
{{/each}}
{{else}}
{{#each this.model.data as |data|}}
<th>{{data.x}}</th>
{{/each}}
{{/if}}
</tr>
</thead>
<tbody>
{{#each this.paginatedData as |data|}}
<AdminReportTableRow
@data={{data}}
@labels={{this.model.computedLabels}}
@options={{this.options}}
/>
{{/each}}
{{#if this.showTotalForSample}}
<tr class="total-row">
<td colspan={{this.totalsForSample.length}}>
{{i18n "admin.dashboard.reports.totals_for_sample"}}
</td>
</tr>
<tr class="admin-report-table-row">
{{#each this.totalsForSample as |total|}}
<td class="admin-report-table-cell {{total.type}} {{total.property}}">
{{total.formattedValue}}
</td>
{{/each}}
</tr>
{{/if}}
{{#if this.showTotal}}
<tr class="total-row">
<td colspan="2">
{{i18n "admin.dashboard.reports.total"}}
</td>
</tr>
<tr class="admin-report-table-row">
<td class="admin-report-table-cell date x">—</td>
<td class="admin-report-table-cell number y">{{number
this.model.total
}}</td>
</tr>
{{/if}}
{{#if this.showAverage}}
<tr class="total-row">
<td colspan="2">
{{i18n "admin.dashboard.reports.average_for_sample"}}
</td>
</tr>
<tr class="admin-report-table-row">
<td class="admin-report-table-cell date x">—</td>
<td class="admin-report-table-cell number y">{{number
this.averageForSample
}}</td>
</tr>
{{/if}}
</tbody>
</table>
<div class="pagination">
{{#each this.pages as |pageState|}}
<DButton
@translatedLabel={{pageState.page}}
@action={{action "changePage"}}
@actionParam={{pageState.index}}
@class={{pageState.class}}
/>
{{/each}}
</div>

View File

@ -1,26 +1,22 @@
import { action } from "@ember/object";
import { classNameBindings, classNames } from "@ember-decorators/component";
import { alias } from "@ember/object/computed";
import Component from "@ember/component";
import { alias } from "@ember/object/computed";
import discourseComputed from "discourse-common/utils/decorators";
import { makeArray } from "discourse-common/lib/helpers";
const PAGES_LIMIT = 8;
@classNameBindings("sortable", "twoColumns")
@classNames("admin-report-table")
export default class AdminReportTable extends Component {
sortable = false;
sortDirection = 1;
@alias("options.perPage") perPage;
page = 0;
export default Component.extend({
classNameBindings: ["sortable", "twoColumns"],
classNames: ["admin-report-table"],
sortable: false,
sortDirection: 1,
perPage: alias("options.perPage"),
page: 0,
@discourseComputed("model.computedLabels.length")
twoColumns(labelsLength) {
return labelsLength === 2;
}
},
@discourseComputed(
"totalsForSample",
@ -35,12 +31,12 @@ export default class AdminReportTable extends Component {
.reduce((s, v) => s + v, 0);
return sum >= 1 && total && datesFiltering;
}
},
@discourseComputed("model.total", "options.total", "twoColumns")
showTotal(reportTotal, total, twoColumns) {
return reportTotal && total && twoColumns;
}
},
@discourseComputed(
"model.{average,data}",
@ -54,17 +50,17 @@ export default class AdminReportTable extends Component {
sampleTotalValue &&
hasTwoColumns
);
}
},
@discourseComputed("totalsForSample.1.value", "model.data.length")
averageForSample(totals, count) {
return (totals / count).toFixed(0);
}
},
@discourseComputed("model.data.length")
showSortingUI(dataLength) {
return dataLength >= 5;
}
},
@discourseComputed("totalsForSampleRow", "model.computedLabels")
totalsForSample(row, labels) {
@ -74,7 +70,7 @@ export default class AdminReportTable extends Component {
computedLabel.property = label.mainProperty;
return computedLabel;
});
}
},
@discourseComputed("model.data", "model.computedLabels")
totalsForSampleRow(rows, labels) {
@ -102,7 +98,7 @@ export default class AdminReportTable extends Component {
});
return totalsRow;
}
},
@discourseComputed("sortLabel", "sortDirection", "model.data.[]")
sortedData(sortLabel, sortDirection, data) {
@ -122,7 +118,7 @@ export default class AdminReportTable extends Component {
}
return data;
}
},
@discourseComputed("sortedData.[]", "perPage", "page")
paginatedData(data, perPage, page) {
@ -132,7 +128,7 @@ export default class AdminReportTable extends Component {
}
return data;
}
},
@discourseComputed("model.data", "perPage", "page")
pages(data, perPage, page) {
@ -160,19 +156,19 @@ export default class AdminReportTable extends Component {
}
return pages;
}
},
@action
changePage(page) {
this.set("page", page);
}
actions: {
changePage(page) {
this.set("page", page);
},
@action
sortByLabel(label) {
if (this.sortLabel === label) {
this.set("sortDirection", this.sortDirection === 1 ? -1 : 1);
} else {
this.set("sortLabel", label);
}
}
}
sortByLabel(label) {
if (this.sortLabel === label) {
this.set("sortDirection", this.sortDirection === 1 ? -1 : 1);
} else {
this.set("sortLabel", label);
}
},
},
});

View File

@ -1,26 +0,0 @@
<td class="title">{{this.report.title}}</td>
<td class="value">
<LinkTo @route="adminUsersList.show" @model="newuser">
{{number (value-at-tl this.report.data level="0")}}
</LinkTo>
</td>
<td class="value">
<LinkTo @route="adminUsersList.show" @model="basic">
{{number (value-at-tl this.report.data level="1")}}
</LinkTo>
</td>
<td class="value">
<LinkTo @route="adminUsersList.show" @model="member">
{{number (value-at-tl this.report.data level="2")}}
</LinkTo>
</td>
<td class="value">
<LinkTo @route="adminUsersList.show" @model="regular">
{{number (value-at-tl this.report.data level="3")}}
</LinkTo>
</td>
<td class="value">
<LinkTo @route="adminUsersList.show" @model="leader">
{{number (value-at-tl this.report.data level="4")}}
</LinkTo>
</td>

View File

@ -1,5 +1,4 @@
import { tagName } from "@ember-decorators/component";
import Component from "@ember/component";
@tagName("tr")
export default class AdminReportTrustLevelCounts extends Component {}
export default Component.extend({
tagName: "tr",
});

View File

@ -1,244 +0,0 @@
{{#unless this.isHidden}}
{{#if this.isEnabled}}
<ConditionalLoadingSection @isLoading={{this.isLoading}}>
{{#if this.showHeader}}
<div class="header">
{{#if this.showTitle}}
<ul class="breadcrumb">
{{#if this.showAllReportsLink}}
<li class="item all-reports">
<LinkTo @route="admin.dashboardReports" class="report-url">
{{i18n "admin.dashboard.all_reports"}}
</LinkTo>
</li>
{{#unless this.showNotFoundError}}
<li class="item separator">|</li>
{{/unless}}
{{/if}}
{{#unless this.showNotFoundError}}
<li class="item report">
<a href={{this.model.reportUrl}} class="report-url">
{{this.model.title}}
</a>
{{#if this.model.description}}
{{#if this.model.description_link}}
<a
target="_blank"
rel="noopener noreferrer"
href={{this.model.description_link}}
class="info"
data-tooltip={{this.model.description}}
>
{{d-icon "question-circle"}}
</a>
{{else}}
<span
class="info"
data-tooltip={{this.model.description}}
>
{{d-icon "question-circle"}}
</span>
{{/if}}
{{/if}}
</li>
{{/unless}}
</ul>
{{/if}}
{{#if this.shouldDisplayTrend}}
<div class="trend {{this.model.trend}}">
<span class="value" title={{this.model.trendTitle}}>
{{#if this.model.average}}
{{number this.model.currentAverage}}{{#if
this.model.percent
}}%{{/if}}
{{else}}
{{number this.model.currentTotal noTitle="true"}}{{#if
this.model.percent
}}%{{/if}}
{{/if}}
{{#if this.model.trendIcon}}
{{d-icon this.model.trendIcon class="icon"}}
{{/if}}
</span>
</div>
{{/if}}
</div>
{{/if}}
<div class="body">
<div class="main">
{{#if this.showError}}
{{#if this.showTimeoutError}}
<div class="alert alert-error report-alert timeout">
{{d-icon "exclamation-triangle"}}
<span>{{i18n "admin.dashboard.timeout_error"}}</span>
</div>
{{/if}}
{{#if this.showExceptionError}}
<div class="alert alert-error report-alert exception">
{{d-icon "exclamation-triangle"}}
<span>{{i18n "admin.dashboard.exception_error"}}</span>
</div>
{{/if}}
{{#if this.showNotFoundError}}
<div class="alert alert-error report-alert not-found">
{{d-icon "exclamation-triangle"}}
<span>{{i18n "admin.dashboard.not_found_error"}}</span>
</div>
{{/if}}
{{else}}
{{#if this.hasData}}
{{#if this.currentMode}}
{{component
this.modeComponent
model=this.model
options=this.options
}}
{{#if this.model.relatedReport}}
<AdminReport
@showFilteringUI={{false}}
@dataSourceName={{this.model.relatedReport.type}}
/>
{{/if}}
{{/if}}
{{else}}
{{#if this.rateLimitationString}}
<div class="alert alert-error report-alert rate-limited">
{{d-icon "thermometer-three-quarters"}}
<span>{{this.rateLimitationString}}</span>
</div>
{{else}}
<div class="alert alert-info report-alert no-data">
{{d-icon "chart-pie"}}
{{#if this.model.reportUrl}}
<a href={{this.model.reportUrl}} class="report-url">
<span>
{{#if this.model.title}}
{{this.model.title}}
{{/if}}
{{i18n "admin.dashboard.reports.no_data"}}
</span>
</a>
{{else}}
<span>{{i18n "admin.dashboard.reports.no_data"}}</span>
{{/if}}
</div>
{{/if}}
{{/if}}
{{/if}}
</div>
{{#if this.showFilteringUI}}
<div class="filters">
{{#if this.showModes}}
<div class="modes">
{{#each this.displayedModes as |displayedMode|}}
<DButton
@action={{action "onChangeMode"}}
@actionParam={{displayedMode.mode}}
@class={{displayedMode.cssClass}}
@icon={{displayedMode.icon}}
/>
{{/each}}
</div>
{{/if}}
{{#if this.isChartMode}}
{{#if this.model.average}}
<span class="average-chart">
{{i18n "admin.dashboard.reports.average_chart_label"}}
</span>
{{/if}}
<div class="chart-groupings">
{{#each this.chartGroupings as |chartGrouping|}}
<DButton
@label={{chartGrouping.label}}
@action={{action "changeGrouping" chartGrouping.id}}
@class={{chartGrouping.class}}
@disabled={{chartGrouping.disabled}}
/>
{{/each}}
</div>
{{/if}}
{{#if this.showDatesOptions}}
<div class="control">
<span class="label">
{{i18n "admin.dashboard.reports.dates"}}
</span>
<div class="input">
<DateTimeInputRange
@from={{this.startDate}}
@to={{this.endDate}}
@onChange={{action "onChangeDateRange"}}
@showFromTime={{false}}
@showToTime={{false}}
/>
</div>
</div>
{{/if}}
{{#each this.model.available_filters as |filter|}}
<div class="control">
<span class="label">
{{i18n
(concat
"admin.dashboard.reports.filters." filter.id ".label"
)
}}
</span>
<div class="input">
{{component
(concat "report-filters/" filter.type)
model=this.model
filter=filter
applyFilter=(action "applyFilter")
}}
</div>
</div>
{{/each}}
<div class="control">
<div class="input">
<DButton
@class="btn-default export-csv-btn"
@action={{action "exportCsv"}}
@label="admin.export_csv.button_text"
@icon="download"
/>
</div>
</div>
{{#if this.showRefresh}}
<div class="control">
<div class="input">
<DButton
@class="refresh-report-btn btn-primary"
@action={{action "refreshReport"}}
@label="admin.dashboard.reports.refresh_report"
@icon="sync"
/>
</div>
</div>
{{/if}}
</div>
{{/if}}
</div>
</ConditionalLoadingSection>
{{else}}
<div class="alert alert-info">
{{html-safe this.disabledLabel}}
</div>
{{/if}}
{{/unless}}

View File

@ -1,7 +1,6 @@
import { classNameBindings, classNames } from "@ember-decorators/component";
import { alias, and, equal, notEmpty, or } from "@ember/object/computed";
import EmberObject, { action, computed } from "@ember/object";
import Report, { DAILY_LIMIT_DAYS, SCHEMA_VERSION } from "admin/models/report";
import { alias, and, equal, notEmpty, or } from "@ember/object/computed";
import Component from "@ember/component";
import I18n from "I18n";
import ReportLoader from "discourse/lib/reports-loader";
@ -22,58 +21,51 @@ const TABLE_OPTIONS = {
const CHART_OPTIONS = {};
@classNameBindings(
"isHidden:hidden",
"isHidden::is-visible",
"isEnabled",
"isLoading",
"dasherizedDataSourceName"
)
@classNames("admin-report")
export default class AdminReport extends Component {
isEnabled = true;
disabledLabel = I18n.t("admin.dashboard.disabled");
isLoading = false;
rateLimitationString = null;
dataSourceName = null;
report = null;
model = null;
reportOptions = null;
forcedModes = null;
showAllReportsLink = false;
filters = null;
showTrend = false;
showHeader = true;
showTitle = true;
showFilteringUI = false;
export default Component.extend({
classNameBindings: [
"isHidden:hidden",
"isHidden::is-visible",
"isEnabled",
"isLoading",
"dasherizedDataSourceName",
],
classNames: ["admin-report"],
isEnabled: true,
disabledLabel: I18n.t("admin.dashboard.disabled"),
isLoading: false,
rateLimitationString: null,
dataSourceName: null,
report: null,
model: null,
reportOptions: null,
forcedModes: null,
showAllReportsLink: false,
filters: null,
showTrend: false,
showHeader: true,
showTitle: true,
showFilteringUI: false,
showDatesOptions: alias("model.dates_filtering"),
showRefresh: or("showDatesOptions", "model.available_filters.length"),
shouldDisplayTrend: and("showTrend", "model.prev_period"),
endDate: null,
startDate: null,
@alias("model.dates_filtering") showDatesOptions;
init() {
this._super(...arguments);
@or("showDatesOptions", "model.available_filters.length") showRefresh;
this._reports = [];
},
@and("showTrend", "model.prev_period") shouldDisplayTrend;
endDate = null;
startDate = null;
@or("showTimeoutError", "showExceptionError", "showNotFoundError") showError;
@equal("model.error", "not_found") showNotFoundError;
@equal("model.error", "timeout") showTimeoutError;
@equal("model.error", "exception") showExceptionError;
@notEmpty("model.data") hasData;
_reports = [];
@computed("siteSettings.dashboard_hidden_reports")
get isHidden() {
isHidden: computed("siteSettings.dashboard_hidden_reports", function () {
return (this.siteSettings.dashboard_hidden_reports || "")
.split("|")
.filter(Boolean)
.includes(this.dataSourceName);
}
}),
didReceiveAttrs() {
super.didReceiveAttrs(...arguments);
this._super(...arguments);
let startDate = moment();
if (this.filters && isPresent(this.filters.startDate)) {
@ -96,35 +88,42 @@ export default class AdminReport extends Component {
} else if (this.dataSourceName) {
this._fetchReport();
}
}
},
showError: or("showTimeoutError", "showExceptionError", "showNotFoundError"),
showNotFoundError: equal("model.error", "not_found"),
showTimeoutError: equal("model.error", "timeout"),
showExceptionError: equal("model.error", "exception"),
hasData: notEmpty("model.data"),
@discourseComputed("dataSourceName", "model.type")
dasherizedDataSourceName(dataSourceName, type) {
return (dataSourceName || type || "undefined").replace(/_/g, "-");
}
},
@discourseComputed("dataSourceName", "model.type")
dataSource(dataSourceName, type) {
dataSourceName = dataSourceName || type;
return `/admin/reports/${dataSourceName}`;
}
},
@discourseComputed("displayedModes.length")
showModes(displayedModesLength) {
return displayedModesLength > 1;
}
},
@discourseComputed("currentMode")
isChartMode(currentMode) {
return currentMode === "chart";
}
},
@action
changeGrouping(grouping) {
this.send("refreshReport", {
chartGrouping: grouping,
});
}
},
@discourseComputed("currentMode", "model.modes", "forcedModes")
displayedModes(currentMode, reportModes, forcedModes) {
@ -140,12 +139,12 @@ export default class AdminReport extends Component {
icon: mode === "table" ? "table" : "signal",
};
});
}
},
@discourseComputed("currentMode")
modeComponent(currentMode) {
return `admin-report-${currentMode.replace(/_/g, "-")}`;
}
},
@discourseComputed(
"dataSourceName",
@ -179,7 +178,7 @@ export default class AdminReport extends Component {
.join(":");
return reportKey;
}
},
@discourseComputed("options.chartGrouping", "model.chartData.length")
chartGroupings(grouping, count) {
@ -193,7 +192,7 @@ export default class AdminReport extends Component {
class: `chart-grouping ${grouping === id ? "active" : "inactive"}`,
};
});
}
},
@action
onChangeDateRange(range) {
@ -201,7 +200,7 @@ export default class AdminReport extends Component {
startDate: range.from,
endDate: range.to,
});
}
},
@action
applyFilter(id, value) {
@ -216,7 +215,7 @@ export default class AdminReport extends Component {
this.send("refreshReport", {
filters: customFilters,
});
}
},
@action
refreshReport(options = {}) {
@ -239,7 +238,7 @@ export default class AdminReport extends Component {
? this.get("filters.customFilters")
: options.filters,
});
}
},
@action
exportCsv() {
@ -255,7 +254,7 @@ export default class AdminReport extends Component {
}
exportEntity("report", args).then(outputExportResult);
}
},
@action
onChangeMode(mode) {
@ -264,7 +263,7 @@ export default class AdminReport extends Component {
this.send("refreshReport", {
chartGrouping: null,
});
}
},
_computeReport() {
if (!this.element || this.isDestroying || this.isDestroyed) {
@ -307,7 +306,7 @@ export default class AdminReport extends Component {
}
this._renderReport(report, this.forcedModes, this.currentMode);
}
},
_renderReport(report, forcedModes, currentMode) {
const modes = forcedModes ? forcedModes.split(",") : report.modes;
@ -318,9 +317,11 @@ export default class AdminReport extends Component {
currentMode,
options: this._buildOptions(currentMode, report),
});
}
},
_fetchReport() {
this._super(...arguments);
this.setProperties({ isLoading: true, rateLimitationString: null });
next(() => {
@ -348,7 +349,7 @@ export default class AdminReport extends Component {
ReportLoader.enqueue(this.dataSourceName, payload.data, callback);
});
}
},
_buildPayload(facets) {
let payload = { data: { facets } };
@ -374,7 +375,7 @@ export default class AdminReport extends Component {
}
return payload;
}
},
_buildOptions(mode, report) {
if (mode === "table") {
@ -392,7 +393,7 @@ export default class AdminReport extends Component {
})
);
}
}
},
_loadReport(jsonReport) {
Report.fillMissingDates(jsonReport, { filledField: "chartData" });
@ -422,5 +423,5 @@ export default class AdminReport extends Component {
}
return Report.create(jsonReport);
}
}
},
});

View File

@ -1,130 +0,0 @@
<div class="edit-main-nav admin-controls">
<nav>
<ul class="nav nav-pills target">
{{#each this.visibleTargets as |target|}}
<li>
<LinkTo
@route={{this.editRouteName}}
@models={{array this.theme.id target.name this.fieldName}}
@replace={{true}}
title={{this.field.title}}
class={{if target.edited "edited" "blank"}}
>
{{#if target.error}}{{d-icon "exclamation-triangle"}}{{/if}}
{{#if target.icon}}{{d-icon target.icon}}{{/if}}
{{i18n (concat "admin.customize.theme." target.name)}}
</LinkTo>
</li>
{{/each}}
{{#if this.allowAdvanced}}
<li>
<a
{{on "click" this.toggleShowAdvanced}}
href
title={{i18n
(concat
"admin.customize.theme."
(if this.showAdvanced "hide_advanced" "show_advanced")
)
}}
class="no-text"
>
{{d-icon
(if this.showAdvanced "angle-double-left" "angle-double-right")
}}
</a>
</li>
{{/if}}
<li class="spacer"></li>
<li>
<label>
<Input
@type="checkbox"
@checked={{this.onlyOverridden}}
{{on
"click"
(action this.onlyOverriddenChanged value="target.checked")
}}
/>
{{i18n "admin.customize.theme.hide_unused_fields"}}
</label>
</li>
</ul>
</nav>
</div>
<div class="admin-controls">
<nav>
<ul class="nav nav-pills fields">
{{#each this.visibleFields as |field|}}
<li>
<LinkTo
@route={{this.editRouteName}}
@models={{array this.theme.id this.currentTargetName field.name}}
@replace={{true}}
title={{field.title}}
class={{if field.edited "edited" "blank"}}
>
{{#if field.error}}{{d-icon "exclamation-triangle"}}{{/if}}
{{#if field.icon}}{{d-icon field.icon}}{{/if}}
{{field.translatedName}}
</LinkTo>
</li>
{{/each}}
{{#if this.showAddField}}
<li>
{{#if this.addingField}}
<Input
@type={{this.text}}
@value={{this.newFieldName}}
@enter={{action "addField"}}
@escape-press={{action "cancelAddField"}}
/>
<DButton
@class="ok"
@action={{action "addField" this.newFieldName}}
@icon="check"
/>
<DButton
@class="cancel"
@action={{action "cancelAddField"}}
@icon="times"
/>
{{else}}
<a href {{on "click" this.toggleAddField}} class="no-text">
{{d-icon "plus"}}
</a>
{{/if}}
</li>
{{/if}}
<li class="spacer"></li>
<li>
<a href {{on "click" this.toggleMaximize}} class="no-text">
{{d-icon this.maximizeIcon}}
</a>
</li>
</ul>
</nav>
</div>
{{#if this.error}}
<pre class="field-error">{{this.error}}</pre>
{{/if}}
{{#if this.warning}}
<pre class="field-warning">{{html-safe this.warning}}</pre>
{{/if}}
<AceEditor
@content={{this.activeSection}}
@editorId={{this.editorId}}
@mode={{this.activeSectionMode}}
@autofocus="true"
@placeholder={{this.placeholder}}
@htmlPlaceholder={{true}}
@save={{this.save}}
@setWarning={{action "setWarning"}}
/>

View File

@ -3,13 +3,10 @@ import I18n from "I18n";
import discourseComputed from "discourse-common/utils/decorators";
import { fmt } from "discourse/lib/computed";
import { isDocumentRTL } from "discourse/lib/text-direction";
import { action, computed } from "@ember/object";
import { next } from "@ember/runloop";
export default class AdminThemeEditor extends Component {
warning = null;
@fmt("fieldName", "currentTargetName", "%@|%@") editorId;
export default Component.extend({
warning: null,
@discourseComputed("theme.targets", "onlyOverridden", "showAdvanced")
visibleTargets(targets, onlyOverridden, showAdvanced) {
@ -22,7 +19,7 @@ export default class AdminThemeEditor extends Component {
}
return target.edited;
});
}
},
@discourseComputed("currentTargetName", "onlyOverridden", "theme.fields")
visibleFields(targetName, onlyOverridden, fields) {
@ -31,7 +28,7 @@ export default class AdminThemeEditor extends Component {
fields = fields.filter((field) => field.edited);
}
return fields;
}
},
@discourseComputed("currentTargetName", "fieldName")
activeSectionMode(targetName, fieldName) {
@ -44,8 +41,8 @@ export default class AdminThemeEditor extends Component {
if (["color_definitions"].includes(fieldName)) {
return "scss";
}
return fieldName && fieldName.includes("scss") ? "scss" : "html";
}
return fieldName && fieldName.indexOf("scss") > -1 ? "scss" : "html";
},
@discourseComputed("currentTargetName", "fieldName")
placeholder(targetName, fieldName) {
@ -60,27 +57,30 @@ export default class AdminThemeEditor extends Component {
});
}
return "";
}
},
@computed("fieldName", "currentTargetName", "theme")
get activeSection() {
return this.theme.getField(this.currentTargetName, this.fieldName);
}
@discourseComputed("fieldName", "currentTargetName", "theme")
activeSection: {
get(fieldName, target, model) {
return model.getField(target, fieldName);
},
set(value, fieldName, target, model) {
model.setField(target, fieldName, value);
return value;
},
},
set activeSection(value) {
this.theme.setField(this.currentTargetName, this.fieldName, value);
return value;
}
editorId: fmt("fieldName", "currentTargetName", "%@|%@"),
@discourseComputed("maximized")
maximizeIcon(maximized) {
return maximized ? "discourse-compress" : "discourse-expand";
}
},
@discourseComputed("currentTargetName", "theme.targets")
showAddField(currentTargetName, targets) {
return targets.find((t) => t.name === currentTargetName).customNames;
}
},
@discourseComputed(
"currentTargetName",
@ -89,45 +89,46 @@ export default class AdminThemeEditor extends Component {
)
error(target, fieldName) {
return this.theme.getError(target, fieldName);
}
},
@action
toggleShowAdvanced(event) {
event?.preventDefault();
this.toggleProperty("showAdvanced");
}
actions: {
toggleShowAdvanced() {
this.toggleProperty("showAdvanced");
},
@action
toggleAddField(event) {
event?.preventDefault();
this.toggleProperty("addingField");
}
toggleAddField() {
this.toggleProperty("addingField");
},
@action
toggleMaximize(event) {
event?.preventDefault();
this.toggleProperty("maximized");
next(() => this.appEvents.trigger("ace:resize"));
}
cancelAddField() {
this.set("addingField", false);
},
@action
cancelAddField() {
this.set("addingField", false);
}
addField(name) {
if (!name) {
return;
}
name = name.replace(/[^a-zA-Z0-9-_/]/g, "");
this.theme.setField(this.currentTargetName, name, "");
this.setProperties({ newFieldName: "", addingField: false });
this.fieldAdded(this.currentTargetName, name);
},
@action
addField(name) {
if (!name) {
return;
}
name = name.replace(/[^a-zA-Z0-9-_/]/g, "");
this.theme.setField(this.currentTargetName, name, "");
this.setProperties({ newFieldName: "", addingField: false });
this.fieldAdded(this.currentTargetName, name);
}
toggleMaximize() {
this.toggleProperty("maximized");
next(() => this.appEvents.trigger("ace:resize"));
},
@action
setWarning(message) {
this.set("warning", message);
}
}
onlyOverriddenChanged(value) {
this.onlyOverriddenChanged(value);
},
save() {
this.attrs.save();
},
setWarning(message) {
this.set("warning", message);
},
},
});

View File

@ -1,114 +0,0 @@
<div class="user-field">
{{#if (or this.isEditing (not this.userField.id))}}
<AdminFormRow @label="admin.user_fields.type">
<ComboBox
@content={{this.fieldTypes}}
@value={{this.buffered.field_type}}
@onChange={{action (mut this.buffered.field_type)}}
/>
</AdminFormRow>
<AdminFormRow @label="admin.user_fields.name">
<Input
@value={{this.buffered.name}}
class="user-field-name"
maxlength="255"
/>
</AdminFormRow>
<AdminFormRow @label="admin.user_fields.description">
<Input
@value={{this.buffered.description}}
class="user-field-desc"
maxlength="255"
/>
</AdminFormRow>
{{#if this.bufferedFieldType.hasOptions}}
<AdminFormRow @label="admin.user_fields.options">
<ValueList @values={{this.buffered.options}} @inputType="array" />
</AdminFormRow>
{{/if}}
<AdminFormRow @wrapLabel="true">
<Input @type="checkbox" @checked={{this.buffered.editable}} />
<span>{{i18n "admin.user_fields.editable.title"}}</span>
</AdminFormRow>
<AdminFormRow @wrapLabel="true">
<Input @type="checkbox" @checked={{this.buffered.required}} />
<span>{{i18n "admin.user_fields.required.title"}}</span>
</AdminFormRow>
<AdminFormRow @wrapLabel="true">
<Input @type="checkbox" @checked={{this.buffered.show_on_profile}} />
<span>{{i18n "admin.user_fields.show_on_profile.title"}}</span>
</AdminFormRow>
<AdminFormRow @wrapLabel="true">
<Input @type="checkbox" @checked={{this.buffered.show_on_user_card}} />
<span>{{i18n "admin.user_fields.show_on_user_card.title"}}</span>
</AdminFormRow>
<AdminFormRow @wrapLabel="true">
<Input @type="checkbox" @checked={{this.buffered.searchable}} />
<span>{{i18n "admin.user_fields.searchable.title"}}</span>
</AdminFormRow>
<AdminFormRow>
<DButton
@action={{action "save"}}
@class="btn-primary save"
@icon="check"
@label="admin.user_fields.save"
/>
<DButton
@action={{action "cancel"}}
@class="btn-danger cancel"
@icon="times"
@label="admin.user_fields.cancel"
/>
</AdminFormRow>
{{else}}
<div class="row">
<div class="form-display">
<b class="name">{{this.userField.name}}</b>
<br />
<span class="description">{{html-safe
this.userField.description
}}</span>
</div>
<div class="form-display field-type">{{this.fieldName}}</div>
<div class="form-element controls">
<DButton
@action={{action "edit"}}
@class="btn-default edit"
@icon="pencil-alt"
@label="admin.user_fields.edit"
/>
<DButton
@action={{this.destroyAction}}
@actionParam={{this.userField}}
@class="btn-danger cancel"
@icon="far-trash-alt"
@label="admin.user_fields.delete"
/>
<DButton
@action={{this.moveUpAction}}
@actionParam={{this.userField}}
@class="btn-default"
@icon="arrow-up"
@disabled={{this.cantMoveUp}}
/>
<DButton
@action={{this.moveDownAction}}
@actionParam={{this.userField}}
@class="btn-default"
@icon="arrow-down"
@disabled={{this.cantMoveDown}}
/>
</div>
</div>
<div class="row">{{this.flags}}</div>
{{/if}}
</div>

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