* transliterate when generating attribute names to avoid emptiness
If you enter a non-ascii (non `\w` matching) string as the profile
field label, the attribute name is the empty string.
This causes problems outlined in #16391
To avoid losing user provided data, transliterate (Sterile is the same
tool we're using for Article#title_to_slug) before matching against
the word regex.
If we persist an empty string, or persist a non-`\w` name, the
coordinating regex in Profile::ATTRIBUTE_NAME_REGEX will leave a nil
match and raise NoMethodError (the method missing is for
match[:attribute_name] when match was nil, not Profile - that's the
next commit.
* Guard against nil matches
If an attribute name doesn't match the regex, the match is nil, and
trying to access (nil)[:attribute_name] raises a NoMethodError.
If there was no match, assume profile does not respond to the
selector, and don't handle it in method missing.
* Ensure generated attribute name is valid before saving
This raises a validation error if the generated name (from the label)
would be empty.
It's not an optimal error message (since the user can't see the
internal attribute name) but it prevents persisting broken/empty data
* actually raise error when validating
validate/valid? only return true or false (and set errors on the
object). In order to reject the creation, we need to raise a
validation error, not only call validate. I think this is because the
execution of before_create hooks happens after validation (which is
why the validation was only checked on update, not create).
* Generate an attribute name completely independent of the field label
This prevents mistakenly labeling a field "Class" or "Association" or
one of the other hundred public methods an AR model like Profile
exposes. Since attribute_name will be passed to `profile.public_send`
we really shouldn't build selectors from user supplied inputs.
* Use the admin supplied label in the sidebar
The profile decorator is used in the Users#show page to populate the
sidebar fields. Don't use the attribute name (which we mangled during
creation, and now generate randomly) as the label, use the label.
* Make the label lookup null safe, and filter attributes more
* Update data update script to not expect predictable labels
This is low impact since it ran in july, but we no longer know what
attribute name a label will create.
* Fix moderator spec
"Test Field" label no longer predictably generates :test_field as an
attribute name. Ask the field what it's name is before asking profile
about it.
* Fix profile preview card request spec
Remove the assumption that profile responds to a method name based on
the label for Work and Education fields.
* Update old DUS and its test
This can probably be archived
* Update profile spec to use fields generated attribute names
We used to "know" how attributes were generated from labels. Now we don't.
* update e2e seeds for profile field change
* Don't expect attribute name to be based on the label
* expect created profile fields respond to their attribute name
* Update system test
The label, not the attribute name, is shown on the profile form (the
field has an id related to the attribute name, but the view shows the
mutable/human-readable label).
* Keep the field title lowercase when sending the json preview card
The userMetadata component expects "work" and "education" to be
attributes of the metadata, but the ui_attributes_for() method was
titlizing these (for display).
Ideally we wouldn't have "special purposed" these two field names, but
they're there.
* update profile field by attribute name, not based on label
* Update profile field removal assumptions
We don't know what the method selectors will be, we have to ask.
* remove old test
* Update translations for Education and Work
Since the ui_attributes_for(area:) now gives the label, not the
attribute, we need to match the label of the profile field.
Note to self: this exposes an issue in localizing the custom profile
fields (probably a bigger problem for large, international communities
like DEV than some others, but trying to match static translation
files against user-modifiable database records seems like a problem
we'll see again).
* Empty commit to retrigger buildkite
* Remove profile field migration update scripts
Cloned the specs from the other "remove unused scripts" script.
* Remove unused scripts
The data update script removes the entry from the table (recording
that these have run) - we also want to remove the files (preventing
them from running again).
* remove unneeded spec for removed file
* when translation for header area field not found, use the title
Only Work and Education already have keys in the yml translation file,
and there's not a great (or easy?) way to make multiple translations
on these fields right now.
Since an admin can create a new field, and assign it to the header
area, we can't assume the code has a configured translation key for
this field.
Fallback to the title (we do this in another context already) if
there's no translation.
* PR feedback: Avoid n+1 query for labels
the original implementation of "label_for_attribute" had an n+1 query
looping over each matched key.
Follow suggested improvement and pull labels and attributes at once
from the db and modify the returned hash.
* Downcase title before looking for translation key
This avoids putting "odd" capitalized keys into the yml translation
file
Revert addition of "Work" and "Education" to the users files.
* use a let binding for duplicated test data
* Update app/models/profile_field.rb
prefer SecureRandom.hex for a dashless uuid (instead of removing the dashes).
Co-authored-by: Jamie Gaskins <jgaskins@hey.com>
Co-authored-by: Jamie Gaskins <jgaskins@hey.com>
* Ensuring confirmation and flash message for spaces
This change delivers an accessible form, and while it doesn't remove the
Save button nor produce a modal it does deliver the minimum viable
functionality.
In conversations with Suzanne, we spent an hour looking at how we might
make an accessible modal with the checkbox and state management
required as we as removing save buttons.
There are two paths:
1. Extend the current, yet deprecated, stimulus modal controller.
2. Extend the Preact modal work done for the Members Detail View.
We spent about 15 minutes pursuing the stimulus modal controller route,
and realized how much cruft it added to the system. Not ideal and very
opaque in it's interaction.
The second one we talked about, but for our alloted time was inadequate
to begin further work. To deliver on that generalized preact modal will
require at least an afternoon of work.
Closesforem/forem#17032
* Update config/locales/controllers/admin/fr.yml
Co-authored-by: Ridhwana <Ridhwana.Khan16@gmail.com>
* Update app/views/admin/spaces/index.html.erb
Co-authored-by: Ridhwana <Ridhwana.Khan16@gmail.com>
Co-authored-by: Ridhwana <Ridhwana.Khan16@gmail.com>
* Added a way to sort comments on an article
* Sorting of comments now uses crayons-dropwn. Some minor fixes as per comments on PR
* Add and fix test cases for sorting comments functionality
* Changes in code for sort comments. Code is more aligned with forem's conventions
* Added cyperss tests for sort comments on an article. Cleaned up code to better follow forem conventions
* Get fresh handle of triggerButton everytime clickOustideListener is clicked. Fix Cypress test cases to reflect the earlier.
* Fixed hiding 'Click to edit' link for drafts
* Improve "click to edit" link spec
Co-authored-by: Julianna Tetreault <32834804+juliannatetreault@users.noreply.github.com>
* Make the expectation more clear
Co-authored-by: Julianna Tetreault <32834804+juliannatetreault@users.noreply.github.com>
Co-authored-by: Julianna Tetreault <32834804+juliannatetreault@users.noreply.github.com>
* Trigger Build
* WIP - use turbo to render html for create post button
todos and discussion topics
[] add tests (probably gonna be a lot of cypress 😅😭)
[] nominclature & file structure for authorization controller/routes
[] is this "authorizations" namespace approach the best?
[] authorization strategy relies on current user and caching doesn't
like `current_user`
* Use URL helper and not change the policy just yet
* put the turbo frame behind a feature flag
* Trigger Build
* Use URL helper and not change the policy just yet
* :)
* Add some test coverage and use same feature flag for consistency
* rubocop
* more rubocop
* trigger build
* adding a small sleep to see if specs pass 😩
* remove sleep
* disable Turbo session drive
* WIP
* Revert "WIP"
This reverts commit ce838672069fd703122156a0d82e5e6ad5398e0a.
* Moving spec from dashboard to root
With forem/forem#16913 the underlying test broke because we were
redirecting on the dashboard.
Co-authored-by: Jeremy Friesen <jeremy.n.friesen@gmail.com>
* initial work to show the expand/collapse search and filter on member index
* replace icon with actual button
* simplify logic in pack
* add cypress tests
* make sure both fields part of same form
* add an indicator in mobile view when field has a value
* make sure empty params treated same as missing params
* make sure indicators stay in step with current user input
* partials for inputs
* rename pack file
* Add toggle button to 'New Forem Secret' form
* Display messages using i18n
* Fix from snake case to kebab case
* Fix a bug when the specified class did not exist
This commit provides two things:
1. Some notes related to my analysis regarding the dashboard
2. Conditional redirects and rendering based on article policies
The code comments say most of what I want to say, but to reiterate:
When a user can't create articles nor do they already have published
articles, then we don't want to avoid showing them stats related to
articles.
Closesforem/forem#16913
Related to forem/forem#16908 and forem/forem#16931
* pagination theme for new admin view
* align pagination widget correctly in desktop view
* remove bottom pagination
* re-add pagination to the bottom
* use block styling for the links
* Adjusting article copy to be more general
Our language regarding articles needs minor revisions to speak a bit
more generally about content. This follows on the features of
AuthN/AuthZ work to allow forem admins to configure their forems such
that a subset of their forem members may not have the ability to create
articles.
Closesforem/forem#16890Closesforem/forem#16891
* Update app/views/users/_notifications.html.erb
Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
* Always show the browse section regardless of featured
* Add tests for /pod
* Use safe operator if there are no episodes to show
* Fix test for new podcast page
* Fix test again for podcast page
As I was looking to implement the new Spaces feature (see
forem/forem#16842), I began looking at how to adjust the admin menu. I
found the Menu and AdminMenu. I wanted to add the "spaces" item under
the `:content_manager` scope. Looking at the implementation, I saw I
would need some additional branching logic.
To get an understanding of the implementation, I chose factor towards
classes.
This refactor does a few things:
1) Clarifies a method name (e.g. "children?" becomes
"has_multiple_children?")
2) Adds some tests of the menu implementation.
3) Removes deeply nested hashs in favor of first class objects.
4) Removes a complex method for determining menu visibility, instead
favoring a method that either takes a boolean OR a lambda.
There are further refactors to consider, especially in regards to the
helper methods and some of the coercion of strings into different
formats. But this refactor gets me the part I most am interested in:
Making it easier to specify a menu item as visible or not.
* Penciling in a Default Spaces section
This delivers two primary things:
1. Extracting shared policy examples
2. Providing a functioning skeleton for toggling on the
"limit_post_creation_to_admins" feature.
Important is that once merged, it would be possible for this code to
"leak" out. But how that leaks out is also how you can test that the
feature works.
First, to orient, there is a constraint for a new route. That
constraint checks if the feature flag exists (e.g. has been explicitly
enabled or explicitly disabled). In other words, at this point, you
can't accidentally enable the feature via the UI. But once you have
enabled the feature, you can then toggle the feature on and off.
So, to test this in the browser:
1. Pull down this branch
2. Run `rails runner "FeatureFlag.disable(:limit_post_creation_to_admins)"`
3. Startup your the web server.
4. Login as an administrator
5. Goto /admin/content_manager/spaces
a. Bask in the glory of a plain HTML form
6. With another browser, login as another non-admin user
7. Go to /settings/extensions, you should see a section Publishing from RSS.
8. Now with the admin's session, update the form to turn on
"limit_post_creation_to_admins"
9. Back to the non-admin browser, refresh /settings/extensions, you
should no longer see the section Publishing from RSS.
Note: I have not included an admin menu item as that is related to and
dependent on some refactors I'm working on (see forem/forem#16888 and
forem/forem#16847). So a bit of "security through obsurity"
Note: In the future, once we resolveforem/forem#16490, we'll start
toggling the "Create a Post" button.
Note: I am not including Cypress tests nor request tests for this
feature because the implementation details related to the testing via
that approach are a little too volitale.
Related to forem/forem#16842
* Updating copy based on forem/forem#16893
* styles
* styles
* dark styles
Co-authored-by: Paweł Ludwiczak <ludwiczakpawel@gmail.com>
* complete IG implementation of profile embed, refactors, update specs
* Follow redirects and check them for validity via recursion
* working out redirects
* add IG test links with params
Co-authored-by: Dwight Scott <dwight@forem.com>
* Adding docs and specs to AdminMenu.nested_menu_items
This relates to PR forem/forem#16847 which addresses issue
forem/forem#16842.
The goal of this PR is to help me develop an understanding of the
AdminMenu so I can further extend it and better understand it.
There's also a bit of knowledge sharing that I'm looking for, and the
comments and tests are there to help "confirm" that knowledge. There
might be more that I'd consider regarding a refactor, but I want to make
sure I'm on the right path before I go further.
tl;dr - this is the smallest commit I can make to begin to tease out an
understanding of the method I put under test.
* Update app/models/admin_menu.rb
Co-authored-by: Ridhwana <Ridhwana.Khan16@gmail.com>
* Adding more documentation
* Update app/models/admin_menu.rb
Co-authored-by: Julianna Tetreault <32834804+juliannatetreault@users.noreply.github.com>
Co-authored-by: Ridhwana <Ridhwana.Khan16@gmail.com>
Co-authored-by: Julianna Tetreault <32834804+juliannatetreault@users.noreply.github.com>
* feat: add the feature flag route and controller
* feat: add a ff page
* feat: update to a post with a success banner
* feat: test the feature
* feat: update the styling
* feat: change feature flag to extension witha few more improvements like adding a model not backed by a table
* feat: update the text
* refactor: if you enable a FF, it gets added under the hood as well
* feat: accessibility name for label
* use keyword args
* use locales
* Update app/views/admin/extensions/index.html.erb
Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
* Update app/views/admin/extensions/index.html.erb
Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
* Update app/views/admin/extensions/index.html.erb
Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
* Update config/locales/controllers/admin/fr.yml
Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
* Update app/controllers/admin/extensions_controller.rb
Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
* fix: rubucop
Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
* Refactors _banish.html.erb by removing duplicate code
* Refactors _banish.html.erb to account for new and old users
* Moves conditional into Admin::UsersController#set_user_to_be_banished
* Reverts last commit, as it didnt work as expected
* Fixes last commit, which reverted to the incorrect code
* Pulls banishable user into instance var and fixes button txt
* Removes admin_member_view feature flags and refactors conditionals
* Removes unused admin/users/_email_tools partial and user_email_tools_spec
* Actually remove the admin/user_email_tools_spec this time
* Removes the edit route from admin.rb users
* Adds a DUS (and spec) to disable and remove admin_member_view flag
* Fixes admin/users_spec.rb failures by updating spec with Member Detail changes
* Fixes spec failures within admin_bans_or_warns_user_spec.rb
* Refactors Admin::UsersController#credit_params due to failing specs
* Removes last traces of edit_admin_user_path and fixes buttons, specs, etc.
* Authorize Web Monetization If User Can Create Article
There are three things I'm introducing in this PR:
1. Extracting a partial
2. Reworking the i18n keys
3. Adding a policy check regarding Web Monetization
In *extracting a partial*, I'm following the existing pattern where
other extensions have their own partial.
In *reworking the i18n keys*, I'm ensuring that the keys are part of the
same namespace. This will make finding their usage easier. Further, if
we decide to remove (or convert to a plugin) the web_monetization, then
we're just a bit closer to that possibility.
Last, and the reason for the work, is *Adding a policy check regarding
Web Monetization*. This follows on the work in forem/forem#16790.
Closes forem/forem#16820
Related to forem/forem#15098
There are two things to test:
1. Does the feature flag work or not.
2. Are the i18n keys properly applied.
For the feature flag:
- checkout this branch
- in rails console `FeatureFlag.enable(:limit_post_creation_to_admins)`
- start the rails server
- login as a non-admin user
- go to /settings/extensions and scroll to the bottom, you **shouldn't** see
the partial
- login as an admin user
- go to /settings/extensions and scroll to the bottom, you **should** see
the partial
Or visually verify the relatively simple change (and accept that it
conforms to #16790's existing pattern).
For the i18n keys, I have a before screenshot (from DEV.to) and the
after (from the changes on this branch).
* Adjustments based on contributor feedback
* Apply overflow-wrap fallback everywhere we use anywhere value
* fix some more non breaking spaces layout issues
* user with org sidebar
* comment index header
With this commit, we're only allowing users who can create articles to
enter RSS feed information for fetching of articles.
Note: I chose not to indent body of the if conditional to ease the code
review. I also chose to place the if statement in this partial instead
of in the [app/views/users/_extensions.html.erb][1] file; this helps
contain the logic around the policy.
For sleuthing this mirrors the approach of forem/forem#16735Closesforem/forem#16788
Related to forem/forem#16766, forem/forem#16732, and forem/forem#16763
[1]:b87fd77992/app/views/users/_extensions.html.erb (L3)
* Fix broken documentation link
When sending an invitation, and smtp isn't configured, we show a link
to the old smtp-settings page, which has been renamed
email-server-settings in the admin documentation site.
* Remove explicit link target, assert link text is present
This spec failed when I changed the link target to match the
documentation. Rather than moving the target, I'm just asserting we
show a link to the docs (not where the docs are located).
Note, I'm not overly keen on writing permission tests for this
component. Why? Robust permissioning tests can create combinatorial
explosions. And there are presently no Rspec request specs for this.
So to add an automated test, we'd need to add a set of seed data that
seeds data that conforms to the emerging business logic of the policy.
And while this is easy with use case 1-1, it gets harder as we move
into more nuanced use cases. Instead we should rely on bombarding our
policy classes with lots of tests to let them demonstrate what we mean
when we say `if p.olicy(Article).create?`
Note, there is a potential relation to forem/forem#14807, namely if we
add a rich text editor to our comments, we may need to explore the
purpose and intention of this setting.
Closesforem/forem#16516
* Use correct table heading for username
* WIP add role filter and crayonsify forms
* styling
* responsive
* Add form back in that was removed by merge conflict fix
* Suggest only valid search options
* Add basic tests for search and filter by role
* Add aria for search field
Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
* Add email to aria
Co-authored-by: Julianna Tetreault <32834804+juliannatetreault@users.noreply.github.com>
Co-authored-by: Paweł Ludwiczak <ludwiczakpawel@gmail.com>
Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
Co-authored-by: Julianna Tetreault <32834804+juliannatetreault@users.noreply.github.com>
This commit compresses the policy check that spanned both :new? and
:enabled?. We hide the ability to upload a video (as per the altered
html.erb files of this commit) but we didn't enforce the same logic in
the controller.
Further, as Videos are a subset of Article, I'm adding the "verify the
user is not suspended" test.
Directly relates to #16483
For sleuthing this relates:
- #16728
- forem/forem#16537
- #16634
And for historical context, this relates to:
- #10955
- #10954
- forem/internalEngineering#149