1
0
Fork 0
mirror of synced 2024-09-19 19:07:21 +12:00

Merge branch 'refs/heads/1.6.x' into refactor-session-alerts

# Conflicts:
#	app/controllers/api/account.php
This commit is contained in:
Binyamin Yawitz 2024-08-05 16:19:41 -04:00
commit 4ca3ef020f
No known key found for this signature in database
21 changed files with 80 additions and 53 deletions

Binary file not shown.

View file

@ -6,7 +6,8 @@ return [
'magicSession',
'recovery',
'invitation',
'mfaChallenge'
'mfaChallenge',
'sessionAlert'
],
'sms' => [
'verification',

View file

@ -11,4 +11,4 @@
<p>{{footer}}</p>
<p style="margin-bottom: 0px;">{{thanks}}</p>
<p style="margin-top: 0px;">{{signature}}</p>
<p style="margin-top: 0px;">{{signature}}</p>

View file

@ -18,13 +18,13 @@
"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.sessionAlert.subject": "New session alert for {{project}}",
"emails.sessionAlert.subject": "Security alert: new session on your {{project}} account",
"emails.sessionAlert.hello":"Hello {{user}}",
"emails.sessionAlert.body": "We're writing to inform you that a new session has been initiated on your {{b}}{{project}}{{/b}} account, on {{b}}{{dateTime}}{{/b}}. \nHere are the details of the new session: ",
"emails.sessionAlert.body": "A new session has been created on your {{b}}{{project}}{{/b}} account, on {{b}}{{dateTime}}{{/b}}.\nHere are the details of the new session: ",
"emails.sessionAlert.listDevice": "Device: {{b}}{{device}}{{/b}}",
"emails.sessionAlert.listIpAddress": "IP Address: {{b}}{{ipAddress}}{{/b}}",
"emails.sessionAlert.listCountry": "Country: {{b}}{{country}}{{/b}}",
"emails.sessionAlert.footer": "If you didn't request the sign in, you can safely ignore this email. If you suspect unauthorized activity, please secure your account immediately.",
"emails.sessionAlert.footer": "If this was you, there's nothing more you need to do.\nIf you didn't initiate this session or suspect any unauthorized activity, please secure your account.",
"emails.sessionAlert.thanks": "Thanks,",
"emails.sessionAlert.signature": "{{project}} team",
"emails.otpSession.subject": "OTP for {{project}} Login",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -124,7 +124,7 @@ function sendSessionAlert(Locale $locale, Document $user, Document $project, Doc
$emailVariables = [
'direction' => $locale->getText('settings.direction'),
'dateTime' => DateTime::format(new \DateTime(), 'Y-m-d H:i:s'),
'dateTime' => DateTime::format(new \DateTime(), 'h:ia MMMM dS'),
'user' => $user->getAttribute('name'),
'project' => $project->getAttribute('name'),
'device' => $session->getAttribute('clientName'),
@ -177,12 +177,6 @@ $createSession = function (string $userId, string $secret, Request $request, Res
default => throw new Exception(Exception::USER_INVALID_TOKEN)
});
$sendAlert = (match ($verifiedToken->getAttribute('type')) {
Auth::TOKEN_TYPE_MAGIC_URL,
Auth::TOKEN_TYPE_EMAIL => false,
default => true
});
$session = new Document(array_merge(
[
'$id' => ID::unique(),
@ -229,8 +223,12 @@ $createSession = function (string $userId, string $secret, Request $request, Res
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed saving user to DB');
}
if (($project->getAttribute('auths', [])['sessionAlerts'] ?? false) && $sendAlert) {
sendSessionAlert($locale, $user, $project, $session, $queueForMails);
if ($project->getAttribute('auths', [])['sessionAlerts'] ?? false) {
if ($dbForProject->count('sessions', [
Query::equal('userId', [$user->getId()]),
]) !== 1) {
sendSessionAlert($locale, $user, $project, $session, $queueForMails);
}
}
$queueForEvents
@ -910,7 +908,11 @@ App::post('/v1/account/sessions/email')
;
if ($project->getAttribute('auths', [])['sessionAlerts'] ?? false) {
sendSessionAlert($locale, $user, $project, $session, $queueForMails);
if ($dbForProject->count('sessions', [
Query::equal('userId', [$user->getId()]),
]) !== 1) {
sendSessionAlert($locale, $user, $project, $session, $queueForMails);
}
}
$response->dynamic($session, Response::MODEL_SESSION);

View file

@ -1459,7 +1459,8 @@ App::post('/v1/functions/:functionId/deployments/:deploymentId/build')
->inject('project')
->inject('queueForEvents')
->inject('queueForBuilds')
->action(function (string $functionId, string $deploymentId, string $buildId, Request $request, Response $response, Database $dbForProject, Document $project, Event $queueForEvents, Build $queueForBuilds) {
->inject('deviceForFunctions')
->action(function (string $functionId, string $deploymentId, string $buildId, Request $request, Response $response, Database $dbForProject, Document $project, Event $queueForEvents, Build $queueForBuilds, Device $deviceForFunctions) {
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
@ -1471,13 +1472,23 @@ App::post('/v1/functions/:functionId/deployments/:deploymentId/build')
throw new Exception(Exception::DEPLOYMENT_NOT_FOUND);
}
$path = $deployment->getAttribute('path');
if(empty($path) || !$deviceForFunctions->exists($path)) {
throw new Exception(Exception::DEPLOYMENT_NOT_FOUND);
}
$deploymentId = ID::unique();
$destination = $deviceForFunctions->getPath($deploymentId . '.' . \pathinfo('code.tar.gz', PATHINFO_EXTENSION));
$deviceForFunctions->transfer($path, $destination, $deviceForFunctions);
$deployment->removeAttribute('$internalId');
$deployment = $dbForProject->createDocument('deployments', $deployment->setAttributes([
'$internalId' => '',
'$id' => $deploymentId,
'buildId' => '',
'buildInternalId' => '',
'path' => $destination,
'entrypoint' => $function->getAttribute('entrypoint'),
'commands' => $function->getAttribute('commands', ''),
'search' => implode(' ', [$deploymentId, $function->getAttribute('entrypoint')]),

View file

@ -999,7 +999,7 @@ $register->set('smtp', function () {
return $mail;
});
$register->set('geodb', function () {
return new Reader(__DIR__ . '/assets/dbip/dbip-country-lite-2024-02.mmdb');
return new Reader(__DIR__ . '/assets/dbip/dbip-country-lite-2024-08.mmdb');
});
$register->set('passwordsDictionary', function () {
$content = \file_get_contents(__DIR__ . '/assets/security/10k-common-passwords');

View file

@ -787,7 +787,7 @@ $image = $this->getParam('image', '');
<<: *x-logging
restart: unless-stopped
stop_signal: SIGINT
image: openruntimes/executor:0.6.2
image: openruntimes/executor:0.6.5
networks:
- appwrite
- runtimes

46
composer.lock generated
View file

@ -1721,16 +1721,16 @@
},
{
"name": "utopia-php/database",
"version": "0.50.0",
"version": "0.50.2",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/database.git",
"reference": "ce3eaccb2f3bbd34b2b97419836fec633b26b8f7"
"reference": "c712d1f6c8ec37886a7a1ad4d60a8cd75dec00aa"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/database/zipball/ce3eaccb2f3bbd34b2b97419836fec633b26b8f7",
"reference": "ce3eaccb2f3bbd34b2b97419836fec633b26b8f7",
"url": "https://api.github.com/repos/utopia-php/database/zipball/c712d1f6c8ec37886a7a1ad4d60a8cd75dec00aa",
"reference": "c712d1f6c8ec37886a7a1ad4d60a8cd75dec00aa",
"shasum": ""
},
"require": {
@ -1771,9 +1771,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/database/issues",
"source": "https://github.com/utopia-php/database/tree/0.50.0"
"source": "https://github.com/utopia-php/database/tree/0.50.2"
},
"time": "2024-06-21T03:21:42+00:00"
"time": "2024-07-31T10:12:19+00:00"
},
{
"name": "utopia-php/domains",
@ -1923,16 +1923,16 @@
},
{
"name": "utopia-php/framework",
"version": "0.33.6",
"version": "0.33.7",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/http.git",
"reference": "8fe57da0cecd57e3b17cd395b4a666a24f4c07a6"
"reference": "78d293d99a262bd63ece750bbf989c7e0643b825"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/http/zipball/8fe57da0cecd57e3b17cd395b4a666a24f4c07a6",
"reference": "8fe57da0cecd57e3b17cd395b4a666a24f4c07a6",
"url": "https://api.github.com/repos/utopia-php/http/zipball/78d293d99a262bd63ece750bbf989c7e0643b825",
"reference": "78d293d99a262bd63ece750bbf989c7e0643b825",
"shasum": ""
},
"require": {
@ -1962,9 +1962,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/http/issues",
"source": "https://github.com/utopia-php/http/tree/0.33.6"
"source": "https://github.com/utopia-php/http/tree/0.33.7"
},
"time": "2024-03-21T18:10:57+00:00"
"time": "2024-08-01T14:01:04+00:00"
},
{
"name": "utopia-php/image",
@ -2990,16 +2990,16 @@
"packages-dev": [
{
"name": "appwrite/sdk-generator",
"version": "0.39.3",
"version": "0.39.4",
"source": {
"type": "git",
"url": "https://github.com/appwrite/sdk-generator.git",
"reference": "16142d88270e368030d7956cadf2d7816413f8c4"
"reference": "501b92d73ae55e0f880ed00f57bc64a54d0ce137"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/16142d88270e368030d7956cadf2d7816413f8c4",
"reference": "16142d88270e368030d7956cadf2d7816413f8c4",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/501b92d73ae55e0f880ed00f57bc64a54d0ce137",
"reference": "501b92d73ae55e0f880ed00f57bc64a54d0ce137",
"shasum": ""
},
"require": {
@ -3035,9 +3035,9 @@
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
"support": {
"issues": "https://github.com/appwrite/sdk-generator/issues",
"source": "https://github.com/appwrite/sdk-generator/tree/0.39.3"
"source": "https://github.com/appwrite/sdk-generator/tree/0.39.4"
},
"time": "2024-07-12T15:29:48+00:00"
"time": "2024-07-26T22:34:10+00:00"
},
{
"name": "doctrine/deprecations",
@ -3158,16 +3158,16 @@
},
{
"name": "laravel/pint",
"version": "v1.16.2",
"version": "v1.17.1",
"source": {
"type": "git",
"url": "https://github.com/laravel/pint.git",
"reference": "51f1ba679a6afe0315621ad143d788bd7ded0eca"
"reference": "b5b6f716db298671c1dfea5b1082ec2c0ae7064f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/pint/zipball/51f1ba679a6afe0315621ad143d788bd7ded0eca",
"reference": "51f1ba679a6afe0315621ad143d788bd7ded0eca",
"url": "https://api.github.com/repos/laravel/pint/zipball/b5b6f716db298671c1dfea5b1082ec2c0ae7064f",
"reference": "b5b6f716db298671c1dfea5b1082ec2c0ae7064f",
"shasum": ""
},
"require": {
@ -3220,7 +3220,7 @@
"issues": "https://github.com/laravel/pint/issues",
"source": "https://github.com/laravel/pint"
},
"time": "2024-07-09T15:58:08+00:00"
"time": "2024-08-01T09:06:33+00:00"
},
{
"name": "matthiasmullie/minify",

View file

@ -873,7 +873,7 @@ services:
hostname: exc1
<<: *x-logging
stop_signal: SIGINT
image: openruntimes/executor:0.6.2
image: openruntimes/executor:0.6.5
restart: unless-stopped
networks:
- appwrite

View file

@ -235,7 +235,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
->setTwitter(APP_SOCIAL_TWITTER_HANDLE)
->setDiscord(APP_SOCIAL_DISCORD_CHANNEL, APP_SOCIAL_DISCORD)
->setDefaultHeaders([
'X-Appwrite-Response-Format' => '1.5.0',
'X-Appwrite-Response-Format' => '1.6.0',
]);
// Make sure we have a clean slate.

View file

@ -333,6 +333,7 @@ class Builds extends Action
$source = $path;
$build = $dbForProject->updateDocument('builds', $build->getId(), $build->setAttribute('source', $source));
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment->setAttribute('path', $source));
$this->runGitAction('processing', $github, $providerCommitHash, $owner, $repositoryName, $project, $function, $deployment->getId(), $dbForProject, $dbForConsole);
}

View file

@ -194,8 +194,7 @@ class Executor
}
$runtimeId = "$projectId-$deploymentId";
$route = '/runtimes/' . $runtimeId . '/execution';
$route = '/runtimes/' . $runtimeId . '/executions';
// Remove after migration
if ($version == 'v3') {
@ -217,6 +216,7 @@ class Executor
'version' => $version,
'runtimeEntrypoint' => $runtimeEntrypoint,
'logging' => $logging,
'restartPolicy' => 'always' // Once utopia/orchestration has it, use DockerAPI::ALWAYS (0.13+)
];
if(!empty($body)) {

View file

@ -1225,7 +1225,7 @@ class AccountCustomClientTest extends Scope
$this->assertEquals(201, $response['headers']['status-code']);
// Create a session for the new account
// Create first session for the new account
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
@ -1238,11 +1238,23 @@ class AccountCustomClientTest extends Scope
$this->assertEquals(201, $response['headers']['status-code']);
// Create second session for the new account
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36',
]), [
'email' => $email,
'password' => $password,
]);
// Check the alert email
$lastEmail = $this->getLastEmail();
$this->assertEquals($email, $lastEmail['to'][0]['address']);
$this->assertStringContainsString('New session alert', $lastEmail['subject']);
$this->assertStringContainsString('Security alert: new session', $lastEmail['subject']);
$this->assertStringContainsString($response['body']['ip'], $lastEmail['text']); // IP Address
$this->assertStringContainsString('Unknown', $lastEmail['text']); // Country
$this->assertStringContainsString($response['body']['clientName'], $lastEmail['text']); // Client name