diff --git a/app/config/locale/templates/email-inner-base.tpl b/app/config/locale/templates/email-inner-base.tpl index 52e1093ff..aa3457412 100644 --- a/app/config/locale/templates/email-inner-base.tpl +++ b/app/config/locale/templates/email-inner-base.tpl @@ -1,4 +1,4 @@ -

{{hello}},

+

{{hello}}

{{body}}

{{redirect}}

{{footer}}

diff --git a/app/config/locale/translations/en.json b/app/config/locale/translations/en.json index 438cdbde5..22a132964 100644 --- a/app/config/locale/translations/en.json +++ b/app/config/locale/translations/en.json @@ -5,24 +5,24 @@ "emails.sender": "%s Team", "emails.verification.subject": "Account Verification", "emails.verification.hello": "Hello {{user}}", - "emails.verification.body": "Follow this link to verify your email address.", + "emails.verification.body": "Follow this link to verify your email address to your {{b}}{{project}}{{/b}} account.", "emails.verification.footer": "If you didn’t ask to verify this address, you can ignore this message.", "emails.verification.thanks": "Thanks", "emails.verification.signature": "{{project}} team", "emails.magicSession.subject": "{{project}} Login", "emails.magicSession.hello": "Hello {{user}}", - "emails.magicSession.optionButton": "Click the button below to securely sign in to your {{project}} account. This link will expire in 1 hour.", + "emails.magicSession.optionButton": "Click the button below to securely sign in to your {{b}}{{project}}{{/b}} account. This link will expire in 1 hour.", "emails.magicSession.buttonText": "Sign in to {{project}}", "emails.magicSession.optionUrl": "If you are unable to sign in using the button above, please visit the following link:", - "emails.magicSession.clientInfo": "This sign in was requested using {{agentClient}} on {{agentDevice}} {{agentOs}}. If you didn't request the sign in, you can safely ignore this email.", - "emails.magicSession.securityPhrase": "Security phrase for this email is {{phrase}}. You can trust this email if this phrase matches the phrase shown during sign in.", + "emails.magicSession.clientInfo": "This sign in was requested using {{b}}{{agentClient}}{{/b}} on {{b}}{{agentDevice}}{{/b}} {{b}}{{agentOs}}{{/b}}. If you didn't request the sign in, you can safely ignore this email.", + "emails.magicSession.securityPhrase": "Security phrase for this email is {{b}}{{phrase}}{{/b}}. You can trust this email if this phrase matches the phrase shown during sign in.", "emails.magicSession.thanks": "Thanks,", "emails.magicSession.signature": "{{project}} team", "emails.otpSession.subject": "OTP for {{project}} Login", "emails.otpSession.hello": "Hello {{user}}", - "emails.otpSession.description": "Enter the following verification code when prompted to securely sign in to your {{project}} account. This code will expire in 15 minutes.", - "emails.otpSession.clientInfo": "This sign in was requested using {{agentClient}} on {{agentDevice}} {{agentOs}}. If you didn't request the sign in, you can safely ignore this email.", - "emails.otpSession.securityPhrase": "Security phrase for this email is {{phrase}}. You can trust this email if this phrase matches the phrase shown during sign in.", + "emails.otpSession.description": "Enter the following verification code when prompted to securely sign in to your {{b}}{{project}}{{/b}} account. This code will expire in 15 minutes.", + "emails.otpSession.clientInfo": "This sign in was requested using {{b}}{{agentClient}}{{/b}} on {{b}}{{agentDevice}}{{/b}} {{b}}{{agentOs}}{{/b}}. If you didn't request the sign in, you can safely ignore this email.", + "emails.otpSession.securityPhrase": "Security phrase for this email is {{b}}{{phrase}}{{/b}}. You can trust this email if this phrase matches the phrase shown during sign in.", "emails.otpSession.thanks": "Thanks,", "emails.otpSession.signature": "{{project}} team", "emails.mfaChallenge.subject": "Verification Code for {{project}}", @@ -33,13 +33,13 @@ "emails.mfaChallenge.signature": "{{project}} team", "emails.recovery.subject": "Password Reset", "emails.recovery.hello": "Hello {{user}}", - "emails.recovery.body": "Follow this link to reset your {{project}} password.", + "emails.recovery.body": "Follow this link to reset your {{b}}{{project}}{{/b}} password.", "emails.recovery.footer": "If you didn’t ask to reset your password, you can ignore this message.", "emails.recovery.thanks": "Thanks", "emails.recovery.signature": "{{project}} team", "emails.invitation.subject": "Invitation to %s Team at %s", "emails.invitation.hello": "Hello {{user}}", - "emails.invitation.body": "This mail was sent to you because {{owner}} wanted to invite you to become a member of the {{team}} team at {{project}}.", + "emails.invitation.body": "This mail was sent to you because {{b}}{{owner}}{{/b}} wanted to invite you to become a member of the {{b}}{{team}}{{/b}} team at {{b}}{{project}}{{/b}}.", "emails.invitation.footer": "If you are not interested, you can ignore this message.", "emails.invitation.thanks": "Thanks", "emails.invitation.signature": "{{project}} team", diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index d054af7f2..a68a882e4 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -1259,15 +1259,14 @@ App::post('/v1/account/tokens/magic-url') $emailVariables = [ 'direction' => $locale->getText('settings.direction'), - /* {{user}}, {{team}}, {{redirect}} and {{project}} are required in default and custom templates */ - 'user' => '', - 'team' => '', + /* {{user}}, {{redirect}} and {{project}} are required in default and custom templates */ + 'user' => $user->getAttribute('name'), 'project' => $project->getAttribute('name'), 'redirect' => $url, - 'agentDevice' => '' . ( $agentDevice['deviceBrand'] ?? $agentDevice['deviceBrand'] ?? 'UNKNOWN') . '', - 'agentClient' => '' . ($agentClient['clientName'] ?? 'UNKNOWN') . '', - 'agentOs' => '' . ($agentOs['osName'] ?? 'UNKNOWN') . '', - 'phrase' => '' . (!empty($phrase) ? $phrase : '') . '' + 'agentDevice' => $agentDevice['deviceBrand'] ?? $agentDevice['deviceBrand'] ?? 'UNKNOWN', + 'agentClient' => $agentClient['clientName'] ?? 'UNKNOWN', + 'agentOs' => $agentOs['osName'] ?? 'UNKNOWN', + 'phrase' => !empty($phrase) ? $phrase : '' ]; $queueForMails @@ -1487,15 +1486,14 @@ App::post('/v1/account/tokens/email') $emailVariables = [ 'direction' => $locale->getText('settings.direction'), - /* {{user}} ,{{team}}, {{project}} and {{otp}} are required in the templates */ - 'user' => '', - 'team' => '', + /* {{user}}, {{project}} and {{otp}} are required in the templates */ + 'user' => $user->getAttribute('name'), 'project' => $project->getAttribute('name'), 'otp' => $tokenSecret, - 'agentDevice' => '' . ( $agentDevice['deviceBrand'] ?? $agentDevice['deviceBrand'] ?? 'UNKNOWN') . '', - 'agentClient' => '' . ($agentClient['clientName'] ?? 'UNKNOWN') . '', - 'agentOs' => '' . ($agentOs['osName'] ?? 'UNKNOWN') . '', - 'phrase' => '' . (!empty($phrase) ? $phrase : '') . '' + 'agentDevice' => $agentDevice['deviceBrand'] ?? $agentDevice['deviceBrand'] ?? 'UNKNOWN', + 'agentClient' => $agentClient['clientName'] ?? 'UNKNOWN', + 'agentOs' => $agentOs['osName'] ?? 'UNKNOWN', + 'phrase' => !empty($phrase) ? $phrase : '' ]; $queueForMails @@ -2953,9 +2951,8 @@ App::post('/v1/account/recovery') $emailVariables = [ 'direction' => $locale->getText('settings.direction'), - /* {{user}}, {{team}}, {{redirect}} and {{project}} are required in default and custom templates */ + /* {{user}}, {{redirect}} and {{project}} are required in default and custom templates */ 'user' => $profile->getAttribute('name'), - 'team' => '', 'redirect' => $url, 'project' => $projectName ]; @@ -3200,9 +3197,8 @@ App::post('/v1/account/verification') $emailVariables = [ 'direction' => $locale->getText('settings.direction'), - /* {{user}}, {{team}}, {{redirect}} and {{project}} are required in default and custom templates */ + /* {{user}}, {{redirect}} and {{project}} are required in default and custom templates */ 'user' => $user->getAttribute('name'), - 'team' => '', 'redirect' => $url, 'project' => $projectName ]; @@ -3745,6 +3741,22 @@ App::post('/v1/account/mfa/challenge') throw new Exception(Exception::USER_PHONE_NOT_VERIFIED); } + $message = Template::fromFile(__DIR__ . '/../../config/locale/templates/sms-base.tpl'); + + $customTemplate = $project->getAttribute('templates', [])['sms.mfa-challenge-' . $locale->default] ?? []; + if (!empty($customTemplate)) { + $message = $customTemplate['message'] ?? $message; + } + + $messageContent = Template::fromString($locale->getText("sms.verification.body")); + $messageContent + ->setParam('{{project}}', $project->getAttribute('name')) + ->setParam('{{secret}}', $code); + $messageContent = \strip_tags($messageContent->render()); + $message = $message->setParam('{{token}}', $messageContent); + + $message = $message->render(); + $queueForMessaging ->setType(MESSAGE_SEND_TYPE_INTERNAL) ->setMessage(new Document([ @@ -3753,7 +3765,8 @@ App::post('/v1/account/mfa/challenge') 'content' => $code, ], ])) - ->setRecipients([$user->getAttribute('phone')]); + ->setRecipients([$user->getAttribute('phone')]) + ->setProviderType(MESSAGE_TYPE_SMS); break; case 'email': if (empty(App::getEnv('_APP_SMTP_HOST'))) { diff --git a/phpunit.xml b/phpunit.xml index 90ebd4225..e77286605 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -6,7 +6,7 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="false" + stopOnFailure="true" >