Merge pull request #296 from appwrite/custom-domains

Custom domains
This commit is contained in:
Eldad A. Fux 2020-03-02 00:21:34 +02:00 committed by GitHub
commit e0fef48412
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
518 changed files with 8448 additions and 989 deletions

View file

@ -23,6 +23,9 @@
* Added ENV vars to change system email sender name and address
* Usage for requests made by project admin in the console are not counted as API usage
* Added ENV var to change default file upload size limit. New default value is 100MB
* Added option to delete file directly from the dashboard
* Added option to view file preview from the dashboard
* Added option to add custom domains with auto SSL certificate generator
## Bug Fixes

View file

@ -46,6 +46,8 @@ ENV TZ=Asia/Tel_Aviv \
DEBIAN_FRONTEND=noninteractive \
PHP_VERSION=7.4 \
_APP_ENV=production \
_APP_DOMAIN=localhost \
_APP_DOMAIN_TARGET=localhost \
_APP_HOME=https://appwrite.io \
_APP_EDITION=community \
_APP_OPTIONS_ABUSE=enabled \
@ -99,8 +101,12 @@ RUN \
rm -rf /var/lib/apt/lists/*
# Set Upload Limit (default to 100MB)
RUN echo "upload_max_filesize = ${_APP_STORAGE_LIMIT}" > /etc/php/$PHP_VERSION/fpm/conf.d/appwrite.ini
RUN echo "post_max_size = ${_APP_STORAGE_LIMIT}" > /etc/php/$PHP_VERSION/fpm/conf.d/appwrite.ini
RUN echo "upload_max_filesize = ${_APP_STORAGE_LIMIT}" >> /etc/php/$PHP_VERSION/fpm/conf.d/appwrite.ini
RUN echo "post_max_size = ${_APP_STORAGE_LIMIT}" >> /etc/php/$PHP_VERSION/fpm/conf.d/appwrite.ini
RUN echo "env[TESTME] = your-secret-key" >> /etc/php/$PHP_VERSION/fpm/conf.d/appwrite.ini
# Add logs file
RUN echo "" >> /var/log/appwrite.log
# Nginx Configuration (with self-signed ssl certificates)
COPY ./docker/nginx.conf /etc/nginx/nginx.conf
@ -128,6 +134,9 @@ COPY ./docker/supervisord.conf /etc/supervisord.conf
COPY ./docker/entrypoint.sh /entrypoint.sh
RUN chmod 775 /entrypoint.sh
# Letsencrypt Permissions
RUN mkdir -p /etc/letsencrypt/live/ && chmod -Rf 755 /etc/letsencrypt/live/
EXPOSE 80
WORKDIR /usr/share/nginx/html

View file

@ -3,7 +3,7 @@
// Init
require_once __DIR__.'/init.php';
global $env, $utopia, $request, $response, $register, $consoleDB, $project, $domain, $version, $service;
global $env, $utopia, $request, $response, $register, $consoleDB, $project, $domain, $version, $service, $protocol;
use Utopia\App;
use Utopia\Request;
@ -76,6 +76,7 @@ $utopia->init(function () use ($utopia, $request, $response, &$user, $project, $
->addHeader('X-Content-Type-Options', 'nosniff')
->addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE')
->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-SDK-Version')
->addHeader('Access-Control-Expose-Headers', 'X-Fallback-Cookies')
->addHeader('Access-Control-Allow-Origin', $refDomain)
->addHeader('Access-Control-Allow-Credentials', 'true')
;
@ -234,7 +235,8 @@ $utopia->options(function () use ($request, $response, $domain, $project) {
$response
->addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE')
->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-SDK-Version')
->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-SDK-Version, X-Fallback-Cookies')
->addHeader('Access-Control-Expose-Headers', 'X-Fallback-Cookies')
->addHeader('Access-Control-Allow-Origin', $origin)
->addHeader('Access-Control-Allow-Credentials', 'true')
->send();
@ -364,39 +366,37 @@ $utopia->get('/.well-known/acme-challenge')
->label('docs', false)
->action(
function () use ($request, $response) {
$base = realpath(__DIR__.'/../certs');
$base = realpath(APP_STORAGE_CERTIFICATES);
$path = str_replace('/.well-known/acme-challenge/', '', $request->getParam('q'));
$absolute = realpath($base.'/'.$path);
$absolute = realpath($base.'/.well-known/acme-challenge/'.$path);
if(!$base) {
throw new Exception('Storage error', 500);
}
if(!$absolute) {
//throw new Exception('Unknown Path', 404);
$response->json([
'error' => 'unknown path',
'base' => scandir($base),
'base/well' => scandir($base . '/.well-known/'),
'base/well/acme' => scandir($base . '/.well-known/acme-challenge/'),
'base/well/acme/query' => ($absolute) ? scandir($absolute) : ['not-a-dir'],
]);
return;
throw new Exception('Unknown path', 404);
}
if(!substr($absolute, 0, strlen($base)) === $base) {
//throw new Exception('Invalid Path', 401);
$response->json([
'error' => 'invalid path',
'base' => scandir($base),
'base/well' => scandir($base . '/.well-known/'),
'base/well/acme' => scandir($base . '/.well-known/acme-challenge/'),
'base/well/acme/query' => ($absolute) ? scandir($absolute) : ['not-a-dir'],
]);
return;
throw new Exception('Invalid path', 401);
}
$response->text(file_get_contents($absolute));
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);
}
);
$utopia->get('/v1/info') // This is only visible to gods
$utopia->get('/v1/info') // This is only visible to the gods
->label('scope', 'god')
->label('docs', false)
->action(
@ -453,7 +453,7 @@ $utopia->get('/v1/open-api-2.json')
->param('extensions', 0, function () {return new Range(0, 1);}, 'Show extra data.', true)
->param('tests', 0, function () {return new Range(0, 1);}, 'Include only test services.', true)
->action(
function ($platform, $extensions, $tests) use ($response, $request, $utopia, $domain, $services) {
function ($platform, $extensions, $tests) use ($response, $request, $utopia, $domain, $services, $protocol) {
function fromCamelCase($input)
{
preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches);
@ -588,7 +588,7 @@ $utopia->get('/v1/open-api-2.json')
],
'externalDocs' => [
'description' => 'Full API docs, specs and tutorials',
'url' => $request->getServer('REQUEST_SCHEME', 'https').'://'.$domain.'/docs',
'url' => $protocol.'://'.$domain.'/docs',
],
];

View file

@ -606,6 +606,16 @@ $collections = [
'array' => true,
'list' => [Database::SYSTEM_COLLECTION_PLATFORMS],
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Domains',
'key' => 'domains',
'type' => 'document',
'default' => [],
'required' => false,
'array' => true,
'list' => [Database::SYSTEM_COLLECTION_DOMAINS],
],
],
],
Database::SYSTEM_COLLECTION_WEBHOOKS => [
@ -931,6 +941,123 @@ $collections = [
],
],
],
Database::SYSTEM_COLLECTION_DOMAINS => [
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
'$id' => Database::SYSTEM_COLLECTION_DOMAINS,
'$permissions' => ['read' => ['*']],
'name' => 'Domains',
'structure' => true,
'rules' => [
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Domain',
'key' => 'domain',
'type' => 'text',
'default' => null,
'required' => true,
'array' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Updated',
'key' => 'updated',
'type' => 'numeric',
'default' => 0,
'required' => false,
'array' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Top Level Domain',
'key' => 'tld',
'type' => 'text',
'default' => '',
'required' => false,
'array' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Registerable Domain',
'key' => 'registerable',
'type' => 'text',
'default' => '',
'required' => false,
'array' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Verification',
'key' => 'verification',
'type' => 'boolean',
'default' => false,
'required' => true,
'array' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Certificate ID',
'key' => 'certificateId',
'type' => 'key',
'default' => '',
'required' => false,
'array' => false,
],
],
],
Database::SYSTEM_COLLECTION_CERTIFICATES => [
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
'$id' => Database::SYSTEM_COLLECTION_CERTIFICATES,
'$permissions' => ['read' => ['*']],
'name' => 'Certificates',
'structure' => true,
'rules' => [
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Domain',
'key' => 'domain',
'type' => 'text',
'default' => null,
'required' => true,
'array' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Issue Date',
'key' => 'issueDate',
'type' => 'numeric',
'default' => 0,
'required' => false,
'array' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Renew Date',
'key' => 'renewDate',
'type' => 'numeric',
'default' => 0,
'required' => false,
'array' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Attempts',
'key' => 'attempts',
'type' => 'numeric',
'default' => 0,
'required' => false,
'array' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Log',
'key' => 'log',
'type' => 'text',
'default' => '',
'required' => false,
'array' => false,
],
],
],
Database::SYSTEM_COLLECTION_FILES => [
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
'$id' => Database::SYSTEM_COLLECTION_FILES,
@ -1126,4 +1253,4 @@ foreach ($providers as $key => $provider) {
];
}
return $collections;
return $collections;

BIN
app/config/files/excel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
app/config/files/none.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
app/config/files/pdf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
app/config/files/ppt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
app/config/files/video.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
app/config/files/word.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -27,7 +27,7 @@ return [
'beta' => false,
'family' => APP_PLATFORM_CLIENT,
'prism' => 'javascript',
'source' => realpath(__DIR__ . '/../sdks/javascript'),
'source' => realpath(__DIR__ . '/../sdks/web-javascript'),
'gitUrl' => 'git@github.com:appwrite/sdk-for-js.git',
'gitRepoName' => 'sdk-for-js',
'gitUserName' => 'appwrite',
@ -136,7 +136,7 @@ return [
'beta' => true,
'family' => APP_PLATFORM_CLIENT,
'prism' => 'dart',
'source' => realpath(__DIR__ . '/../sdks/dart'),
'source' => realpath(__DIR__ . '/../sdks/flutter-dart'),
'gitUrl' => 'git@github.com:appwrite/sdk-for-dart.git',
'gitRepoName' => 'sdk-for-dart',
'gitUserName' => 'appwrite',
@ -144,27 +144,28 @@ return [
],
],
// APP_PLATFORM_CONSOLE => [
// 'name' => 'Console',
// 'enabled' => false,
// 'beta' => false,
// 'languages' => [
// [
// 'key' => 'javascript',
// 'name' => 'JS',
// 'version' => '1.0.0',
// 'url' => 'https://github.com/appwrite/sdk-for-console',
// 'enabled' => true,
// 'beta' => false,
// 'family' => APP_PLATFORM_CONSOLE,
// 'prism' => 'console',
// 'source' => realpath(__DIR__ . '/../sdks/console'),
// 'gitUrl' => 'git@github.com:appwrite/sdk-for-console.git',
// 'gitRepoName' => 'sdk-for-console',
// 'gitUserName' => 'appwrite',
// ],
// ],
// ],
APP_PLATFORM_CONSOLE => [
'key' => APP_PLATFORM_CONSOLE,
'name' => 'Console',
'enabled' => false,
'beta' => false,
'languages' => [
[
'key' => 'javascript',
'name' => 'JS',
'version' => '1.0.0',
'url' => 'https://github.com/appwrite/sdk-for-console',
'enabled' => true,
'beta' => false,
'family' => APP_PLATFORM_CONSOLE,
'prism' => 'console',
'source' => realpath(__DIR__ . '/../sdks/console-javascript'),
'gitUrl' => null,
'gitRepoName' => 'sdk-for-console',
'gitUserName' => 'appwrite',
],
],
],
APP_PLATFORM_SERVER => [
'key' => APP_PLATFORM_SERVER,
@ -182,7 +183,7 @@ return [
'beta' => false,
'family' => APP_PLATFORM_SERVER,
'prism' => 'javascript',
'source' => realpath(__DIR__ . '/../sdks/nodejs'),
'source' => realpath(__DIR__ . '/../sdks/server-nodejs'),
'gitUrl' => 'git@github.com:appwrite/sdk-for-node.git',
'gitRepoName' => 'sdk-for-node',
'gitUserName' => 'appwrite',
@ -196,7 +197,7 @@ return [
'beta' => false,
'family' => APP_PLATFORM_SERVER,
'prism' => 'php',
'source' => realpath(__DIR__ . '/../sdks/php'),
'source' => realpath(__DIR__ . '/../sdks/server-php'),
'gitUrl' => 'git@github.com:appwrite/sdk-for-php.git',
'gitRepoName' => 'sdk-for-php',
'gitUserName' => 'appwrite',
@ -210,7 +211,7 @@ return [
'beta' => true,
'family' => APP_PLATFORM_SERVER,
'prism' => 'python',
'source' => realpath(__DIR__ . '/../sdks/python'),
'source' => realpath(__DIR__ . '/../sdks/server-python'),
'gitUrl' => 'git@github.com:appwrite/sdk-for-python.git',
'gitRepoName' => 'sdk-for-python',
'gitUserName' => 'appwrite',
@ -224,7 +225,7 @@ return [
'beta' => true,
'family' => APP_PLATFORM_SERVER,
'prism' => 'ruby',
'source' => realpath(__DIR__ . '/../sdks/ruby'),
'source' => realpath(__DIR__ . '/../sdks/server-ruby'),
'gitUrl' => 'git@github.com:appwrite/sdk-for-ruby.git',
'gitRepoName' => 'sdk-for-ruby',
'gitUserName' => 'appwrite',
@ -238,7 +239,7 @@ return [
'beta' => true,
'family' => APP_PLATFORM_SERVER,
'prism' => 'go',
'source' => realpath(__DIR__ . '/../sdks/go'),
'source' => realpath(__DIR__ . '/../sdks/server-go'),
'gitUrl' => 'git@github.com:appwrite/sdk-for-go.git',
'gitRepoName' => 'sdk-for-go',
'gitUserName' => 'appwrite',

View file

@ -1,7 +1,7 @@
<?php
global $utopia, $register, $request, $response, $user, $audit,
$webhook, $project, $domain, $projectDB, $providers, $clients;
$webhook, $project, $domain, $projectDB, $providers, $clients, $protocol;
use Utopia\Exception;
use Utopia\Response;
@ -150,7 +150,7 @@ $utopia->post('/v1/account/sessions')
->param('email', '', function () { return new Email(); }, 'User email.')
->param('password', '', function () { return new Password(); }, 'User password.')
->action(
function ($email, $password) use ($response, $request, $projectDB, $audit, $webhook) {
function ($email, $password) use ($response, $request, $projectDB, $audit, $webhook, $protocol) {
$profile = $projectDB->getCollection([ // Get user by email address
'limit' => 1,
'first' => true,
@ -212,8 +212,9 @@ $utopia->post('/v1/account/sessions')
;
$response
->addCookie(Auth::$cookieName.'_legacy', Auth::encodeSession($profile->getId(), $secret), $expiry, '/', COOKIE_DOMAIN, ('https' == $request->getServer('REQUEST_SCHEME', 'https')), true, null)
->addCookie(Auth::$cookieName, Auth::encodeSession($profile->getId(), $secret), $expiry, '/', COOKIE_DOMAIN, ('https' == $request->getServer('REQUEST_SCHEME', 'https')), true, COOKIE_SAMESITE)
->addCookie(Auth::$cookieName.'_legacy', Auth::encodeSession($profile->getId(), $secret), $expiry, '/', COOKIE_DOMAIN, ('https' == $protocol), true, null)
->addCookie(Auth::$cookieName, Auth::encodeSession($profile->getId(), $secret), $expiry, '/', COOKIE_DOMAIN, ('https' == $protocol), true, COOKIE_SAMESITE)
->addHeader('X-Fallback-Cookies', json_encode([Auth::$cookieName => Auth::encodeSession($profile->getId(), $secret)]))
->setStatusCode(Response::STATUS_CODE_CREATED)
->json($session->getArrayCopy(['$id', 'type', 'expire']))
;
@ -237,8 +238,8 @@ $utopia->get('/v1/account/sessions/oauth2/:provider')
->param('success', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect back to your app after a successful login attempt.')
->param('failure', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect back to your app after a failed login attempt.')
->action(
function ($provider, $success, $failure) use ($response, $request, $project) {
$callback = $request->getServer('REQUEST_SCHEME', 'https').'://'.$request->getServer('HTTP_HOST').'/v1/account/sessions/oauth2/callback/'.$provider.'/'.$project->getId();
function ($provider, $success, $failure) use ($response, $request, $project, $protocol) {
$callback = $protocol.'://'.$request->getServer('HTTP_HOST').'/v1/account/sessions/oauth2/callback/'.$provider.'/'.$project->getId();
$appId = $project->getAttribute('usersOauth2'.ucfirst($provider).'Appid', '');
$appSecret = $project->getAttribute('usersOauth2'.ucfirst($provider).'Secret', '{}');
@ -275,8 +276,8 @@ $utopia->get('/v1/account/sessions/oauth2/callback/:provider/:projectId')
->param('code', '', function () { return new Text(1024); }, 'OAuth2 code.')
->param('state', '', function () { return new Text(2048); }, 'Login state params.', true)
->action(
function ($projectId, $provider, $code, $state) use ($response, $request, $domain) {
$response->redirect($request->getServer('REQUEST_SCHEME', 'https').'://'.$domain.'/v1/account/sessions/oauth2/'.$provider.'/redirect?'
function ($projectId, $provider, $code, $state) use ($response, $request, $domain, $protocol) {
$response->redirect($protocol.'://'.$domain.'/v1/account/sessions/oauth2/'.$provider.'/redirect?'
.http_build_query(['project' => $projectId, 'code' => $code, 'state' => $state]));
}
);
@ -293,8 +294,8 @@ $utopia->get('/v1/account/sessions/oauth2/:provider/redirect')
->param('code', '', function () { return new Text(1024); }, 'OAuth2 code.')
->param('state', '', function () { return new Text(2048); }, 'OAuth2 state params.', true)
->action(
function ($provider, $code, $state) use ($response, $request, $user, $projectDB, $project, $audit) {
$callback = $request->getServer('REQUEST_SCHEME', 'https').'://'.$request->getServer('HTTP_HOST').'/v1/account/sessions/oauth2/callback/'.$provider.'/'.$project->getId();
function ($provider, $code, $state) use ($response, $request, $user, $projectDB, $project, $audit, $protocol) {
$callback = $protocol.'://'.$request->getServer('HTTP_HOST').'/v1/account/sessions/oauth2/callback/'.$provider.'/'.$project->getId();
$defaultState = ['success' => $project->getAttribute('url', ''), 'failure' => ''];
$validateURL = new URL();
@ -443,8 +444,9 @@ $utopia->get('/v1/account/sessions/oauth2/:provider/redirect')
;
$response
->addCookie(Auth::$cookieName.'_legacy', Auth::encodeSession($user->getId(), $secret), $expiry, '/', COOKIE_DOMAIN, ('https' == $request->getServer('REQUEST_SCHEME', 'https')), true, null)
->addCookie(Auth::$cookieName, Auth::encodeSession($user->getId(), $secret), $expiry, '/', COOKIE_DOMAIN, ('https' == $request->getServer('REQUEST_SCHEME', 'https')), true, COOKIE_SAMESITE)
->addCookie(Auth::$cookieName.'_legacy', Auth::encodeSession($user->getId(), $secret), $expiry, '/', COOKIE_DOMAIN, ('https' == $protocol), true, null)
->addCookie(Auth::$cookieName, Auth::encodeSession($user->getId(), $secret), $expiry, '/', COOKIE_DOMAIN, ('https' == $protocol), true, COOKIE_SAMESITE)
->addHeader('X-Fallback-Cookies', json_encode([Auth::$cookieName => Auth::encodeSession($user->getId(), $secret)]))
->redirect($state['success'])
;
}
@ -810,7 +812,7 @@ $utopia->delete('/v1/account')
->label('sdk.method', 'delete')
->label('sdk.description', '/docs/references/account/delete.md')
->action(
function () use ($response, $request, $user, $projectDB, $audit, $webhook) {
function () use ($response, $user, $projectDB, $audit, $webhook, $protocol) {
$user = $projectDB->updateDocument(array_merge($user->getArrayCopy(), [
'status' => Auth::USER_STATUS_BLOCKED,
]));
@ -842,8 +844,9 @@ $utopia->delete('/v1/account')
;
$response
->addCookie(Auth::$cookieName.'_legacy', '', time() - 3600, '/', COOKIE_DOMAIN, ('https' == $request->getServer('REQUEST_SCHEME', 'https')), true, null)
->addCookie(Auth::$cookieName, '', time() - 3600, '/', COOKIE_DOMAIN, ('https' == $request->getServer('REQUEST_SCHEME', 'https')), true, COOKIE_SAMESITE)
->addCookie(Auth::$cookieName.'_legacy', '', time() - 3600, '/', COOKIE_DOMAIN, ('https' == $protocol), true, null)
->addCookie(Auth::$cookieName, '', time() - 3600, '/', COOKIE_DOMAIN, ('https' == $protocol), true, COOKIE_SAMESITE)
->addHeader('X-Fallback-Cookies', json_encode([]))
->noContent()
;
}
@ -860,7 +863,7 @@ $utopia->delete('/v1/account/sessions/:sessionId')
->label('abuse-limit', 100)
->param('sessionId', null, function () { return new UID(); }, 'Session unique ID. Use the string \'current\' to delete the current device session.')
->action(
function ($sessionId) use ($response, $request, $user, $projectDB, $webhook, $audit) {
function ($sessionId) use ($response, $user, $projectDB, $webhook, $audit, $protocol) {
$sessionId = ($sessionId === 'current')
? Auth::tokenVerify($user->getAttribute('tokens'), Auth::TOKEN_TYPE_LOGIN, Auth::$secret)
: $sessionId;
@ -888,8 +891,9 @@ $utopia->delete('/v1/account/sessions/:sessionId')
if ($token->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too
$response
->addCookie(Auth::$cookieName.'_legacy', '', time() - 3600, '/', COOKIE_DOMAIN, ('https' == $request->getServer('REQUEST_SCHEME', 'https')), true, null)
->addCookie(Auth::$cookieName, '', time() - 3600, '/', COOKIE_DOMAIN, ('https' == $request->getServer('REQUEST_SCHEME', 'https')), true, COOKIE_SAMESITE)
->addCookie(Auth::$cookieName.'_legacy', '', time() - 3600, '/', COOKIE_DOMAIN, ('https' == $protocol), true, null)
->addCookie(Auth::$cookieName, '', time() - 3600, '/', COOKIE_DOMAIN, ('https' == $protocol), true, COOKIE_SAMESITE)
->addHeader('X-Fallback-Cookies', json_encode([]))
;
}
@ -911,7 +915,7 @@ $utopia->delete('/v1/account/sessions')
->label('sdk.description', '/docs/references/account/delete-sessions.md')
->label('abuse-limit', 100)
->action(
function () use ($response, $request, $user, $projectDB, $audit, $webhook) {
function () use ($response, $user, $projectDB, $audit, $webhook, $protocol) {
$tokens = $user->getAttribute('tokens', []);
foreach ($tokens as $token) { /* @var $token Document */
@ -934,8 +938,9 @@ $utopia->delete('/v1/account/sessions')
if ($token->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too
$response
->addCookie(Auth::$cookieName.'_legacy', '', time() - 3600, '/', COOKIE_DOMAIN, ('https' == $request->getServer('REQUEST_SCHEME', 'https')), true, null)
->addCookie(Auth::$cookieName, '', time() - 3600, '/', COOKIE_DOMAIN, ('https' == $request->getServer('REQUEST_SCHEME', 'https')), true, COOKIE_SAMESITE)
->addCookie(Auth::$cookieName.'_legacy', '', time() - 3600, '/', COOKIE_DOMAIN, ('https' == $protocol), true, null)
->addCookie(Auth::$cookieName, '', time() - 3600, '/', COOKIE_DOMAIN, ('https' == $protocol), true, COOKIE_SAMESITE)
->addHeader('X-Fallback-Cookies', json_encode([]))
;
}
}

View file

@ -49,7 +49,7 @@ $avatarCallback = function ($type, $code, $width, $height, $quality) use ($types
throw new Exception('File not readable in '.$path, 500);
}
$cache = new Cache(new Filesystem('/storage/cache/app-0')); // Limit file number or size
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE.'/app-0')); // Limit file number or size
$data = $cache->load($key, 60 * 60 * 24 * 30 * 3 /* 3 months */);
if ($data) {
@ -146,7 +146,7 @@ $utopia->get('/v1/avatars/image')
$date = date('D, d M Y H:i:s', time() + (60 * 60 * 24 * 45)).' GMT'; // 45 days cache
$key = md5('/v2/avatars/images-'.$url.'-'.$width.'/'.$height.'/'.$quality);
$type = 'png';
$cache = new Cache(new Filesystem('/storage/cache/app-0')); // Limit file number or size
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE.'/app-0')); // Limit file number or size
$data = $cache->load($key, 60 * 60 * 24 * 7 /* 1 week */);
if ($data) {
@ -206,7 +206,7 @@ $utopia->get('/v1/avatars/favicon')
->label('sdk.method', 'getFavicon')
->label('sdk.description', '/docs/references/avatars/get-favicon.md')
->action(
function ($url) use ($response, $version) {
function ($url) use ($response, $request, $version) {
$width = 56;
$height = 56;
$quality = 80;
@ -214,7 +214,7 @@ $utopia->get('/v1/avatars/favicon')
$date = date('D, d M Y H:i:s', time() + (60 * 60 * 24 * 45)).' GMT'; // 45 days cache
$key = md5('/v2/avatars/favicon-'.$url);
$type = 'png';
$cache = new Cache(new Filesystem('/storage/cache/app-0')); // Limit file number or size
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE.'/app-0')); // Limit file number or size
$data = $cache->load($key, 60 * 60 * 24 * 30 * 3 /* 3 months */);
if ($data) {
@ -237,7 +237,10 @@ $utopia->get('/v1/avatars/favicon')
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 3,
CURLOPT_URL => $url,
CURLOPT_USERAGENT => sprintf(APP_USERAGENT, $version),
CURLOPT_USERAGENT => sprintf(APP_USERAGENT,
$version,
$request->getServer('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', APP_EMAIL_SECURITY)
),
]);
$html = curl_exec($curl);

View file

@ -119,7 +119,7 @@ $utopia->get('/v1/health/storage/local')
->label('docs', false)
->action(
function () use ($response) {
$device = new Local('/storage/uploads/');
$device = new Local(APP_STORAGE_UPLOADS.'/');
if (!is_readable($device->getRoot().'/..')) {
throw new Exception('Device is not readable');

View file

@ -6,16 +6,19 @@ use Auth\Auth;
use Utopia\Exception;
use Utopia\Response;
use Utopia\Validator\ArrayList;
use Utopia\Validator\Domain as DomainValidator;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
use Utopia\Validator\Range;
use Utopia\Validator\URL;
use Utopia\Domains\Domain;
use Task\Validator\Cron;
use Database\Database;
use Database\Document;
use Database\Validator\UID;
use OpenSSL\OpenSSL;
use Cron\CronExpression;
use Network\Validators\CNAME;
include_once __DIR__ . '/../shared/api.php';
@ -515,7 +518,7 @@ $utopia->get('/v1/projects/:projectId/webhooks/:webhookId')
$webhook = $project->search('$id', $webhookId, $project->getAttribute('webhooks', []));
if (empty($webhook) && $webhook instanceof Document) {
if (empty($webhook) || !$webhook instanceof Document) {
throw new Exception('Webhook not found', 404);
}
@ -565,7 +568,7 @@ $utopia->put('/v1/projects/:projectId/webhooks/:webhookId')
$webhook = $project->search('$id', $webhookId, $project->getAttribute('webhooks', []));
if (empty($webhook) && $webhook instanceof Document) {
if (empty($webhook) || !$webhook instanceof Document) {
throw new Exception('Webhook not found', 404);
}
@ -603,7 +606,7 @@ $utopia->delete('/v1/projects/:projectId/webhooks/:webhookId')
$webhook = $project->search('$id', $webhookId, $project->getAttribute('webhooks', []));
if (empty($webhook) && $webhook instanceof Document) {
if (empty($webhook) || !$webhook instanceof Document) {
throw new Exception('Webhook not found', 404);
}
@ -698,7 +701,7 @@ $utopia->get('/v1/projects/:projectId/keys/:keyId')
$key = $project->search('$id', $keyId, $project->getAttribute('keys', []));
if (empty($key) && $key instanceof Document) {
if (empty($key) || !$key instanceof Document) {
throw new Exception('Key not found', 404);
}
@ -725,7 +728,7 @@ $utopia->put('/v1/projects/:projectId/keys/:keyId')
$key = $project->search('$id', $keyId, $project->getAttribute('keys', []));
if (empty($key) && $key instanceof Document) {
if (empty($key) || !$key instanceof Document) {
throw new Exception('Key not found', 404);
}
@ -759,7 +762,7 @@ $utopia->delete('/v1/projects/:projectId/keys/:keyId')
$key = $project->search('$id', $keyId, $project->getAttribute('keys', []));
if (empty($key) && $key instanceof Document) {
if (empty($key) || !$key instanceof Document) {
throw new Exception('Key not found', 404);
}
@ -904,7 +907,7 @@ $utopia->get('/v1/projects/:projectId/tasks/:taskId')
$task = $project->search('$id', $taskId, $project->getAttribute('tasks', []));
if (empty($task) && $task instanceof Document) {
if (empty($task) || !$task instanceof Document) {
throw new Exception('Task not found', 404);
}
@ -945,7 +948,7 @@ $utopia->put('/v1/projects/:projectId/tasks/:taskId')
$task = $project->search('$id', $taskId, $project->getAttribute('tasks', []));
if (empty($task) && $task instanceof Document) {
if (empty($task) || !$task instanceof Document) {
throw new Exception('Task not found', 404);
}
@ -1006,7 +1009,7 @@ $utopia->delete('/v1/projects/:projectId/tasks/:taskId')
$task = $project->search('$id', $taskId, $project->getAttribute('tasks', []));
if (empty($task) && $task instanceof Document) {
if (empty($task) || !$task instanceof Document) {
throw new Exception('Task not found', 404);
}
@ -1110,7 +1113,7 @@ $utopia->get('/v1/projects/:projectId/platforms/:platformId')
$platform = $project->search('$id', $platformId, $project->getAttribute('platforms', []));
if (empty($platform) && $platform instanceof Document) {
if (empty($platform) || !$platform instanceof Document) {
throw new Exception('Platform not found', 404);
}
@ -1139,7 +1142,7 @@ $utopia->put('/v1/projects/:projectId/platforms/:platformId')
$platform = $project->search('$id', $platformId, $project->getAttribute('platforms', []));
if (empty($platform) && $platform instanceof Document) {
if (empty($platform) || !$platform instanceof Document) {
throw new Exception('Platform not found', 404);
}
@ -1176,7 +1179,7 @@ $utopia->delete('/v1/projects/:projectId/platforms/:platformId')
$platform = $project->search('$id', $platformId, $project->getAttribute('platforms', []));
if (empty($platform) && $platform instanceof Document) {
if (empty($platform) || !$platform instanceof Document) {
throw new Exception('Platform not found', 404);
}
@ -1186,4 +1189,218 @@ $utopia->delete('/v1/projects/:projectId/platforms/:platformId')
$response->noContent();
}
);
// Domains
$utopia->post('/v1/projects/:projectId/domains')
->desc('Create Domain')
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'createDomain')
->param('projectId', null, function () { return new UID(); }, 'Project unique ID.')
->param('domain', null, function () { return new DomainValidator(); }, 'Domain name.')
->action(
function ($projectId, $domain) use ($request, $response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
if (empty($project->getId()) || Database::SYSTEM_COLLECTION_PROJECTS != $project->getCollection()) {
throw new Exception('Project not found', 404);
}
$document = $project->search('domain', $domain, $project->getAttribute('domains', []));
if (!empty($document)) {
throw new Exception('Domain already exists', 409);
}
$target = new Domain($request->getServer('_APP_DOMAIN_TARGET', ''));
if(!$target->isKnown() || $target->isTest()) {
throw new Exception('Unreachable CNAME target ('.$target->get().'), plesse use a domain with a public suffix.', 500);
}
$domain = new Domain($domain);
$domain = $consoleDB->createDocument([
'$collection' => Database::SYSTEM_COLLECTION_DOMAINS,
'$permissions' => [
'read' => ['team:'.$project->getAttribute('teamId', null)],
'write' => ['team:'.$project->getAttribute('teamId', null).'/owner', 'team:'.$project->getAttribute('teamId', null).'/developer'],
],
'updated' => time(),
'domain' => $domain->get(),
'tld' => $domain->getSuffix(),
'registerable' => $domain->getRegisterable(),
'verification' => false,
'certificateId' => null,
]);
if (false === $domain) {
throw new Exception('Failed saving domain to DB', 500);
}
$project->setAttribute('domains', $domain, Document::SET_TYPE_APPEND);
$project = $consoleDB->updateDocument($project->getArrayCopy());
if (false === $project) {
throw new Exception('Failed saving project to DB', 500);
}
$response
->setStatusCode(Response::STATUS_CODE_CREATED)
->json($domain->getArrayCopy())
;
}
);
$utopia->get('/v1/projects/:projectId/domains')
->desc('List Domains')
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'listDomains')
->param('projectId', '', function () { return new UID(); }, 'Project unique ID.')
->action(
function ($projectId) use ($response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
if (empty($project->getId()) || Database::SYSTEM_COLLECTION_PROJECTS != $project->getCollection()) {
throw new Exception('Project not found', 404);
}
$domains = $project->getAttribute('domains', []);
$response->json($domains);
}
);
$utopia->get('/v1/projects/:projectId/domains/:domainId')
->desc('Get Domain')
->label('scope', 'projects.read')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'getDomain')
->param('projectId', null, function () { return new UID(); }, 'Project unique ID.')
->param('domainId', null, function () { return new UID(); }, 'Domain unique ID.')
->action(
function ($projectId, $domainId) use ($request, $response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
if (empty($project->getId()) || Database::SYSTEM_COLLECTION_PROJECTS != $project->getCollection()) {
throw new Exception('Project not found', 404);
}
$domain = $project->search('$id', $domainId, $project->getAttribute('domains', []));
if (empty($domain) || !$domain instanceof Document) {
throw new Exception('Domain not found', 404);
}
$response->json($domain->getArrayCopy());
}
);
$utopia->patch('/v1/projects/:projectId/domains/:domainId/verification')
->desc('Update Domain Verification Status')
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updateDomainVerification')
->param('projectId', null, function () { return new UID(); }, 'Project unique ID.')
->param('domainId', null, function () { return new UID(); }, 'Domain unique ID.')
->action(
function ($projectId, $domainId) use ($request, $response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
if (empty($project->getId()) || Database::SYSTEM_COLLECTION_PROJECTS != $project->getCollection()) {
throw new Exception('Project not found', 404);
}
$domain = $project->search('$id', $domainId, $project->getAttribute('domains', []));
if (empty($domain) || !$domain instanceof Document) {
throw new Exception('Domain not found', 404);
}
$target = new Domain($request->getServer('_APP_DOMAIN_TARGET', ''));
if(!$target->isKnown() || $target->isTest()) {
throw new Exception('Unreachable CNAME target ('.$target->get().'), plesse use a domain with a public suffix.', 500);
}
if($domain->getAttribute('verification') === true) {
return $response->json($domain->getArrayCopy());
}
// Verify Domain with DNS records
$validator = new CNAME($target->get());
if(!$validator->isValid($domain->getAttribute('domain', ''))) {
throw new Exception('Failed to verify domain', 401);
}
$domain
->setAttribute('verification', true)
;
if (false === $consoleDB->updateDocument($domain->getArrayCopy())) {
throw new Exception('Failed saving domains to DB', 500);
}
// Issue a TLS certificate when domain is verified
Resque::enqueue('v1-certificates', 'CertificatesV1', [
'document' => $domain->getArrayCopy(),
'domain' => $domain->getAttribute('domain'),
]);
$response->json($domain->getArrayCopy());
}
);
$utopia->delete('/v1/projects/:projectId/domains/:domainId')
->desc('Delete Domain')
->label('scope', 'projects.write')
->label('sdk.namespace', 'projects')
->label('sdk.method', 'deleteDomain')
->param('projectId', null, function () { return new UID(); }, 'Project unique ID.')
->param('domainId', null, function () { return new UID(); }, 'Domain unique ID.')
->action(
function ($projectId, $domainId) use ($response, $consoleDB) {
$project = $consoleDB->getDocument($projectId);
if (empty($project->getId()) || Database::SYSTEM_COLLECTION_PROJECTS != $project->getCollection()) {
throw new Exception('Project not found', 404);
}
$domain = $project->search('$id', $domainId, $project->getAttribute('domains', []));
if (empty($domain) || !$domain instanceof Document) {
throw new Exception('Domain not found', 404);
}
if (!$consoleDB->deleteDocument($domain->getId())) {
throw new Exception('Failed to remove domains from DB', 500);
}
$response->noContent();
}
);
$utopia->get('/v1/projects/x/certs')
->desc('List Domains')
->label('scope', 'public')
->action(
function () use ($response, $consoleDB) {
\Database\Validator\Authorization::disable();
$results = $consoleDB->getCollection([
'limit' => 2000,
'offset' => 0,
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_USERS,
],
]);
\Database\Validator\Authorization::reset();
$response->json($results);
}
);

View file

@ -1,6 +1,6 @@
<?php
global $utopia, $request, $response, $register, $user, $audit, $usage, $project, $projectDB;
global $utopia, $request, $response, $register, $user, $audit, $usage, $project, $projectDB, $version;
use Utopia\Exception;
use Utopia\Response;
@ -25,41 +25,48 @@ use OpenSSL\OpenSSL;
include_once __DIR__ . '/../shared/api.php';
Storage::addDevice('local', new Local('/storage/uploads/app-'.$project->getId()));
Storage::addDevice('local', new Local(APP_STORAGE_UPLOADS.'/app-'.$project->getId()));
$fileLogos = [ // Based on this list @see http://stackoverflow.com/a/4212908/2299554
'default' => 'default.gif',
'default' => __DIR__.'/../../config/files/none.png',
// Video Files
'video/mp4' => __DIR__.'/../../config/files/video.png',
'video/x-flv' => __DIR__.'/../../config/files/video.png',
'application/x-mpegURL' => __DIR__.'/../../config/files/video.png',
'video/MP2T' => __DIR__.'/../../config/files/video.png',
'video/3gpp' => __DIR__.'/../../config/files/video.png',
'video/quicktime' => __DIR__.'/../../config/files/video.png',
'video/x-msvideo' => __DIR__.'/../../config/files/video.png',
'video/x-ms-wmv' => __DIR__.'/../../config/files/video.png',
// Microsoft Word
'application/msword' => 'word.gif',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'word.gif',
'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => 'word.gif',
'application/vnd.ms-word.document.macroEnabled.12' => 'word.gif',
// // Microsoft Word
'application/msword' => __DIR__.'/../../config/files/word.png',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => __DIR__.'/../../config/files/word.png',
'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => __DIR__.'/../../config/files/word.png',
'application/vnd.ms-word.document.macroEnabled.12' => __DIR__.'/../../config/files/word.png',
// Microsoft Excel
'application/vnd.ms-excel' => 'excel.gif',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'excel.gif',
'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => 'excel.gif',
'application/vnd.ms-excel.sheet.macroEnabled.12' => 'excel.gif',
'application/vnd.ms-excel.template.macroEnabled.12' => 'excel.gif',
'application/vnd.ms-excel.addin.macroEnabled.12' => 'excel.gif',
'application/vnd.ms-excel.sheet.binary.macroEnabled.12' => 'excel.gif',
// // Microsoft Excel
'application/vnd.ms-excel' => __DIR__.'/../../config/files/excel.png',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => __DIR__.'/../../config/files/excel.png',
'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => __DIR__.'/../../config/files/excel.png',
'application/vnd.ms-excel.sheet.macroEnabled.12' => __DIR__.'/../../config/files/excel.png',
'application/vnd.ms-excel.template.macroEnabled.12' => __DIR__.'/../../config/files/excel.png',
'application/vnd.ms-excel.addin.macroEnabled.12' => __DIR__.'/../../config/files/excel.png',
'application/vnd.ms-excel.sheet.binary.macroEnabled.12' => __DIR__.'/../../config/files/excel.png',
// Microsoft Power Point
'application/vnd.ms-powerpoint' => 'powerpoint.gif',
'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'powerpoint.gif',
'application/vnd.openxmlformats-officedocument.presentationml.template' => 'powerpoint.gif',
'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => 'powerpoint.gif',
'application/vnd.ms-powerpoint.addin.macroEnabled.12' => 'powerpoint.gif',
'application/vnd.ms-powerpoint.presentation.macroEnabled.12' => 'powerpoint.gif',
'application/vnd.ms-powerpoint.template.macroEnabled.12' => 'powerpoint.gif',
'application/vnd.ms-powerpoint.slideshow.macroEnabled.12' => 'powerpoint.gif',
// Microsoft Access
'application/vnd.ms-access' => 'access.gif',
// // Microsoft Power Point
'application/vnd.ms-powerpoint' => __DIR__.'/../../config/files/ppt.png',
'application/vnd.openxmlformats-officedocument.presentationml.presentation' => __DIR__.'/../../config/files/ppt.png',
'application/vnd.openxmlformats-officedocument.presentationml.template' => __DIR__.'/../../config/files/ppt.png',
'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => __DIR__.'/../../config/files/ppt.png',
'application/vnd.ms-powerpoint.addin.macroEnabled.12' => __DIR__.'/../../config/files/ppt.png',
'application/vnd.ms-powerpoint.presentation.macroEnabled.12' => __DIR__.'/../../config/files/ppt.png',
'application/vnd.ms-powerpoint.template.macroEnabled.12' => __DIR__.'/../../config/files/ppt.png',
'application/vnd.ms-powerpoint.slideshow.macroEnabled.12' => __DIR__.'/../../config/files/ppt.png',
// Adobe PDF
'application/pdf' => 'pdf.gif',
'application/pdf' => __DIR__.'/../../config/files/pdf.png',
];
$inputs = [
@ -84,6 +91,16 @@ $mimes = [
'image/png',
'image/webp',
// Video Files
'video/mp4',
'video/x-flv',
'application/x-mpegURL',
'video/MP2T',
'video/3gpp',
'video/quicktime',
'video/x-msvideo',
'video/x-ms-wmv',
// Microsoft Word
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
@ -321,7 +338,7 @@ $utopia->get('/v1/storage/files/:fileId/preview')
//->param('storage', 'local', function () {return new WhiteList(array('local'));}, 'Selected storage device. defaults to local')
//->param('token', '', function () {return new Text(128);}, 'Preview token', true)
->action(
function ($fileId, $width, $height, $quality, $background, $output) use ($request, $response, $projectDB, $project, $inputs, $outputs, $fileLogos) {
function ($fileId, $width, $height, $quality, $background, $output) use ($request, $response, $projectDB, $project, $inputs, $outputs, $fileLogos, $version) {
$storage = 'local';
if (!extension_loaded('imagick')) {
@ -337,7 +354,7 @@ $utopia->get('/v1/storage/files/:fileId/preview')
}
$date = date('D, d M Y H:i:s', time() + (60 * 60 * 24 * 45)).' GMT'; // 45 days cache
$key = md5($fileId.$width.$height.$quality.$background.$storage.$output);
$key = md5($version.$fileId.$width.$height.$quality.$background.$storage.$output);
$file = $projectDB->getDocument($fileId);
@ -346,18 +363,28 @@ $utopia->get('/v1/storage/files/:fileId/preview')
}
$path = $file->getAttribute('path');
$algorithm = $file->getAttribute('algorithm');
$type = strtolower(pathinfo($path, PATHINFO_EXTENSION));
$algorithm = $file->getAttribute('algorithm');
$cipher = $file->getAttribute('fileOpenSSLCipher');
$mime = $file->getAttribute('mimeType');
if(!in_array($mime, $inputs)) {
$path = (array_key_exists($mime, $fileLogos)) ? $fileLogos[$mime] : $fileLogos['default'];
$algorithm = null;
$cipher = null;
$background = (empty($background)) ? 'eceff1' : $background;
$type = strtolower(pathinfo($path, PATHINFO_EXTENSION));
$key = md5($version.$path.$width.$height.$quality.$background.$storage.$output);
}
$compressor = new GZIP();
$device = Storage::getDevice('local');
if (!file_exists($path)) {
throw new Exception('File not found in '.$path, 404);
throw new Exception('File not found', 404);
}
$cache = new Cache(new Filesystem('/storage/cache/app-'.$project->getId())); // Limit file number or size
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE.'/app-'.$project->getId())); // Limit file number or size
$data = $cache->load($key, 60 * 60 * 24 * 30 * 3 /* 3 months */);
if ($data) {

View file

@ -426,7 +426,7 @@ $utopia->patch('/v1/teams/:teamId/memberships/:inviteId/status')
->param('userId', '', function () { return new UID(); }, 'User unique ID.')
->param('secret', '', function () { return new Text(256); }, 'Secret key.')
->action(
function ($teamId, $inviteId, $userId, $secret) use ($response, $request, $user, $audit, $projectDB) {
function ($teamId, $inviteId, $userId, $secret) use ($response, $request, $user, $audit, $projectDB, $protocol) {
$membership = $projectDB->getDocument($inviteId);
if (empty($membership->getId()) || Database::SYSTEM_COLLECTION_MEMBERSHIPS != $membership->getCollection()) {
@ -521,8 +521,9 @@ $utopia->patch('/v1/teams/:teamId/memberships/:inviteId/status')
;
$response
->addCookie(Auth::$cookieName.'_legacy', Auth::encodeSession($user->getId(), $secret), $expiry, '/', COOKIE_DOMAIN, ('https' == $request->getServer('REQUEST_SCHEME', 'https')), true, null)
->addCookie(Auth::$cookieName, Auth::encodeSession($user->getId(), $secret), $expiry, '/', COOKIE_DOMAIN, ('https' == $request->getServer('REQUEST_SCHEME', 'https')), true, COOKIE_SAMESITE)
->addCookie(Auth::$cookieName.'_legacy', Auth::encodeSession($user->getId(), $secret), $expiry, '/', COOKIE_DOMAIN, ('https' == $protocol), true, null)
->addCookie(Auth::$cookieName, Auth::encodeSession($user->getId(), $secret), $expiry, '/', COOKIE_DOMAIN, ('https' == $protocol), true, COOKIE_SAMESITE)
->addHeader('X-Fallback-Cookies', json_encode([Auth::$cookieName => Auth::encodeSession($user->getId(), $secret)]))
->json(array_merge($membership->getArrayCopy([
'$id',
'userId',

View file

@ -321,7 +321,7 @@ $utopia->get('/v1/mock/tests/general/oauth2/failure')
$utopia->shutdown(function() use ($response, $request, &$result, $utopia) {
$route = $utopia->match($request);
$path = '/storage/cache/tests.json';
$path = APP_STORAGE_CACHE.'/tests.json';
$tests = (file_exists($path)) ? json_decode(file_get_contents($path), true) : [];
if(!is_array($tests)) {

View file

@ -3,6 +3,8 @@
use Utopia\View;
use Utopia\Locale\Locale;
global $protocol;
Locale::$exceptions = false;
$roles = [
@ -20,7 +22,7 @@ if (!empty($request->getQuery('version', ''))) {
$layout
->setParam('title', APP_NAME)
->setParam('protocol', $request->getServer('REQUEST_SCHEME', 'https'))
->setParam('protocol', $protocol)
->setParam('domain', $domain)
->setParam('home', $request->getServer('_APP_HOME'))
->setParam('setup', $request->getServer('_APP_SETUP'))

View file

@ -5,6 +5,7 @@ include_once __DIR__ . '/../shared/web.php';
global $utopia, $response, $request, $layout, $version, $providers, $projectDB;
use Utopia\View;
use Utopia\Domains\Domain;
use Database\Database;
use Database\Validator\UID;
use Storage\Storage;
@ -116,9 +117,16 @@ $utopia->get('/console/settings')
->desc('Platform console project settings')
->label('permission', 'public')
->label('scope', 'console')
->action(function () use ($layout) {
->action(function () use ($request, $layout) {
$target = new Domain($request->getServer('_APP_DOMAIN_TARGET', ''));
$page = new View(__DIR__.'/../../views/console/settings/index.phtml');
$page
->setParam('customDomainsEnabled', ($target->isKnown() && !$target->isTest()))
->setParam('customDomainsTarget', $target->get())
;
$layout
->setParam('title', APP_NAME.' - Settings')
->setParam('body', $page);

View file

@ -20,12 +20,24 @@ use PHPMailer\PHPMailer\PHPMailer;
const APP_NAME = 'Appwrite';
const APP_DOMAIN = 'appwrite.io';
const APP_EMAIL_TEAM = 'team@'.APP_DOMAIN;
const APP_EMAIL_SECURITY = 'security@'.APP_DOMAIN;
const APP_USERAGENT = APP_NAME.'-Server/%s Please report abuse at '.APP_EMAIL_SECURITY;
const APP_EMAIL_TEAM = 'team@localhost.test'; // Default email address
const APP_EMAIL_SECURITY = 'security@localhost.test'; // Default security email address
const APP_USERAGENT = APP_NAME.'-Server v%s. Please report abuse at %s';
const APP_MODE_ADMIN = 'admin';
const APP_PAGING_LIMIT = 15;
const APP_CACHE_BUSTER = 48;
const APP_VERSION_STABLE = '0.5.0';
const APP_STORAGE_UPLOADS = '/storage/uploads';
const APP_STORAGE_CACHE = '/storage/cache';
const APP_STORAGE_CERTIFICATES = '/storage/certificates';
const APP_STORAGE_CONFIG = '/storage/config';
const APP_SOCIAL_TWITTER = 'https://twitter.com/appwrite_io';
const APP_SOCIAL_TWITTER_HANDLE = 'appwrite_io';
const APP_SOCIAL_FACEBOOK = 'https://www.facebook.com/appwrite.io';
const APP_SOCIAL_LINKEDIN = 'https://www.linkedin.com/company/appwrite';
const APP_SOCIAL_INSTAGRAM = 'https://www.instagram.com/appwrite.io';
const APP_SOCIAL_GITHUB = 'https://github.com/appwrite';
const APP_SOCIAL_DISCORD = 'https://discord.gg/GSeTUeA';
$register = new Registry();
$request = new Request();
@ -44,8 +56,8 @@ $collections = include __DIR__.'/../app/config/collections.php'; // Collections
$redisHost = $request->getServer('_APP_REDIS_HOST', '');
$redisPort = $request->getServer('_APP_REDIS_PORT', '');
$utopia = new App('Asia/Tel_Aviv', $env);
$scheme = $request->getServer('REQUEST_SCHEME', '');
$port = (string) parse_url($scheme.'://'.$request->getServer('HTTP_HOST', ''), PHP_URL_PORT);
$protocol = $request->getServer('HTTP_X_FORWARDED_PROTO', $request->getServer('REQUEST_SCHEME', 'https'));
$port = (string) parse_url($protocol.'://'.$request->getServer('HTTP_HOST', ''), PHP_URL_PORT);
Resque::setBackend($redisHost.':'.$redisPort);
@ -56,7 +68,7 @@ define('COOKIE_DOMAIN',
(filter_var($request->getServer('HTTP_HOST', null), FILTER_VALIDATE_IP) !== false)
)
? null
: '.'.parse_url($scheme.'://'.$request->getServer('HTTP_HOST', ''), PHP_URL_HOST));
: '.'.parse_url($protocol.'://'.$request->getServer('HTTP_HOST', ''), PHP_URL_HOST));
define('COOKIE_SAMESITE', Response::COOKIE_SAMESITE_NONE);
/*
@ -197,7 +209,9 @@ if (in_array($locale, $locales)) {
stream_context_set_default([ // Set global user agent and http settings
'http' => [
'method' => 'GET',
'user_agent' => sprintf(APP_USERAGENT, $version),
'user_agent' => sprintf(APP_USERAGENT,
$version,
$request->getServer('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', APP_EMAIL_SECURITY)),
'timeout' => 2,
],
]);
@ -229,7 +243,18 @@ if (APP_MODE_ADMIN === $mode) {
$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
$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', null);
$fallback = json_decode($fallback, true);
$session = Auth::decodeSession(((isset($fallback[Auth::$cookieName])) ? $fallback[Auth::$cookieName] : ''));
}
Auth::$unique = $session['id'];
Auth::$secret = $session['secret'];

View file

@ -0,0 +1,38 @@
# Appwrite SDK for JavaScript
![License](https://img.shields.io/github/license/appwrite/sdk-for-console.svg?v=1)
![Version](https://img.shields.io/badge/api%20version-0.5.0-blue.svg?v=1)
Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)
![Appwrite](https://appwrite.io/images/github.png)
## Installation
### NPM
To install via [NPM](https://www.npmjs.com/):
```bash
npm install appwrite --save
```
If you're using a bundler (like [Browserify](http://browserify.org/) or [webpack](https://webpack.js.org/)), you can import the Appwrite module when you need it:
```js
import * as Appwrite from "appwrite";
```
### CDN
To install with a CDN (content delivery network) add the following scripts to the bottom of your <body> tag, but before you use any Appwrite services:
```html
<script src="https://cdn.jsdelivr.net/npm/appwrite@1.0.0"></script>
```
## License
Please see the [BSD-3-Clause license](https://raw.githubusercontent.com/appwrite/appwrite/master/LICENSE) file for more information.

View file

@ -0,0 +1,10 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let result = sdk.account.createOAuth2Session('bitbucket', 'https://example.com', 'https://example.com');
console.log(result); // Resource URL

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.account.createRecovery('email@example.com', 'https://example.com');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.account.createSession('email@example.com', 'password');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.account.createVerification('https://example.com');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.account.create('email@example.com', 'password');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.account.deleteSession('[SESSION_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.account.deleteSessions();
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.account.delete();
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.account.getLogs();
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.account.getPrefs();
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.account.getSessions();
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.account.get();
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.account.updateEmail('email@example.com', 'password');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.account.updateName('[NAME]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.account.updatePassword('password', 'password');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.account.updatePrefs({});
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.account.updateRecovery('[USER_ID]', '[SECRET]', 'password', 'password');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.account.updateVerification('[USER_ID]', '[SECRET]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.avatars.getBrowser('aa');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.avatars.getCreditCard('amex');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.avatars.getFavicon('https://example.com');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.avatars.getFlag('af');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.avatars.getImage('https://example.com');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.avatars.getQR('[TEXT]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.database.createCollection('[NAME]', [], [], []);
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.database.createDocument('[COLLECTION_ID]', {}, [], []);
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.database.deleteCollection('[COLLECTION_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.database.deleteDocument('[COLLECTION_ID]', '[DOCUMENT_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.database.getCollection('[COLLECTION_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.database.getDocument('[COLLECTION_ID]', '[DOCUMENT_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.database.listCollections();
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.database.listDocuments('[COLLECTION_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.database.updateCollection('[COLLECTION_ID]', '[NAME]', [], []);
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.database.updateDocument('[COLLECTION_ID]', '[DOCUMENT_ID]', {}, [], []);
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.locale.getContinents();
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.locale.getCountriesEU();
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.locale.getCountriesPhones();
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.locale.getCountries();
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.locale.getCurrencies();
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.locale.get();
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.createDomain('[PROJECT_ID]', '');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.createKey('[PROJECT_ID]', '[NAME]', []);
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.createPlatform('[PROJECT_ID]', 'web', '[NAME]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.createTask('[PROJECT_ID]', '[NAME]', 'play', '', 0, 'GET', 'https://example.com');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.createWebhook('[PROJECT_ID]', '[NAME]', [], '[URL]', 0);
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.create('[NAME]', '[TEAM_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.deleteDomain('[PROJECT_ID]', '[DOMAIN_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.deleteKey('[PROJECT_ID]', '[KEY_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.deletePlatform('[PROJECT_ID]', '[PLATFORM_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.deleteTask('[PROJECT_ID]', '[TASK_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.deleteWebhook('[PROJECT_ID]', '[WEBHOOK_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.delete('[PROJECT_ID]', '[PASSWORD]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.getDomain('[PROJECT_ID]', '[DOMAIN_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.getKey('[PROJECT_ID]', '[KEY_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.getPlatform('[PROJECT_ID]', '[PLATFORM_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.getTask('[PROJECT_ID]', '[TASK_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.getUsage('[PROJECT_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.getWebhook('[PROJECT_ID]', '[WEBHOOK_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.get('[PROJECT_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.listDomains('[PROJECT_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.listKeys('[PROJECT_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.listPlatforms('[PROJECT_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.listTasks('[PROJECT_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.listWebhooks('[PROJECT_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.list();
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.updateDomainVerification('[PROJECT_ID]', '[DOMAIN_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.updateKey('[PROJECT_ID]', '[KEY_ID]', '[NAME]', []);
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.updateOAuth2('[PROJECT_ID]', 'bitbucket');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.updatePlatform('[PROJECT_ID]', '[PLATFORM_ID]', '[NAME]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.updateTask('[PROJECT_ID]', '[TASK_ID]', '[NAME]', 'play', '', 0, 'GET', 'https://example.com');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.updateWebhook('[PROJECT_ID]', '[WEBHOOK_ID]', '[NAME]', [], '[URL]', 0);
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.update('[PROJECT_ID]', '[NAME]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.storage.createFile(document.getElementById('uploader').files[0], [], []);
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.storage.deleteFile('[FILE_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -0,0 +1,10 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let result = sdk.storage.getFileDownload('[FILE_ID]');
console.log(result); // Resource URL

View file

@ -0,0 +1,10 @@
let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let result = sdk.storage.getFilePreview('[FILE_ID]');
console.log(result); // Resource URL

View file

@ -2,8 +2,9 @@ let sdk = new Appwrite();
sdk
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let result = sdk.account.createOAuthSession('bitbucket', 'https://example.com', 'https://example.com');
let result = sdk.storage.getFileView('[FILE_ID]');
console.log(result); // Resource URL

Some files were not shown because too many files have changed in this diff Show more