mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Merge branch 'remove-globals' of github.com:appwrite/appwrite into swoole
This commit is contained in:
+109
-219
@@ -2,8 +2,6 @@
|
||||
|
||||
require_once __DIR__.'/init.php';
|
||||
|
||||
global $request, $response, $register, $project;
|
||||
|
||||
use Utopia\App;
|
||||
use Appwrite\Utopia\Request;
|
||||
use Appwrite\Utopia\Response;
|
||||
@@ -11,154 +9,48 @@ use Utopia\View;
|
||||
use Utopia\Exception;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Domains\Domain;
|
||||
use Utopia\Locale\Locale;
|
||||
use Appwrite\Auth\Auth;
|
||||
use Appwrite\Database\Database;
|
||||
use Appwrite\Database\Document;
|
||||
use Appwrite\Database\Validator\Authorization;
|
||||
use Appwrite\Database\Adapter\MySQL as MySQLAdapter;
|
||||
use Appwrite\Database\Adapter\Redis as RedisAdapter;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Network\Validator\Origin;
|
||||
|
||||
$request = new Request();
|
||||
$response = new Response();
|
||||
|
||||
$locale = $request->getParam('locale', $request->getHeader('X-Appwrite-Locale', ''));
|
||||
|
||||
if (\in_array($locale, Config::getParam('locales'))) {
|
||||
Locale::setDefault($locale);
|
||||
}
|
||||
|
||||
Config::setParam('env', App::getMode());
|
||||
Config::setParam('domain', $request->getServer('HTTP_HOST', ''));
|
||||
Config::setParam('domain', 'localhost');
|
||||
Config::setParam('domainVerification', false);
|
||||
Config::setParam('version', App::getEnv('_APP_VERSION', 'UNKNOWN'));
|
||||
Config::setParam('protocol', $request->getServer('HTTP_X_FORWARDED_PROTO', $request->getServer('REQUEST_SCHEME', 'https')));
|
||||
Config::setParam('port', (string) \parse_url(Config::getParam('protocol').'://'.$request->getServer('HTTP_HOST', ''), PHP_URL_PORT));
|
||||
Config::setParam('hostname', \parse_url(Config::getParam('protocol').'://'.$request->getServer('HTTP_HOST', null), PHP_URL_HOST));
|
||||
Config::setParam('cookieDomain', 'localhost');
|
||||
Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE);
|
||||
|
||||
\define('COOKIE_DOMAIN',
|
||||
(
|
||||
$request->getServer('HTTP_HOST', null) === 'localhost' ||
|
||||
$request->getServer('HTTP_HOST', null) === 'localhost:'.Config::getParam('port') ||
|
||||
(\filter_var(Config::getParam('hostname'), FILTER_VALIDATE_IP) !== false)
|
||||
)
|
||||
? null
|
||||
: '.'.Config::getParam('hostname')
|
||||
);
|
||||
\define('COOKIE_SAMESITE', Response::COOKIE_SAMESITE_NONE);
|
||||
// // Set project mail
|
||||
// $register->get('smtp')
|
||||
// ->setFrom(
|
||||
// App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM),
|
||||
// ($project->getId() === 'console')
|
||||
// ? \urldecode(App::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME.' Server'))
|
||||
// : \sprintf(Locale::getText('account.emails.team'), $project->getAttribute('name')
|
||||
// )
|
||||
// );
|
||||
|
||||
Authorization::disable();
|
||||
App::init(function ($utopia, $request, $response, $console, $project, $user, $locale, $webhooks, $audits, $usage, $clients) {
|
||||
/** @var Utopia\Request $request */
|
||||
/** @var Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $console */
|
||||
/** @var Appwrite\Database\Document $project */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
/** @var Appwrite\Event\Event $webhook */
|
||||
/** @var Appwrite\Event\Event $audit */
|
||||
/** @var Appwrite\Event\Event $usage */
|
||||
/** @var Appwrite\Event\Event $mail */
|
||||
/** @var Appwrite\Event\Event $deletes */
|
||||
/** @var bool $mode */
|
||||
/** @var array $clients */
|
||||
|
||||
$project = $consoleDB->getDocument($request->getParam('project', $request->getHeader('X-Appwrite-Project', '')));
|
||||
$localeParam = (string)$request->getParam('locale', $request->getHeader('X-Appwrite-Locale', ''));
|
||||
|
||||
Authorization::enable();
|
||||
if (\in_array($localeParam, Config::getParam('locale-codes'))) {
|
||||
$locale->setDefault($localeParam);
|
||||
};
|
||||
|
||||
$console = $consoleDB->getDocument('console');
|
||||
|
||||
$mode = $request->getParam('mode', $request->getHeader('X-Appwrite-Mode', 'default'));
|
||||
|
||||
Auth::setCookieName('a_session_'.$project->getId());
|
||||
|
||||
if (APP_MODE_ADMIN === $mode) {
|
||||
Auth::setCookieName('a_session_'.$console->getId());
|
||||
}
|
||||
|
||||
$session = Auth::decodeSession(
|
||||
$request->getCookie(Auth::$cookieName, // Get sessions
|
||||
$request->getCookie(Auth::$cookieName.'_legacy', // Get fallback session from old clients (no SameSite support)
|
||||
$request->getHeader('X-Appwrite-Key', '')))); // Get API Key
|
||||
|
||||
// Get fallback session from clients who block 3rd-party cookies
|
||||
$response->addHeader('X-Debug-Fallback', 'false');
|
||||
|
||||
if(empty($session['id']) && empty($session['secret'])) {
|
||||
$response->addHeader('X-Debug-Fallback', 'true');
|
||||
$fallback = $request->getHeader('X-Fallback-Cookies', '');
|
||||
$fallback = \json_decode($fallback, true);
|
||||
$session = Auth::decodeSession(((isset($fallback[Auth::$cookieName])) ? $fallback[Auth::$cookieName] : ''));
|
||||
}
|
||||
|
||||
Auth::$unique = $session['id'];
|
||||
Auth::$secret = $session['secret'];
|
||||
|
||||
$projectDB = new Database();
|
||||
$projectDB->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register));
|
||||
$projectDB->setNamespace('app_'.$project->getId());
|
||||
$projectDB->setMocks(Config::getParam('collections', []));
|
||||
|
||||
if (APP_MODE_ADMIN !== $mode) {
|
||||
$user = $projectDB->getDocument(Auth::$unique);
|
||||
}
|
||||
else {
|
||||
$user = $consoleDB->getDocument(Auth::$unique);
|
||||
|
||||
$user
|
||||
->setAttribute('$id', 'admin-'.$user->getAttribute('$id'))
|
||||
;
|
||||
}
|
||||
|
||||
if (empty($user->getId()) // Check a document has been found in the DB
|
||||
|| Database::SYSTEM_COLLECTION_USERS !== $user->getCollection() // Validate returned document is really a user document
|
||||
|| !Auth::tokenVerify($user->getAttribute('tokens', []), Auth::TOKEN_TYPE_LOGIN, Auth::$secret)) { // Validate user has valid login token
|
||||
$user = new Document(['$id' => '', '$collection' => Database::SYSTEM_COLLECTION_USERS]);
|
||||
}
|
||||
|
||||
if (APP_MODE_ADMIN === $mode) {
|
||||
if (!empty($user->search('teamId', $project->getAttribute('teamId'), $user->getAttribute('memberships')))) {
|
||||
Authorization::disable();
|
||||
} else {
|
||||
$user = new Document(['$id' => '', '$collection' => Database::SYSTEM_COLLECTION_USERS]);
|
||||
}
|
||||
}
|
||||
|
||||
// Set project mail
|
||||
$register->get('smtp')
|
||||
->setFrom(
|
||||
App::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM),
|
||||
($project->getId() === 'console')
|
||||
? \urldecode(App::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME.' Server'))
|
||||
: \sprintf(Locale::getText('account.emails.team'), $project->getAttribute('name')
|
||||
)
|
||||
);
|
||||
|
||||
/*
|
||||
* Configuration files
|
||||
*/
|
||||
$utopia = new App('Asia/Tel_Aviv');
|
||||
$webhook = new Event('v1-webhooks', 'WebhooksV1');
|
||||
$audit = new Event('v1-audits', 'AuditsV1');
|
||||
$usage = new Event('v1-usage', 'UsageV1');
|
||||
$mail = new Event('v1-mails', 'MailsV1');
|
||||
$deletes = new Event('v1-deletes', 'DeletesV1');
|
||||
|
||||
/**
|
||||
* Get All verified client URLs for both console and current projects
|
||||
* + Filter for duplicated entries
|
||||
*/
|
||||
$clientsConsole = \array_map(function ($node) {
|
||||
return $node['hostname'];
|
||||
}, \array_filter($console->getAttribute('platforms', []), function ($node) {
|
||||
if (isset($node['type']) && $node['type'] === 'web' && isset($node['hostname']) && !empty($node['hostname'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}));
|
||||
|
||||
$clients = \array_unique(\array_merge($clientsConsole, \array_map(function ($node) {
|
||||
return $node['hostname'];
|
||||
}, \array_filter($project->getAttribute('platforms', []), function ($node) {
|
||||
if (isset($node['type']) && $node['type'] === 'web' && isset($node['hostname']) && !empty($node['hostname'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}))));
|
||||
|
||||
App::init(function () use ($utopia, $request, $response, &$user, $project, $console, $webhook, $audit, $usage, $clients) {
|
||||
|
||||
$route = $utopia->match($request);
|
||||
|
||||
if(!empty($route->getLabel('sdk.platform', [])) && empty($project->getId()) && ($route->getLabel('scope', '') !== 'public')) {
|
||||
@@ -183,10 +75,20 @@ App::init(function () use ($utopia, $request, $response, &$user, $project, $cons
|
||||
$selfDomain = new Domain(Config::getParam('hostname'));
|
||||
$endDomain = new Domain($origin);
|
||||
|
||||
Config::setParam('domain', $request->getServer('HTTP_HOST', ''));
|
||||
|
||||
Config::setParam('domainVerification',
|
||||
($selfDomain->getRegisterable() === $endDomain->getRegisterable()) &&
|
||||
$endDomain->getRegisterable() !== '');
|
||||
|
||||
Config::setParam('cookieDomain', (
|
||||
$request->getServer('HTTP_HOST', null) === 'localhost' ||
|
||||
$request->getServer('HTTP_HOST', null) === 'localhost:'.$request->getPort() ||
|
||||
(\filter_var($request->getHostname(), FILTER_VALIDATE_IP) !== false)
|
||||
)
|
||||
? null
|
||||
: '.'.$request->getHostname()
|
||||
);
|
||||
/*
|
||||
* Security Headers
|
||||
*
|
||||
@@ -194,7 +96,7 @@ App::init(function () use ($utopia, $request, $response, &$user, $project, $cons
|
||||
* @see https://www.owasp.org/index.php/List_of_useful_HTTP_headers
|
||||
*/
|
||||
if (App::getEnv('_APP_OPTIONS_FORCE_HTTPS', 'disabled') === 'enabled') { // Force HTTPS
|
||||
if(Config::getParam('protocol') !== 'https') {
|
||||
if($request->getProtocol() !== 'https') {
|
||||
return $response->redirect('https://' . Config::getParam('domain').$request->getServer('REQUEST_URI'));
|
||||
}
|
||||
|
||||
@@ -312,13 +214,13 @@ App::init(function () use ($utopia, $request, $response, &$user, $project, $cons
|
||||
/*
|
||||
* Background Jobs
|
||||
*/
|
||||
$webhook
|
||||
$webhooks
|
||||
->setParam('projectId', $project->getId())
|
||||
->setParam('event', $route->getLabel('webhook', ''))
|
||||
->setParam('payload', [])
|
||||
;
|
||||
|
||||
$audit
|
||||
$audits
|
||||
->setParam('projectId', $project->getId())
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('event', '')
|
||||
@@ -336,10 +238,9 @@ App::init(function () use ($utopia, $request, $response, &$user, $project, $cons
|
||||
->setParam('response', 0)
|
||||
->setParam('storage', 0)
|
||||
;
|
||||
});
|
||||
|
||||
App::shutdown(function () use ($response, $request, $webhook, $audit, $usage, $deletes, $mode, $project, $utopia) {
|
||||
}, ['utopia', 'request', 'response', 'console', 'project', 'user', 'locale', 'webhook', 'audit', 'usage', 'clients']);
|
||||
|
||||
App::shutdown(function ($utopia, $response, $request, $webhook, $audit, $usage, $deletes, $mode, $project) {
|
||||
/*
|
||||
* Trigger events for background workers
|
||||
*/
|
||||
@@ -366,9 +267,9 @@ App::shutdown(function () use ($response, $request, $webhook, $audit, $usage, $d
|
||||
->trigger()
|
||||
;
|
||||
}
|
||||
});
|
||||
}, ['utopia', 'response', 'request', 'webhook', 'audit', 'usage', 'deletes', 'mode', 'project']);
|
||||
|
||||
App::options(function () use ($request, $response) {
|
||||
App::options(function ($request, $response) {
|
||||
$origin = $request->getServer('HTTP_ORIGIN');
|
||||
|
||||
$response
|
||||
@@ -378,10 +279,12 @@ App::options(function () use ($request, $response) {
|
||||
->addHeader('Access-Control-Allow-Origin', $origin)
|
||||
->addHeader('Access-Control-Allow-Credentials', 'true')
|
||||
->send();
|
||||
});
|
||||
}, ['request', 'response']);
|
||||
|
||||
App::error(function ($error /* @var $error Exception */) use ($request, $response, $utopia, $project) {
|
||||
$version = Config::getParam('version');
|
||||
App::error(function ($error, $utopia, $request, $response, $project) {
|
||||
/** @var Exception $error */
|
||||
|
||||
$version = App::getEnv('_APP_VERSION', 'UNKNOWN');
|
||||
|
||||
switch ($error->getCode()) {
|
||||
case 400: // Error allowed publicly
|
||||
@@ -449,102 +352,89 @@ App::error(function ($error /* @var $error Exception */) use ($request, $respons
|
||||
|
||||
$response->dynamic(new Document($output),
|
||||
$utopia->isDevelopment() ? Response::MODEL_ERROR_DEV : Response::MODEL_LOCALE);
|
||||
});
|
||||
}, ['error', 'utopia', 'request', 'response', 'project']);
|
||||
|
||||
App::get('/manifest.json')
|
||||
->desc('Progressive app manifest file')
|
||||
->label('scope', 'public')
|
||||
->label('docs', false)
|
||||
->action(
|
||||
function () use ($response) {
|
||||
$response->json([
|
||||
'name' => APP_NAME,
|
||||
'short_name' => APP_NAME,
|
||||
'start_url' => '.',
|
||||
'url' => 'https://appwrite.io/',
|
||||
'display' => 'standalone',
|
||||
'background_color' => '#fff',
|
||||
'theme_color' => '#f02e65',
|
||||
'description' => 'End to end backend server for frontend and mobile apps. 👩💻👨💻',
|
||||
'icons' => [
|
||||
[
|
||||
'src' => 'images/favicon.png',
|
||||
'sizes' => '256x256',
|
||||
'type' => 'image/png',
|
||||
],
|
||||
->action(function ($response) {
|
||||
/** @var Utopia\Response $response */
|
||||
|
||||
$response->json([
|
||||
'name' => APP_NAME,
|
||||
'short_name' => APP_NAME,
|
||||
'start_url' => '.',
|
||||
'url' => 'https://appwrite.io/',
|
||||
'display' => 'standalone',
|
||||
'background_color' => '#fff',
|
||||
'theme_color' => '#f02e65',
|
||||
'description' => 'End to end backend server for frontend and mobile apps. 👩💻👨💻',
|
||||
'icons' => [
|
||||
[
|
||||
'src' => 'images/favicon.png',
|
||||
'sizes' => '256x256',
|
||||
'type' => 'image/png',
|
||||
],
|
||||
]);
|
||||
}
|
||||
);
|
||||
],
|
||||
]);
|
||||
}, ['response']);
|
||||
|
||||
App::get('/robots.txt')
|
||||
->desc('Robots.txt File')
|
||||
->label('scope', 'public')
|
||||
->label('docs', false)
|
||||
->action(
|
||||
function () use ($response) {
|
||||
$template = new View(__DIR__.'/views/general/robots.phtml');
|
||||
$response->text($template->render(false));
|
||||
}
|
||||
);
|
||||
->action(function ($response) {
|
||||
$template = new View(__DIR__.'/views/general/robots.phtml');
|
||||
$response->text($template->render(false));
|
||||
}, ['response']);
|
||||
|
||||
App::get('/humans.txt')
|
||||
->desc('Humans.txt File')
|
||||
->label('scope', 'public')
|
||||
->label('docs', false)
|
||||
->action(
|
||||
function () use ($response) {
|
||||
$template = new View(__DIR__.'/views/general/humans.phtml');
|
||||
$response->text($template->render(false));
|
||||
}
|
||||
);
|
||||
->action(function ($response) {
|
||||
$template = new View(__DIR__.'/views/general/humans.phtml');
|
||||
$response->text($template->render(false));
|
||||
}, ['response']);
|
||||
|
||||
App::get('/.well-known/acme-challenge')
|
||||
->desc('SSL Verification')
|
||||
->label('scope', 'public')
|
||||
->label('docs', false)
|
||||
->action(
|
||||
function () use ($request, $response) {
|
||||
$base = \realpath(APP_STORAGE_CERTIFICATES);
|
||||
$path = \str_replace('/.well-known/acme-challenge/', '', $request->getParam('q'));
|
||||
$absolute = \realpath($base.'/.well-known/acme-challenge/'.$path);
|
||||
->action(function ($request, $response) {
|
||||
$base = \realpath(APP_STORAGE_CERTIFICATES);
|
||||
$path = \str_replace('/.well-known/acme-challenge/', '', $request->getParam('q'));
|
||||
$absolute = \realpath($base.'/.well-known/acme-challenge/'.$path);
|
||||
|
||||
if(!$base) {
|
||||
throw new Exception('Storage error', 500);
|
||||
}
|
||||
|
||||
if(!$absolute) {
|
||||
throw new Exception('Unknown path', 404);
|
||||
}
|
||||
|
||||
if(!\substr($absolute, 0, \strlen($base)) === $base) {
|
||||
throw new Exception('Invalid path', 401);
|
||||
}
|
||||
|
||||
if(!\file_exists($absolute)) {
|
||||
throw new Exception('Unknown path', 404);
|
||||
}
|
||||
|
||||
$content = @\file_get_contents($absolute);
|
||||
|
||||
if(!$content) {
|
||||
throw new Exception('Failed to get contents', 500);
|
||||
}
|
||||
|
||||
$response->text($content);
|
||||
if(!$base) {
|
||||
throw new Exception('Storage error', 500);
|
||||
}
|
||||
);
|
||||
|
||||
if(!$absolute) {
|
||||
throw new Exception('Unknown path', 404);
|
||||
}
|
||||
|
||||
if(!\substr($absolute, 0, \strlen($base)) === $base) {
|
||||
throw new Exception('Invalid path', 401);
|
||||
}
|
||||
|
||||
if(!\file_exists($absolute)) {
|
||||
throw new Exception('Unknown path', 404);
|
||||
}
|
||||
|
||||
$content = @\file_get_contents($absolute);
|
||||
|
||||
if(!$content) {
|
||||
throw new Exception('Failed to get contents', 500);
|
||||
}
|
||||
|
||||
$response->text($content);
|
||||
}, ['request', 'response']);
|
||||
|
||||
include_once __DIR__ . '/controllers/shared/api.php';
|
||||
include_once __DIR__ . '/controllers/shared/web.php';
|
||||
|
||||
foreach(Config::getParam('services', []) as $service) {
|
||||
include_once $service['controller'];
|
||||
}
|
||||
|
||||
App::setResource('utopia', function() use ($utopia) {return $utopia;});
|
||||
App::setResource('request', function() use ($request) {return $request;});
|
||||
App::setResource('response', function() use ($response) {return $response;});
|
||||
App::setResource('register', function() use ($register) {return $register;});
|
||||
|
||||
$utopia->run($request, $response);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user