Skip to content

WeBWorK 2.21 Release Candidate#2940

Open
drgrice1 wants to merge 485 commits into
mainfrom
WeBWorK-2.21
Open

WeBWorK 2.21 Release Candidate#2940
drgrice1 wants to merge 485 commits into
mainfrom
WeBWorK-2.21

Conversation

@drgrice1

Copy link
Copy Markdown
Member

This is the release candidate for WeBWorK 2.21. Please re-target any pull requests that you want to get into the release for this branch.

drgrice1 and others added 30 commits February 17, 2026 15:40
This implements the specification detailed at
https://www.imsglobal.org/spec/lti-dr/v1p0.

To use this the LMS administrator enters the URL
`https://your.webwork2.server.edu/webwork2/ltiadvantage/registration`.
That automatically adds the LTI 1.3 configuration for the webwork2
server to the LMS.  Then the LMS administrator just needs to activate
the tool.

On the webwork2 side of things the LTI 1.3 configuration for the LMS
will be saved into a file in the directory `webwork/DATA/LTIRegistrationRequests`.
The file will be named `$lmsName-XXXX.conf` where `$lmsName` is whatever
the tool reported in the `product_family_code` subkey of the
`https://purl.imsglobal.org/spec/lti-platform-configuration` key in the
configuration webwork2 obtains from the LMS and `XXXX` is whatever
`tempfile` fills in to ensure the file is unique.  Note that the
`product_family_code` is "moodle", "canvas", etc. Unfortunately, there
isn't really a unique identifier that can be used here in the
information sent from the LMS, so not much better can be done for the
file name.

The webwork2 system administrator then needs to copy and paste the
contents of that file into either the `conf/authen_LTI_1_3.conf` file
for site wide setup, or into all of the appropriate `course.conf` files
for course specific setup. Note that depending on the LMS the data in
the file may not be complete. The specification essentially states that
it is optional for the LMS to sent this value.  Moodle sends the
`deployment_id` in the returned configuration, but Canvas does not.  Of
course I don't know what D2L or Blackboard will do.  In this case the
generated will contain `'obtain from LMS administrator`' for the
`$LTI{v1p3}{DeploymentID}`.  So for Canvas, at least, the webwork2
administrator will still need to communicate with the LMS administrator
to obtain the `deployment_id`.  Eventually, a user interface in the
admin course could perhaps be implemented for dealing with these
configurations in a nicer way than cutting a pasting from this file that
is created.  However, that most likely will require a change in how the
LTI configurations are saved. The config file approach is a limiting
factor in this.

Also, there may be additional configuration that the LMS administrator
needs (or may want) to do, and how the tool is presented in the LMS when
editing it may be different than how it was previously with the manual
configuration approach.

For Moodle the tool that is automatically created needs to be activated
(a click of a button does this), but furthermore, the administrator will
probably want to edit the configuration and set the "Tool configuration
usage" to "Show in activity chooser and as preconfigured tool" (it is
set to "Show as preconfigured tool when adding an external tool" by
default), and set "Default launch container" to "New Window" (it is set
to "Embed, without blocks" by default). Also, the way the tool is
presented when editing it is indistinguishable from a tool created using
the manual configuration approach.  This means that all aspects of the
tool can be edited as before.

For Canvas even before the tool is created in the LMS there are some
options that can be configured although usually they should be left with
the defaults.  The only things that can be changed are if certain things
in the configuration from webwork2 are enabled or not.  For example,
placements in the configuration from webwork2 can not be added, but can
only be disabled.  Also, the way the tool is presented when editing it
is quite different from a manually configured tool. None of the URLs can
be edited, and the things that were in the configuration from webwork
can only be disabled again.

Of course, it remains to be seen what D2L or Blackboard do with this.

Note that there is a little more that can be added to this.  Before the
tool is added to the LMS, webwork2 could present a page that allows the
LMS administrator to select options for the tool.  For example, the
current tool name will be "WeBWorK at your.webwork2.server.edu", but
that could be allowed to be changed by the LMS administrator.  Note that
for Moodle that can be changed later anyway, but Canvas does not provide
a way to change the tool name.  Also, it may be desirable to allow the
administrator to determine if grade passback is allowed or not.
Although, for both Moodle and Canvas this can still be done in any case.

Note that LTI 1.1 does support something like this, but I haven't found
any documentation on it (although I haven't looked to hard).
First, this makes it so that feedback is shown on initial render.  This
occurs both on initial page load (for the initially selected user), and
also occurs when a different user is selected from the dropdown.

Second, this fixes some issues with tests and answers.  The test answer
prefix needs to be preserved in the form so that checking answers works.
Also, the `ProblemGrader.html.ep` template was constructing the quiz
prefix from the problem number and should be using the `problem_id`
(which is what the GatewayQuiz.pm module uses).  That means the last
answers were not working at all for tests with random problem order.
Make the problem graders also save the sub_status when needed.
…ime-factor

Fix an issue with adding and updating users when the accomodation_time_factor is not set.
…isplay

Fix three issues with display of answers on the problem grader page.
Implement LTI 1.3 dynamic registration with the LMS.
Improvements for the problem renderer on the problem grader page.
Allow viewing ProblemSet page for any valid set.
The issue with link styles has been fixed, and the workaround in the
`js/MathJaxConfig/bs-color-scheme.js` file removed.

The other issue with the `--mjx-bg-alpha` versus `--mjx-bg1-alpha`
variable has not been fixed.  This should probably be brought to the
attention of @dpvc.
… used.

This is a case that was missed in #2855.  At this point on the develop
branch when the "Show Correct Answers" button is used, the form fields
are not submitted to PG, and so the answer disappears. This is perhaps a
minor issue as this is not the answer saved in the database, but just
the answer entered at the time the "Show Correct Answers" button is used
which won't be saved to the database anyway.  However, it is a change in
behavior. So this pull request just restores that prior behavior.

Note that if there is an answer saved in the database, then that will
replace what is submitted when the "Show Correct Answers" button is used
anyway.  That is how it was before, and that is the same with this.
…nswers

Preserve the entered answer when the "Show Correct Answers" button is used.
…ing sets from the "Sets Manager".

This restriction was removed when editing the set detail page several
releases ago (if I recall correctly).  However, the restriction was not
removed on this page.  So this make this page consistent and this should
have been done at that time.
This is the result of running `npm audit fix`.
Remove the restriction that a close date be within 10 years when editing sets from the "Sets Manager".
Add the completed time next to the time taken on completed test versions.
Move the set description from a tooltip on the link to the set to
a tooltip on an info button located just right of the set link if
the set description is not empty.

This adds an additional option to the `set-id-tooltip` class
JavaScript that if `data-fallback-placements` is set as a spaced
separated list list, that list will be passed to the bootstrap
Tooltip on creation.
The student statistics and student progress page are identical.
Remove the student statistics version of the page, since the page
doesn't provide any summary of the data, and only shows a student's
number of attempts and grade.
The only shared code is a new template which just links to
all sets. The problem links or student links are put in each
pages siblings template.
ProblemSets: Place set description in info button.
Add completed time to test output.
Remove the copyright/license from README.md.

Clarify that the artistic license is version 1.0 and provide links
to the copy on github and the perlfoundation.

Remove the old FSF physical address and provide links to the
GPL license on github and a direct link to the gpl version 2
on gnu.org (since the old link resolved to version 3).
Since we are now on MathJax 4.1.1 and the version specified in the
`bs-color-scheme.js` file is 4.1.0, a console warning points out the
version mismatch.

We will need to remember to change this every time we upgrade MathJax.
Of course the extension will also need to be updated for changes to
MathJax.
Node 18 is deprecated, and our dependencies now require node 20 or
newer.
This is the result of executing the
`bin/dev_scripts/update-localization-files` script.
Alex-Jordan and others added 30 commits July 9, 2026 21:13
typos identified by github.com/crate-ci/typos
…manager.

This just adds the `courseLinks` in the course environment to the list
of directories (and now links) that are checked when an instructor
attempts to delete a directory in the file manager.

This is to address issue #2568.
Caliper::Entity::problem_user() called $problem_user->prHintsAfter() to
populate the 'showHintsAfter' event field, but the UserProblem record has
no prHintsAfter accessor -- the field is showHintsAfter (used correctly
for the global problem in problem()). Generating a Caliper event for a
problem attempt would die with "Can't locate object method prHintsAfter".
Call showHintsAfter() instead.
typos identified by github.com/crate-ci/typos
Fix Caliper::Entity calling nonexistent prHintsAfter() method
…t-silent

Abort a course archive when the database dump actually fails
Protect the required course symbolic links from deletion in the file manager.
…thJax content has rendered.

In addition to setting the `.problem-content` div not visible, this
injects an overlay div that is position absolutely over the
`.problem-content` div with the same size.  It also gets that
`.problem-content` class so that it appears like an empty problem.  It
also pulsatess slowly using essentially bootstrap's `placeholder-glow`
animation (although implemented with a JavaScript animation instead of
css). In addition a height transition is set on the div so that it grows
a bit slower than just the immediate jump in size.

Perhaps this will allay the appearance of the content below jumping down
in some cases since now there is something shown instead of just an
empty space.

This is an alternate approach to #3003 that maybe some will like better?
This is to address openwebwork/pg#1018 (comment).

The two settings that affect backups for `perltidy` are `-b` (or
`--backup-and-modify-in-place`) and `-bext` (or `--backup-file-extension`).

The `-b` option is boolean and if given it means that a backup of the
original Perl file will be created with the extension specified by the
`-bext` option, and the original Perl file will be modified in place.
This is currently set by default in the `.perltidyrc` file that we use.
If this option is not given, then the original Perl file is never
modified, and the result of running `perltidy` is saved in a new file
with the extension `.tdy`.

The `-bext` option sets the file extension that is used when the `-b`
option is set, and determines if the backup file should be kept.  The
default value is `bak` which means the extension `.bak` is used and the
backup will be kept.  If this is set to a value that does not include a
forward slash, then its value will be used for the extension and the
backup will be kept.  If the value is set to something that has a
forward slash in it, then the backup will be created with that
extension, but will be deleted if there are no errors. This is currently
set by default in the `bin/dev_scripts/run-perltidy.pl` script.

This changes the `-bext` value set by the `bin/dev_scripts/run-perltidy.pl`
to `/tidybak`.  That means that a backup file will be created with the
extension `.tidybak`, but will be deleted if there are no errors.

This will fix @Alex-Jordan's issue because it will not touch any file
with the `.bak` extension. Note that anyone that creates backups with
the `.tidybak` extension will end up having the same problem, but the
extension is chosen because no one really should be using that, and it
should not conflict.
Problems selected from a problem group have the pseudo source file
"group:problemGroupName" (see
WeBWorK::Utils::Instructor::assignProblemToUserSetVersion), which is not
a real file under the course templates directory.  Caliper::Entity::problem
unconditionally passed that path to WeBWorK::Utils::Tags->new, which dies
when it cannot open the file, so any Caliper event embedding the problem
entity (e.g. answer submission in a gateway quiz that uses problem groups)
crashed server side.

Skip tag parsing for "group:" pseudo source files instead.  For those
problems the entity now reports keywords => [] and tags => undef.  Real
problem files are unaffected: their keywords and unblessed tags are built
exactly as before.
The paragraph asking users to report errors to the site's webmaster
read "as well as what what you were doing when the error occurred".
Remove the duplicated "what".
The User Settings page shows a 'Use Equation Editor?' option when
$pg{specialPGEnvironmentVars}{entryAssist} is set to 'MathView', but
the useMathView parameter it submits was never read when saving, so the
selected value was silently discarded and the setting reverted to the
course default on every reload.

Include useMathView in the change detection and save it together with
the other display settings, matching how displayMode, showOldAnswers,
and useMathQuill are handled.
The alertToast helper in the library browser interpolated its title and
msg arguments directly into an innerHTML template, letting DOM text be
reinterpreted as HTML (CodeQL js/xss-through-dom). Build the toast with
document.createElement instead and assign the title and message with
textContent, so caller-supplied strings are always treated as text. This
matches the toast construction already used in htdocs/js/TagWidget.
The comment above the $database_* variables still says they "are used by
database.conf", but conf/database.conf no longer ships. Replace it with a
simple statement of what the variables are for: "These variables define
the database connection."
…at-typo

Fix duplicated word in default exception template
Save the useMathView user setting on the User Settings page
…f-comment

Fix stale comment in site.conf.dist referencing removed database.conf
Prevent Caliper events from dying on problem-group pseudo source files
Change the extension used by `perltidy`.
Alternate approach to delaying showing problem content until after MathJax content has rendered.
In order to enable the reset password flow, the course environment
variable `$password_reset_sender_email` must be set. This can be set per
course in the `course.conf` files.

If that is set, then a "Forgot Password" link will appear on the course
login page to the right of the "Continue" button. When that link is used
a "Forgot Password" page is shown. The user will then need to enter
their username and click "Request Password Reset". Then an email is sent
to the user (assuming the user has a valid email address in the
database) containing a "Reset Password" link. A single use token is
embedded in the link, and that token expires in 15 minutes. When that
link is used a "Reset Password" page is shown. On that page the user
must enter a new password, and confirm it by entering it again, and then
click "Reset Password".  If the token in the link is valid, then the
user's password is changed.

If two factor authentication is enabled, then when the reset link that
is emailed to the user is used, the user must enter a one-time security
code as well as a new password in order to reset their password. Also,
if the user has not yet set up two factor authentication for their
account, then password reset is not allowed for the user.

All requests to reset a user's password and the success or failure when
using the reset password link are logged to the login log.

This is to address issue #2976.
…m-archive

Determine the unarchive source course ID from the archive contents, not its filename
show file size of archived courses when unarchiving
Wrap the `unarchiveCourse` call in the `do_unarchive_course` method of
the `WeBWorK::ContentGenerator::CourseAdmin` package in an `eval`, so
that exceptions are caught.  The exceptions are already checked for on
the next line, but deal with the exception message better.  Instead of
displaying `$@` which might include a backtrace, show `$@->message` in
the case that `$@` is an object.
Build the library browser alert toast with DOM methods to avoid DOM XSS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants