Skip to content

Commit

Permalink
Merge branch 'master' into make-ui-responsive
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewPoppe committed Nov 26, 2023
2 parents f175474 + 26ed975 commit aa7c93b
Show file tree
Hide file tree
Showing 78 changed files with 22,427 additions and 19,866 deletions.
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,17 @@ link to set their password.

![forgot-username](images/screenshots/forgot-username.png)

* If it is enabled in the project, they will also be required to provide a multifactor token after successfully logging in with their username and password
* If multifactor authentication is enabled in the project, they will also be required to provide a security token after successfully logging in with their username and password. This token can either be sent to their email address or generated by an authenticator app like Google Authenticator or Microsoft Authenticator.

*If authenticator apps are enabled for MFA, users will have a choice of MFA method*
![mfa-choice](images/screenshots/mfa-choice.png)

*If email is chosen as the MFA method, users will receive an email with a security code*
![mfa-email](images/screenshots/mfa-email.png)

*If an authenticator app is chosen for the MFA method, users will be prompted to enter a code from their authenticator app*
![mfa-authenticator-app](images/screenshots/mfa-authenticator-app.png)

![mfa](images/screenshots/mfa.png)


## Installation
Expand All @@ -112,6 +120,8 @@ These are settings/configuration options accessible in the normal External Modul
| **Login Attempts** | Integer | Number of consecutive failed login attempts before being locked out | 3 attempts |
| **Lockout Duration** | Integer | Length of a lockout due to failed login attempts, in seconds | 300 seconds |
| **Multi-Factor Authentication** | Checkbox | Require participants to use multi-factor authentication when logging in. This requires participants to enter a code sent to their email address in addition to their password. | Unchecked |
| **Multi-Factor Authentication with Authenticator App** | Checkbox | Allow participants to use an authenticator app (like Google Authenticator or Microsoft Authenticator) to generate a security code for multi-factor authentication. If unchecked, participants will only be able to receive a security code via email. | Unchecked |
| **Restrict Multi-Factor Authentication project settings to REDCap administrators** | Checkbox | If checked, only REDCap administrators will be able to access the multi-factor authentication settings in the project. If unchecked, any REDCapPRO manager will be able to access the multi-factor authentication settings. | Unchecked |
| **Allow Self-Registration** | Checkbox | Allow participants to [register themselves](#self-registration) with **REDCapPRO**. If checked, a link will appear on the login page that will take the participant to a registration page. | Unchecked |
| **Restrict Self-Registration project settings to REDCap administrators** | Checkbox | If checked, only REDCap administrators will be able to access the self-registration settings in the project. If unchecked, any REDCapPRO manager will be able to access the self-registration settings. | Unchecked |
| **Allow Auto-Enroll Upon Self-Registration** | Checkbox | Allow participants to enroll themselves in a project when they register. If checked, the participant will be automatically enrolled in the REDCapPRO project when they self-register | Unchecked |
Expand Down Expand Up @@ -234,6 +244,7 @@ accessible by managers.
| **Language** | Dropdown | The language that participant-facing text in the module will appear in. This overrides the default system setting. See the [Translation](#translation) section for more information. | English |
| **Prevent Email Login** | Checkbox | If checked, this prevents participants from using their email address to log in to surveys. Instead, they must use their REDCapPRO username to log in. <br>*If email logins are prevented at the system level, this setting will not appear in the project setttings tab.* | Unchecked |
| **Multifactor Authentication** | Checkbox | Require participants to use multi-factor authentication when logging in. This requires participants to enter a code sent to their email address in addition to their password. | Unchecked |
| **Allow MFA Authenticator App** | Checkbox | Allow participants to use an authenticator app (like Google Authenticator or Microsoft Authenticator) to generate a security code for multi-factor authentication. If unchecked, participants will only be able to receive a security code via email. | Unchecked |
| **API** | Checkbox | Enable the API for this project. This allows you to register and enroll participants using the [API](#api). | Unchecked |
| **Allow Self-Registration** | Checkbox | Allow participants to [register themselves](#self-registration) with **REDCapPRO**. If checked, a link will appear on the login page that will take the participant to a registration page. | Unchecked |
| **Auto-Enroll Upon Self-Registration** | Checkbox | Participants will be automatically enrolled in this project when they self-register. | Unchecked |
Expand Down Expand Up @@ -352,6 +363,8 @@ information about **REDCapPRO** participants. These are described below:

| Version | Release Date | Description |
| ------- | ------------ | ------------------------------------------------------------------------------------------------------------- |
| 2.2.1 | 2023-11-20 | Minor Change and Bug fix - [Release Notes](https://github.com/AndrewPoppe/REDCap-PRO/releases/tag/2.2.1) |
| 2.2.0 | 2023-11-19 | Feature release - [Release Notes](https://github.com/AndrewPoppe/REDCap-PRO/releases/tag/2.2.0) |
| 2.1.3 | 2023-11-10 | Minor Change to UI Text - [Release Notes](https://github.com/AndrewPoppe/REDCap-PRO/releases/tag/2.1.3) |
| 2.1.2 | 2023-10-30 | Major Bug fix - [Release Notes](https://github.com/AndrewPoppe/REDCap-PRO/releases/tag/2.1.2) |
| 2.1.1 | 2023-10-27 | Minor Bug fix - [Release Notes](https://github.com/AndrewPoppe/REDCap-PRO/releases/tag/2.1.1) |
Expand Down
74 changes: 58 additions & 16 deletions REDCapPRO.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,18 @@ class REDCapPRO extends AbstractExternalModule
public $PROJECT;
public $DAG;
static $COLORS = [
"primary" => "#900000",
"secondary" => "#17a2b8",
"primaryHighlight" => "#c91616",
"primaryDark" => "#7a0000",
"primaryLight" => "#ffadad",
"lightGrey" => "#f9f9f9",
"mediumGrey" => "#dddddd",
"darkGrey" => "#6c757d",
"blue" => "#000090",
"green" => "#009000",
"ban" => "tomato"
"primary" => "#900000",
"secondary" => "#17a2b8",
"primaryHighlight" => "#c91616",
"primaryDark" => "#7a0000",
"primaryLight" => "#ffadad",
"primaryExtraLight" => "#fff0f0",
"lightGrey" => "#f9f9f9",
"mediumGrey" => "#dddddd",
"darkGrey" => "#6c757d",
"blue" => "#000090",
"green" => "#009000",
"ban" => "tomato"
];

static $logColumnsCC = [
Expand Down Expand Up @@ -213,9 +214,6 @@ public function redcap_survey_page_top(

// Check MFA Token
if ( $settings->mfaEnabled((int) $project_id) && !$auth->is_mfa_verified() ) {
$code = $auth->get_mfa_code();
$participantEmail = $participantHelper->getEmail($auth->get_participant_id());
$this->sendMfaTokenEmail($participantEmail, $code);
header("location: " . $this->framework->getUrl("src/mfa.php", true));
return;
}
Expand Down Expand Up @@ -795,6 +793,50 @@ public function sendMfaTokenEmail(string $email, int $token)
}
}

/**
* Send an email with a link for the participant to get Authenticator App information / QR code
*
* @param mixed $rcpro_participant_id
*
* @return mixed
*/
public function sendAuthenticatorAppInfoEmail($rcpro_participant_id)
{
try {

$settings = new ProjectSettings($this);
$participantHelper = new ParticipantHelper($this);

// generate token
$token = $participantHelper->createAuthenticatorAppInfoToken($rcpro_participant_id);
$to = $participantHelper->getEmail($rcpro_participant_id);

// create email
$subject = $this->tt("email_authenticator_app_mfa_info_subject");
$from = $settings->getEmailFromAddress();
$body = "<html><body><div>
<img src='" . $this->LOGO_ALTERNATE_URL . "' alt='img' width='500px'><br>
<p>" . $this->tt("email_authenticator_app_mfa_info_greeting") . "
<br>" . $this->tt("email_authenticator_app_mfa_info_message1") . "<br>
<br>" . $this->tt("email_authenticator_app_mfa_info_message2") . "
<br>
<br>" . $this->tt("email_authenticator_app_mfa_info_message5") . "<a href='" . $this->getUrl("src/authenticator-app-info.php", true) . "&t=${token}'>" . $this->tt("email_authenticator_app_mfa_info_link_text") . "</a>
</p><br>";
$body .= "<p>" . $this->tt("email_authenticator_app_mfa_info_message4");
if ( $this->framework->getProjectId() ) {
$study_contact = $this->getContactPerson($subject);
if ( isset($study_contact["info"]) ) {
$body .= "<br>" . $study_contact["info"];
}
}
$body .= "</p></div></body></html>";

return \REDCap::email($to, $from, $subject, $body);
} catch ( \Exception $e ) {
$this->logError("Error sending Authenticator App information email", $e);
}
}


public function sendAutoEnrollNotificationEmail(string $email, $project_id)
{
Expand Down Expand Up @@ -971,7 +1013,7 @@ public function safeGetUsername() : string
*/
public function logError(string $message, \Throwable $e)
{
if (empty($message)) {
if ( empty($message) ) {
$message = 'Error';
}
$params = [
Expand All @@ -984,7 +1026,7 @@ public function logError(string $message, \Throwable $e)
"module_token" => $this->getModuleToken()
];
if ( isset($e->rcpro) ) {
$params = array_merge($params, ['rcpro' => $e->rcpro]);
$params = array_merge($params, [ 'rcpro' => $e->rcpro ]);
}
$this->logEvent($message, $params);
}
Expand Down
32 changes: 29 additions & 3 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,27 @@
"validation": "integer"
},
{
"key": "mfa",
"name": "<strong>Multi-Factor Authentication</strong>:<br>Should participants be required to use multi-factor authentication (MFA) when logging in? If so, they will be required to enter a code sent to their email address after entering their username and password. This is an additional security measure to prevent unauthorized access.<br><em>Note: this setting enables the MFA option globally, but it still must be enabled in the project settings to take effect</em>",
"key": "mfa-descriptive",
"name": "<div class='p-2' style='background-image: linear-gradient(rgb(197, 248, 255), rgb(197, 248, 255)); border: 1px solid rgba(37, 168, 133, 0.4); border-radius: 0.375rem;'><strong>Multi-Factor Authentication Settings</strong><p>These settings control the use of multi-factor authentication (MFA). Please take care to understand how MFA may be used before enabling it in the system.</p></div>",
"type": "descriptive"
},
{
"key": "mfa-system",
"name": "<div class='p-2' style='background-image: linear-gradient(rgb(197, 248, 255), rgb(197, 248, 255)); border: 1px solid rgba(37, 168, 133, 0.4); border-radius: 0.375rem;'><strong>Multi-Factor Authentication</strong>:</div><br>Should participants be required to use multi-factor authentication (MFA) when logging in? If so, they will be required to enter a code after entering their username and password. This is an additional security measure to prevent unauthorized access.<br><em>Note: this setting enables the MFA option globally, but it still must be enabled in the project settings to take effect</em>",
"type": "checkbox"
},
{
"key": "mfa-authenticator-app-system",
"name": "<div class='p-2' style='background-image: linear-gradient(rgb(197, 248, 255), rgb(197, 248, 255)); border: 1px solid rgba(37, 168, 133, 0.4); border-radius: 0.375rem;'><strong>Multi-Factor Authentication with Authenticator App</strong>:</div><br>Should participants be allowed to use an authenticator app (such as Google Authenticator or Microsoft Authenticator) to generate their MFA code? If not, they will be required to use the code sent to their email address.<br><em>Note: this setting only applies if MFA is enabled globally, but it still must be enabled in the project settings to take effect</em>",
"type": "checkbox",
"branchingLogic": {
"field": "mfa-system",
"value": "1"
}
},
{
"key": "mfa-require-admin",
"name": "<div class='p-2' style='background-image: linear-gradient(rgb(197, 248, 255), rgb(197, 248, 255)); border: 1px solid rgba(37, 168, 133, 0.4); border-radius: 0.375rem;'><strong>Restrict MFA project settings to REDCap administrators</strong>:</div><br>Should only REDCap administrators be able to enable/disable MFA options in project settings? If not, any REDCapPRO manager in the project will be able to enable/disable MFA options in project settings.<br><em>Note: this setting only applies if MFA is enabled globally</em>",
"type": "checkbox"
},
{
Expand Down Expand Up @@ -135,7 +154,9 @@
"src/forgot-username",
"src/session_check",
"src/create-account",
"src/api"
"src/api",
"src/generate_qr_code",
"src/authenticator-app-info"
],
"no-csrf-pages": [
"src/api"
Expand All @@ -152,6 +173,11 @@
"importCsvRegister",
"searchParticipantByEmail"
],
"no-auth-ajax-actions": [
"sendMfaTokenEmail",
"showMFAInfo",
"sendMFAInfo"
],
"action-tags": [
{
"tag": "@RCPRO-USERNAME",
Expand Down
Empty file added docs/mfa.md
Empty file.
Binary file added images/ga.webp
Binary file not shown.
Binary file added images/ma.webp
Binary file not shown.
Binary file added images/screenshots/mfa-authenticator-app.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/screenshots/mfa-choice.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/screenshots/mfa-email.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed images/screenshots/mfa.png
Binary file not shown.
Binary file modified images/screenshots/settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit aa7c93b

Please sign in to comment.