mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Clean up code and switch to mfaEnabled/Disabled
This commit is contained in:
@@ -7,8 +7,8 @@ return [
|
||||
'recovery',
|
||||
'invitation',
|
||||
'mfaChallenge',
|
||||
'mfaCreated',
|
||||
'mfaRemoved',
|
||||
'mfaEnabled',
|
||||
'mfaDisabled',
|
||||
],
|
||||
'sms' => [
|
||||
'verification',
|
||||
|
||||
@@ -31,20 +31,20 @@
|
||||
"emails.mfaChallenge.clientInfo": "This verification code was requested using {{b}}{{agentClient}}{{/b}} on {{b}}{{agentDevice}}{{/b}} {{b}}{{agentOs}}{{/b}}. If you didn't request the verification code, you can safely ignore this email.",
|
||||
"emails.mfaChallenge.thanks": "Thanks,",
|
||||
"emails.mfaChallenge.signature": "{{project}} team",
|
||||
"emails.mfaCreated.subject": "Two-factor authentication is enabled in your {{project}} account",
|
||||
"emails.mfaCreated.hello": "Hello {{user}}",
|
||||
"emails.mfaCreated.body": "Two-factor authentication has been successfully enabled for your {{project}} account.<br/><br/>Please make sure to store your security codes safely, so you can use them if you lose or can’t access your mobile device. Each recovery code can only be used once, but you can re-generate a new set of 6 codes at any time.",
|
||||
"emails.mfaCreated.footer": "If you didn’t enable two-factor authentication, please contact us immediately.",
|
||||
"emails.mfaCreated.thanks": "Thanks,",
|
||||
"emails.mfaCreated.signature": "{{project}} team",
|
||||
"emails.mfaCreated.buttonText": "Visit your account",
|
||||
"emails.mfaRemoved.subject": "Two-factor authentication is disabled in your {{project}} account",
|
||||
"emails.mfaRemoved.hello": "Hello {{user}}",
|
||||
"emails.mfaRemoved.body": "You've recently disabled two-factor authentication for your {{project}} account. You can always enable it again through your {{project}} account.",
|
||||
"emails.mfaRemoved.footer": "If you didn’t disable two-factor authentication, please contact us immediately.",
|
||||
"emails.mfaRemoved.thanks": "Thanks,",
|
||||
"emails.mfaRemoved.signature": "{{project}} team",
|
||||
"emails.mfaRemoved.buttonText": "Visit your account",
|
||||
"emails.mfaEnabled.subject": "Two-factor authentication is enabled in your {{project}} account",
|
||||
"emails.mfaEnabled.hello": "Hello {{user}}",
|
||||
"emails.mfaEnabled.body": "Two-factor authentication has been successfully enabled for your {{project}} account.<br/><br/>Please make sure to store your security codes safely, so you can use them if you lose or can’t access your mobile device. Each recovery code can only be used once, but you can re-generate a new set of 6 codes at any time.",
|
||||
"emails.mfaEnabled.footer": "If you didn’t enable two-factor authentication, please contact us immediately.",
|
||||
"emails.mfaEnabled.thanks": "Thanks",
|
||||
"emails.mfaEnabled.signature": "{{project}} team",
|
||||
"emails.mfaEnabled.buttonText": "Visit your account",
|
||||
"emails.mfaDisabled.subject": "Two-factor authentication is disabled in your {{project}} account",
|
||||
"emails.mfaDisabled.hello": "Hello {{user}}",
|
||||
"emails.mfaDisabled.body": "You've disabled two-factor authentication for your {{project}} account. You can always enable it again through your {{project}} account.",
|
||||
"emails.mfaDisabled.footer": "If you didn’t disable two-factor authentication, please contact us immediately.",
|
||||
"emails.mfaDisabled.thanks": "Thanks",
|
||||
"emails.mfaDisabled.signature": "{{project}} team",
|
||||
"emails.mfaDisabled.buttonText": "Visit your account",
|
||||
"emails.recovery.subject": "Password Reset",
|
||||
"emails.recovery.hello": "Hello {{user}}",
|
||||
"emails.recovery.body": "Follow this link to reset your {{b}}{{project}}{{/b}} password.",
|
||||
|
||||
+111
-197
@@ -166,6 +166,101 @@ $createSession = function (string $userId, string $secret, Request $request, Res
|
||||
$response->dynamic($session, Response::MODEL_SESSION);
|
||||
};
|
||||
|
||||
$sendMFAAlert = function (Document $project, Document $user, Locale $locale, Mail $queueForMails, string $type, string $redirect) {
|
||||
$subject = $locale->getText("emails.{$type}.subject");
|
||||
$customTemplate = $project->getAttribute('templates', [])["email.{$type}-" . $locale->default] ?? [];
|
||||
|
||||
// Appwrite Theming for Console
|
||||
if ($project->getInternalId() === 'console') {
|
||||
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-base-styled.tpl');
|
||||
$body = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-mfa-altered.tpl');
|
||||
|
||||
$body
|
||||
->setParam('{{buttonText}}', $locale->getText("emails.{$type}.buttonText"))
|
||||
->setParam('{{redirect}}', 'http://' . App::getEnv('_APP_DOMAIN') . '/console/account')
|
||||
->setParam('{{body}}', $locale->getText("emails.{$type}.body"), escapeHtml: false)
|
||||
->setParam('{{project}}', $project->getAttribute('name'))
|
||||
->setParam('{{user}}', $user->getAttribute('name'));
|
||||
|
||||
$message->setParam('{{body}}', $body->render(), escapeHtml: false);
|
||||
} else {
|
||||
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
|
||||
|
||||
$message->setParam('{{body}}', $locale->getText("emails.{$type}.body"), escapeHtml: false);
|
||||
}
|
||||
|
||||
$message
|
||||
->setParam('{{hello}}', $locale->getText("emails.{$type}.hello"))
|
||||
->setParam('{{footer}}', $locale->getText("emails.{$type}.footer"))
|
||||
->setParam('{{thanks}}', $locale->getText("emails.{$type}.thanks"))
|
||||
->setParam('{{signature}}', $locale->getText("emails.{$type}.signature"));
|
||||
|
||||
$body = $message->render();
|
||||
|
||||
$smtp = $project->getAttribute('smtp', []);
|
||||
$smtpEnabled = $smtp['enabled'] ?? false;
|
||||
|
||||
$senderEmail = System::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM);
|
||||
$senderName = System::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server');
|
||||
$replyTo = "";
|
||||
|
||||
if ($smtpEnabled) {
|
||||
if (!empty($smtp['senderEmail'])) {
|
||||
$senderEmail = $smtp['senderEmail'];
|
||||
}
|
||||
if (!empty($smtp['senderName'])) {
|
||||
$senderName = $smtp['senderName'];
|
||||
}
|
||||
if (!empty($smtp['replyTo'])) {
|
||||
$replyTo = $smtp['replyTo'];
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSmtpHost($smtp['host'] ?? '')
|
||||
->setSmtpPort($smtp['port'] ?? '')
|
||||
->setSmtpUsername($smtp['username'] ?? '')
|
||||
->setSmtpPassword($smtp['password'] ?? '')
|
||||
->setSmtpSecure($smtp['secure'] ?? '');
|
||||
|
||||
if (!empty($customTemplate)) {
|
||||
if (!empty($customTemplate['senderEmail'])) {
|
||||
$senderEmail = $customTemplate['senderEmail'];
|
||||
}
|
||||
if (!empty($customTemplate['senderName'])) {
|
||||
$senderName = $customTemplate['senderName'];
|
||||
}
|
||||
if (!empty($customTemplate['replyTo'])) {
|
||||
$replyTo = $customTemplate['replyTo'];
|
||||
}
|
||||
|
||||
$body = $customTemplate['message'] ?? '';
|
||||
$subject = $customTemplate['subject'] ?? $subject;
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSmtpReplyTo($replyTo)
|
||||
->setSmtpSenderEmail($senderEmail)
|
||||
->setSmtpSenderName($senderName);
|
||||
}
|
||||
|
||||
$emailVariables = [
|
||||
'owner' => $user->getAttribute('name'),
|
||||
'direction' => $locale->getText('settings.direction'),
|
||||
'user' => $user->getAttribute('name'),
|
||||
'project' => $project->getAttribute('name'),
|
||||
'redirect' => $redirect
|
||||
];
|
||||
|
||||
$queueForMails
|
||||
->setSubject($subject)
|
||||
->setBody($body)
|
||||
->setRecipient($user->getAttribute('email'))
|
||||
->setName($user->getAttribute('name'))
|
||||
->setVariables($emailVariables)
|
||||
->trigger()
|
||||
;
|
||||
};
|
||||
|
||||
App::post('/v1/account')
|
||||
->desc('Create account')
|
||||
->groups(['api', 'account', 'auth'])
|
||||
@@ -3505,12 +3600,25 @@ App::patch('/v1/account/mfa')
|
||||
->label('sdk.offline.key', 'current')
|
||||
->param('mfa', null, new Boolean(), 'Enable or disable MFA.')
|
||||
->inject('requestTimestamp')
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('project')
|
||||
->inject('session')
|
||||
->inject('locale')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->action(function (bool $mfa, ?\DateTime $requestTimestamp, Response $response, Document $user, Document $session, Database $dbForProject, Event $queueForEvents) {
|
||||
->inject('queueForMails')
|
||||
->action(function (bool $mfa, ?\DateTime $requestTimestamp, Request $request, Response $response, Document $user, Document $project, Document $session, Locale $locale, Database $dbForProject, Event $queueForEvents, Mail $queueForMails) use ($sendMFAAlert) {
|
||||
// If MFA Changes then we need to send a email
|
||||
if ($mfa !== $user->getAttribute('mfa')) {
|
||||
$domain = $request->getHostname();
|
||||
$protocol = $request->getProtocol();
|
||||
|
||||
$redirect = $protocol . '://' . $domain . '/console/account';
|
||||
|
||||
$sendMFAAlert($project, $user, $locale, $queueForMails, $mfa ? 'mfaEnabled' : 'mfaDisabled', $redirect);
|
||||
}
|
||||
|
||||
$user->setAttribute('mfa', $mfa);
|
||||
|
||||
@@ -3667,11 +3775,7 @@ App::put('/v1/account/mfa/authenticators/:type')
|
||||
->inject('session')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('project')
|
||||
->inject('locale')
|
||||
->inject('queueForMails')
|
||||
->action(function (string $type, string $otp, Response $response, Document $user, Document $session, Database $dbForProject, Event $queueForEvents, Document $project, Locale $locale, Mail $queueForMails) {
|
||||
|
||||
->action(function (string $type, string $otp, Response $response, Document $user, Document $session, Database $dbForProject, Event $queueForEvents) {
|
||||
$authenticator = (match ($type) {
|
||||
Type::TOTP => TOTP::getAuthenticatorFromUser($user),
|
||||
default => null
|
||||
@@ -3706,99 +3810,6 @@ App::put('/v1/account/mfa/authenticators/:type')
|
||||
$session->setAttribute('factors', $factors);
|
||||
$dbForProject->updateDocument('sessions', $session->getId(), $session);
|
||||
|
||||
// Send email to user informing that MFA is enabled
|
||||
$subject = $locale->getText("emails.mfaCreated.subject");
|
||||
$customTemplate = $project->getAttribute('templates', [])['email.mfaCreated-' . $locale->default] ?? [];
|
||||
|
||||
// Appwrite theming for console
|
||||
if ($project->getInternalId() === 'console') {
|
||||
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-base-styled.tpl');
|
||||
$body = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-mfa-altered.tpl');
|
||||
|
||||
$body
|
||||
->setParam('{{buttonText}}', $locale->getText("emails.mfaCreated.buttonText"))
|
||||
->setParam('{{redirect}}', 'http://' . App::getEnv('_APP_DOMAIN') . '/console/account')
|
||||
->setParam('{{body}}', $locale->getText("emails.mfaCreated.body"), escapeHtml: false)
|
||||
->setParam('{{project}}', $project->getAttribute('name'))
|
||||
->setParam('{{user}}', $user->getAttribute('name'));
|
||||
|
||||
$message->setParam('{{body}}', $body->render(), escapeHtml: false);
|
||||
} else {
|
||||
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
|
||||
|
||||
$message->setParam('{{body}}', $locale->getText("emails.mfaCreated.body"), escapeHtml: false);
|
||||
}
|
||||
|
||||
$message
|
||||
->setParam('{{hello}}', $locale->getText("emails.mfaCreated.hello"))
|
||||
->setParam('{{footer}}', $locale->getText("emails.mfaCreated.footer"))
|
||||
->setParam('{{thanks}}', $locale->getText("emails.mfaCreated.thanks"))
|
||||
->setParam('{{signature}}', $locale->getText("emails.mfaCreated.signature"));
|
||||
|
||||
$body = $message->render();
|
||||
|
||||
$smtp = $project->getAttribute('smtp', []);
|
||||
$smtpEnabled = $smtp['enabled'] ?? false;
|
||||
|
||||
$senderEmail = System::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM);
|
||||
$senderName = System::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server');
|
||||
$replyTo = "";
|
||||
|
||||
if ($smtpEnabled) {
|
||||
if (!empty($smtp['senderEmail'])) {
|
||||
$senderEmail = $smtp['senderEmail'];
|
||||
}
|
||||
if (!empty($smtp['senderName'])) {
|
||||
$senderName = $smtp['senderName'];
|
||||
}
|
||||
if (!empty($smtp['replyTo'])) {
|
||||
$replyTo = $smtp['replyTo'];
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSmtpHost($smtp['host'] ?? '')
|
||||
->setSmtpPort($smtp['port'] ?? '')
|
||||
->setSmtpUsername($smtp['username'] ?? '')
|
||||
->setSmtpPassword($smtp['password'] ?? '')
|
||||
->setSmtpSecure($smtp['secure'] ?? '');
|
||||
|
||||
if (!empty($customTemplate)) {
|
||||
if (!empty($customTemplate['senderEmail'])) {
|
||||
$senderEmail = $customTemplate['senderEmail'];
|
||||
}
|
||||
if (!empty($customTemplate['senderName'])) {
|
||||
$senderName = $customTemplate['senderName'];
|
||||
}
|
||||
if (!empty($customTemplate['replyTo'])) {
|
||||
$replyTo = $customTemplate['replyTo'];
|
||||
}
|
||||
|
||||
$body = $customTemplate['message'] ?? '';
|
||||
$subject = $customTemplate['subject'] ?? $subject;
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSmtpReplyTo($replyTo)
|
||||
->setSmtpSenderEmail($senderEmail)
|
||||
->setSmtpSenderName($senderName);
|
||||
}
|
||||
|
||||
$emailVariables = [
|
||||
'owner' => $user->getAttribute('name'),
|
||||
'direction' => $locale->getText('settings.direction'),
|
||||
'user' => $user->getAttribute('name'),
|
||||
'project' => $project->getAttribute('name')
|
||||
];
|
||||
|
||||
$queueForMails
|
||||
->setSubject($subject)
|
||||
->setBody($body)
|
||||
->setRecipient($user->getAttribute('email'))
|
||||
->setName($user->getAttribute('name'))
|
||||
->setVariables($emailVariables)
|
||||
->trigger()
|
||||
;
|
||||
|
||||
$queueForEvents->setParam('userId', $user->getId());
|
||||
|
||||
$response->dynamic($user, Response::MODEL_ACCOUNT);
|
||||
@@ -3937,11 +3948,7 @@ App::delete('/v1/account/mfa/authenticators/:type')
|
||||
->inject('user')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('project')
|
||||
->inject('locale')
|
||||
->inject('queueForMails')
|
||||
->action(function (string $type, string $otp, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Document $project, Locale $locale, Mail $queueForMails) {
|
||||
|
||||
->action(function (string $type, string $otp, Response $response, Document $user, Database $dbForProject, Event $queueForEvents) {
|
||||
$authenticator = (match ($type) {
|
||||
Type::TOTP => TOTP::getAuthenticatorFromUser($user),
|
||||
default => null
|
||||
@@ -3975,99 +3982,6 @@ App::delete('/v1/account/mfa/authenticators/:type')
|
||||
$dbForProject->deleteDocument('authenticators', $authenticator->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
// Send email to user informing that MFA is disabled
|
||||
$subject = $locale->getText("emails.mfaRemoved.subject");
|
||||
$customTemplate = $project->getAttribute('templates', [])['email.mfaRemoved-' . $locale->default] ?? [];
|
||||
|
||||
// Appwrite theming for console
|
||||
if ($project->getInternalId() === 'console') {
|
||||
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-base-styled.tpl');
|
||||
$body = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-mfa-altered.tpl');
|
||||
|
||||
$body
|
||||
->setParam('{{buttonText}}', $locale->getText("emails.mfaRemoved.buttonText"))
|
||||
->setParam('{{redirect}}', 'http://' . App::getEnv('_APP_DOMAIN') . '/console/account')
|
||||
->setParam('{{body}}', $locale->getText("emails.mfaRemoved.body"), escapeHtml: false)
|
||||
->setParam('{{project}}', $project->getAttribute('name'))
|
||||
->setParam('{{user}}', $user->getAttribute('name'));
|
||||
|
||||
$message->setParam('{{body}}', $body->render(), escapeHtml: false);
|
||||
} else {
|
||||
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
|
||||
|
||||
$message->setParam('{{body}}', $locale->getText("emails.mfaRemoved.body"), escapeHtml: false);
|
||||
}
|
||||
|
||||
$message
|
||||
->setParam('{{hello}}', $locale->getText("emails.mfaRemoved.hello"))
|
||||
->setParam('{{footer}}', $locale->getText("emails.mfaRemoved.footer"))
|
||||
->setParam('{{thanks}}', $locale->getText("emails.mfaRemoved.thanks"))
|
||||
->setParam('{{signature}}', $locale->getText("emails.mfaRemoved.signature"));
|
||||
|
||||
$body = $message->render();
|
||||
|
||||
$smtp = $project->getAttribute('smtp', []);
|
||||
$smtpEnabled = $smtp['enabled'] ?? false;
|
||||
|
||||
$senderEmail = System::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM);
|
||||
$senderName = System::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server');
|
||||
$replyTo = "";
|
||||
|
||||
if ($smtpEnabled) {
|
||||
if (!empty($smtp['senderEmail'])) {
|
||||
$senderEmail = $smtp['senderEmail'];
|
||||
}
|
||||
if (!empty($smtp['senderName'])) {
|
||||
$senderName = $smtp['senderName'];
|
||||
}
|
||||
if (!empty($smtp['replyTo'])) {
|
||||
$replyTo = $smtp['replyTo'];
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSmtpHost($smtp['host'] ?? '')
|
||||
->setSmtpPort($smtp['port'] ?? '')
|
||||
->setSmtpUsername($smtp['username'] ?? '')
|
||||
->setSmtpPassword($smtp['password'] ?? '')
|
||||
->setSmtpSecure($smtp['secure'] ?? '');
|
||||
|
||||
if (!empty($customTemplate)) {
|
||||
if (!empty($customTemplate['senderEmail'])) {
|
||||
$senderEmail = $customTemplate['senderEmail'];
|
||||
}
|
||||
if (!empty($customTemplate['senderName'])) {
|
||||
$senderName = $customTemplate['senderName'];
|
||||
}
|
||||
if (!empty($customTemplate['replyTo'])) {
|
||||
$replyTo = $customTemplate['replyTo'];
|
||||
}
|
||||
|
||||
$body = $customTemplate['message'] ?? '';
|
||||
$subject = $customTemplate['subject'] ?? $subject;
|
||||
}
|
||||
|
||||
$queueForMails
|
||||
->setSmtpReplyTo($replyTo)
|
||||
->setSmtpSenderEmail($senderEmail)
|
||||
->setSmtpSenderName($senderName);
|
||||
}
|
||||
|
||||
$emailVariables = [
|
||||
'owner' => $user->getAttribute('name'),
|
||||
'direction' => $locale->getText('settings.direction'),
|
||||
'user' => $user->getAttribute('name'),
|
||||
'project' => $project->getAttribute('name')
|
||||
];
|
||||
|
||||
$queueForMails
|
||||
->setSubject($subject)
|
||||
->setBody($body)
|
||||
->setRecipient($user->getAttribute('email'))
|
||||
->setName($user->getAttribute('name'))
|
||||
->setVariables($emailVariables)
|
||||
->trigger()
|
||||
;
|
||||
|
||||
$queueForEvents->setParam('userId', $user->getId());
|
||||
|
||||
$response->noContent();
|
||||
|
||||
Reference in New Issue
Block a user