1
0
Fork 0
mirror of synced 2024-06-14 08:44:49 +12:00

Resolve merge conflicts

This commit is contained in:
Khushboo Verma 2024-02-02 12:53:25 +05:30
commit 0ea7b28a6b
8 changed files with 31 additions and 30 deletions

1
.env
View file

@ -99,4 +99,5 @@ _APP_ASSISTANT_OPENAI_API_KEY=
_APP_MESSAGE_SMS_TEST_DSN=
_APP_MESSAGE_EMAIL_TEST_DSN=
_APP_MESSAGE_PUSH_TEST_DSN=
_APP_WEBHOOK_MAX_FAILED_ATTEMPTS=10
_APP_COUNTRIES_DENYLIST=AQ

View file

@ -8,7 +8,7 @@ use Appwrite\Auth\Validator\Phone;
use Appwrite\Detector\Detector;
use Appwrite\Event\Event;
use Appwrite\Event\Mail;
use Appwrite\Auth\SecurityPhrase;
use Appwrite\Auth\Phrase;
use Appwrite\Extend\Exception;
use Appwrite\Network\Validator\Email;
use Utopia\Validator\Host;
@ -990,7 +990,7 @@ App::post('/v1/account/tokens/magic-url')
->param('userId', '', new CustomId(), 'User ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
->param('email', '', new Email(), 'User email.')
->param('url', '', fn($clients) => new Host($clients), 'URL to redirect the user back to your app from the magic URL login. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['clients'])
->param('securityPhrase', false, new Boolean(), 'Toggle for security phrase. If enabled, email will be send with a randomly generated phrase and the phrase will also be included in the response. Confirming phrases match increases the security of authentication flow.', true)
->param('phrase', false, new Boolean(), 'Toggle for security phrase. If enabled, email will be send with a randomly generated phrase and the phrase will also be included in the response. Confirming phrases match increases the security of your authentication flow.', true)
->inject('request')
->inject('response')
->inject('user')
@ -999,14 +999,14 @@ App::post('/v1/account/tokens/magic-url')
->inject('locale')
->inject('queueForEvents')
->inject('queueForMails')
->action(function (string $userId, string $email, string $url, bool $securityPhrase, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails) {
->action(function (string $userId, string $email, string $url, bool $phrase, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails) {
if (empty(App::getEnv('_APP_SMTP_HOST'))) {
throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP disabled');
}
if ($securityPhrase === true) {
$securityPhrase = SecurityPhrase::generate();
if ($phrase === true) {
$phrase = Phrase::generate();
}
$roles = Authorization::getRoles();
@ -1116,7 +1116,7 @@ App::post('/v1/account/tokens/magic-url')
->setParam('{{thanks}}', $locale->getText("emails.magicSession.thanks"))
->setParam('{{signature}}', $locale->getText("emails.magicSession.signature"));
if (!empty($securityPhrase)) {
if (!empty($phrase)) {
$message->setParam('{{securityPhrase}}', $locale->getText("emails.magicSession.securityPhrase"));
} else {
$message->setParam('{{securityPhrase}}', '');
@ -1180,7 +1180,7 @@ App::post('/v1/account/tokens/magic-url')
'agentDevice' => '<strong>' . ( $agentDevice['deviceBrand'] ?? $agentDevice['deviceBrand'] ?? 'UNKNOWN') . '</strong>',
'agentClient' => '<strong>' . ($agentClient['clientName'] ?? 'UNKNOWN') . '</strong>',
'agentOs' => '<strong>' . ($agentOs['osName'] ?? 'UNKNOWN') . '</strong>',
'phrase' => '<strong>' . (!empty($securityPhrase) ? $securityPhrase : '') . '</strong>'
'phrase' => '<strong>' . (!empty($phrase) ? $phrase : '') . '</strong>'
];
$queueForMails
@ -1200,8 +1200,8 @@ App::post('/v1/account/tokens/magic-url')
// Hide secret for clients
$token->setAttribute('secret', ($isPrivilegedUser || $isAppUser) ? $tokenSecret : '');
if (!empty($securityPhrase)) {
$token->setAttribute('securityPhrase', $securityPhrase);
if (!empty($phrase)) {
$token->setAttribute('phrase', $phrase);
}
$response
@ -1229,7 +1229,7 @@ App::post('/v1/account/tokens/email')
->label('abuse-key', 'url:{url},email:{param-email}')
->param('userId', '', new CustomId(), 'User ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
->param('email', '', new Email(), 'User email.')
->param('securityPhrase', false, new Boolean(), 'Toggle for security phrase. If enabled, email will be send with a randomly generated phrase and the phrase will also be included in the response. Confirming phrases match increases the security of authentication flow.', true)
->param('phrase', false, new Boolean(), 'Toggle for security phrase. If enabled, email will be send with a randomly generated phrase and the phrase will also be included in the response. Confirming phrases match increases the security of your authentication flow.', true)
->inject('request')
->inject('response')
->inject('user')
@ -1238,13 +1238,13 @@ App::post('/v1/account/tokens/email')
->inject('locale')
->inject('queueForEvents')
->inject('queueForMails')
->action(function (string $userId, string $email, bool $securityPhrase, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails) {
->action(function (string $userId, string $email, bool $phrase, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails) {
if (empty(App::getEnv('_APP_SMTP_HOST'))) {
throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP disabled');
}
if ($securityPhrase === true) {
$securityPhrase = SecurityPhrase::generate();
if ($phrase === true) {
$phrase = Phrase::generate();
}
$roles = Authorization::getRoles();
@ -1344,7 +1344,7 @@ App::post('/v1/account/tokens/email')
->setParam('{{thanks}}', $locale->getText("emails.otpSession.thanks"))
->setParam('{{signature}}', $locale->getText("emails.otpSession.signature"));
if (!empty($securityPhrase)) {
if (!empty($phrase)) {
$message->setParam('{{securityPhrase}}', $locale->getText("emails.otpSession.securityPhrase"));
} else {
$message->setParam('{{securityPhrase}}', '');
@ -1408,7 +1408,7 @@ App::post('/v1/account/tokens/email')
'agentDevice' => '<strong>' . ( $agentDevice['deviceBrand'] ?? $agentDevice['deviceBrand'] ?? 'UNKNOWN') . '</strong>',
'agentClient' => '<strong>' . ($agentClient['clientName'] ?? 'UNKNOWN') . '</strong>',
'agentOs' => '<strong>' . ($agentOs['osName'] ?? 'UNKNOWN') . '</strong>',
'phrase' => '<strong>' . (!empty($securityPhrase) ? $securityPhrase : '') . '</strong>'
'phrase' => '<strong>' . (!empty($phrase) ? $phrase : '') . '</strong>'
];
$queueForMails
@ -1428,8 +1428,8 @@ App::post('/v1/account/tokens/email')
// Hide secret for clients
$token->setAttribute('secret', ($isPrivilegedUser || $isAppUser) ? $tokenSecret : '');
if (!empty($securityPhrase)) {
$token->setAttribute('securityPhrase', $securityPhrase);
if (!empty($phrase)) {
$token->setAttribute('phrase', $phrase);
}
$response

View file

@ -298,6 +298,7 @@ services:
- _APP_REDIS_PASS
- _APP_LOGGING_PROVIDER
- _APP_LOGGING_CONFIG
- _APP_WEBHOOK_MAX_FAILED_ATTEMPTS
appwrite-worker-deletes:
entrypoint: worker-deletes

View file

@ -2,7 +2,7 @@
namespace Appwrite\Auth;
class SecurityPhrase
class Phrase
{
public static function generate(): string
{

View file

@ -16,7 +16,6 @@ use Utopia\Queue\Message;
class Webhooks extends Action
{
private array $errors = [];
private const MAX_FAILED_ATTEMPTS = 10;
private const MAX_FILE_SIZE = 5242880; // 5 MB
public static function getName(): string
@ -157,7 +156,7 @@ class Webhooks extends Action
$webhook->setAttribute('logs', $logs);
if ($attempts >= self::MAX_FAILED_ATTEMPTS) {
if ($attempts >= \intval(App::getEnv('_APP_WEBHOOK_MAX_FAILED_ATTEMPTS', '10'))) {
$webhook->setAttribute('enabled', false);
$this->sendEmailAlert($attempts, $statusCode, $webhook, $project, $dbForConsole, $queueForMails);
}

View file

@ -40,7 +40,7 @@ class Token extends Model
'default' => '',
'example' => self::TYPE_DATETIME_EXAMPLE,
])
->addRule('securityPhrase', [
->addRule('phrase', [
'type' => self::TYPE_STRING,
'description' => 'Security phrase of a token. Empty if security phrase was not requested when creating a token. It includes randomly generated phrase which is also sent in the external resource such as email.',
'default' => '',

View file

@ -163,7 +163,7 @@ trait AccountBase
$this->assertNotEmpty($response['body']['userId']);
$this->assertNotEmpty($response['body']['expire']);
$this->assertEmpty($response['body']['secret']);
$this->assertEmpty($response['body']['securityPhrase']);
$this->assertEmpty($response['body']['phrase']);
$userId = $response['body']['userId'];
@ -223,21 +223,21 @@ trait AccountBase
]), [
'userId' => ID::unique(),
'email' => 'otpuser@appwrite.io',
'securityPhrase' => true
'phrase' => true
]);
$this->assertEquals($response['headers']['status-code'], 201);
$this->assertNotEmpty($response['body']['securityPhrase']);
$this->assertNotEmpty($response['body']['phrase']);
$this->assertEmpty($response['body']['secret']);
$this->assertEquals($userId, $response['body']['userId']);
$securityPhrase = $response['body']['securityPhrase'];
$phrase = $response['body']['phrase'];
$lastEmail = $this->getLastEmail();
$this->assertEquals('otpuser@appwrite.io', $lastEmail['to'][0]['address']);
$this->assertEquals('OTP for ' . $this->getProject()['name'] . ' Login', $lastEmail['subject']);
$this->assertStringContainsStringIgnoringCase('security phrase', $lastEmail['text']);
$this->assertStringContainsStringIgnoringCase($securityPhrase, $lastEmail['text']);
$this->assertStringContainsStringIgnoringCase($phrase, $lastEmail['text']);
$response = $this->client->call(Client::METHOD_POST, '/account/tokens/email', array_merge([
'origin' => 'http://localhost',

View file

@ -2331,7 +2331,7 @@ class AccountCustomClientTest extends Scope
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEmpty($response['body']['secret']);
$this->assertEmpty($response['body']['securityPhrase']);
$this->assertEmpty($response['body']['phrase']);
$this->assertEquals(true, (new DatetimeValidator())->isValid($response['body']['expire']));
$userId = $response['body']['userId'];
@ -2399,15 +2399,15 @@ class AccountCustomClientTest extends Scope
]), [
'userId' => ID::unique(),
'email' => $email,
'securityPhrase' => true
'phrase' => true
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertNotEmpty($response['body']['securityPhrase']);
$this->assertNotEmpty($response['body']['phrase']);
$lastEmail = $this->getLastEmail();
$this->assertStringContainsStringIgnoringCase($response['body']['securityPhrase'], $lastEmail['text']);
$this->assertStringContainsStringIgnoringCase($response['body']['phrase'], $lastEmail['text']);
$data['token'] = $token;
$data['id'] = $userId;