Merge branch '0.8.x' into feat-update-team-membership-password
This commit is contained in:
commit
5c4ee95d23
3
.env
3
.env
|
@ -1,6 +1,9 @@
|
|||
_APP_ENV=production
|
||||
_APP_ENV=development
|
||||
_APP_LOCALE=en
|
||||
_APP_CONSOLE_WHITELIST_ROOT=disabled
|
||||
_APP_CONSOLE_WHITELIST_EMAILS=
|
||||
_APP_CONSOLE_WHITELIST_IPS=
|
||||
_APP_SYSTEM_EMAIL_NAME=Appwrite
|
||||
_APP_SYSTEM_EMAIL_ADDRESS=team@appwrite.io
|
||||
_APP_SYSTEM_SECURITY_EMAIL_ADDRESS=security@appwrite.io
|
||||
|
|
52
CHANGES.md
52
CHANGES.md
|
@ -1,45 +1,49 @@
|
|||
# Version 0.8.0 (Not Released Yet)
|
||||
|
||||
## Features
|
||||
|
||||
- Refactoring SSL generation to work on every request so no domain environment variable is required for SSL generation (#1133)
|
||||
- Added Anonymous Login ([RFC-010](https://github.com/appwrite/rfc/blob/main/010-anonymous-login.md), #914)
|
||||
- Added events for functions and executions (#971)
|
||||
- Added JWT support
|
||||
- Added ARM support
|
||||
- Splitted token & session models to become 2 different internal entities (#922)
|
||||
- Added JWT support (#784)
|
||||
- Added ARM support (#726)
|
||||
- Split token & session models to become 2 different internal entities (#922)
|
||||
- Added Dart 2.12 as a new Cloud Functions runtime (#989)
|
||||
- Added option to disable email/password
|
||||
- Added option to disable anonymous login (need to merge and apply changed)
|
||||
- Added option to disable JWT auth
|
||||
- Added option to disable team invites
|
||||
- Option to limit number of users (good for app launches + god account PR)
|
||||
- Added 2 new endpoints to the projects API to allow new settings
|
||||
- Added option to disable email/password (#947)
|
||||
- Added option to disable anonymous login (need to merge and apply changed) (#947)
|
||||
- Added option to disable JWT auth (#947)
|
||||
- Added option to disable team invites (#947)
|
||||
- Option to limit number of users (good for app launches + root account PR) (#947)
|
||||
- Added 2 new endpoints to the projects API to allow new settings
|
||||
- Enabled 501 errors (Not Implemented) from the error handler
|
||||
- Added Python 3.9 as a new Cloud Functions runtime
|
||||
- Added Python 3.9 as a new Cloud Functions runtime (#1044)
|
||||
- Added Deno 1.8 as a new Cloud Functions runtime (#989)
|
||||
- Upgraded to PHP 8.0 (#713)
|
||||
- ClamAV is now disabled by default to allow lower min requirments for Appwrite (#1064)
|
||||
- ClamAV is now disabled by default to allow lower min requirements for Appwrite (#1064)
|
||||
- Added a new env var named `_APP_LOCALE` that allow to change the default `en` locale value (#1056)
|
||||
- Updated all the console bottom control to be consistent. Dropped the `+` icon (#1062)
|
||||
- Added Response Models for Documents and Preferences
|
||||
- Added Response Models for Documents and Preferences (#1075, #1102)
|
||||
|
||||
## Bugs
|
||||
|
||||
- Fixed default value for HTTPS force option
|
||||
- Fixed form array casting in dashboard
|
||||
- Fixed collection document rule form in dashboard
|
||||
- Fixed form array casting in dashboard (#1070)
|
||||
- Fixed collection document rule form in dashboard (#1069)
|
||||
- Bugs in the Teams API:
|
||||
- Fixed incorrect audit worker event names (#1143)
|
||||
- Increased limit of memberships fetched in `createTeamMembership` to 2000 (#1143)
|
||||
|
||||
## Breaking Changes (Read before upgrading!)
|
||||
|
||||
- Rename `deleteuser` to `delete` on Users Api
|
||||
- Environment variable `_APP_FUNCTIONS_ENVS` renamed to `_APP_FUNCTIONS_RUNTIMES`
|
||||
- Only logged in users can execute functions (for guests, use anonymous login)
|
||||
- Only the user who has triggered the execution get access to the relevant execution logs
|
||||
- Function execution environment variable `APPWRITE_FUNCTION_EVENT_PAYLOAD` renamed to `APPWRITE_FUNCTION_EVENT_DATA`
|
||||
- Function execution environment variable `APPWRITE_FUNCTION_ENV_NAME` renamed to `APPWRITE_FUNCTION_RUNTIME_NAME`
|
||||
- Function execution environment variable `APPWRITE_FUNCTION_ENV_VERSION` renamed to `APPWRITE_FUNCTION_RUNTIME_VERSION`
|
||||
- Introdcues rate limits for:
|
||||
- Team invite (10 requests in every 60 minutes per IP address)
|
||||
- Rename `deleteuser` to `delete` on Users Api (#1089)
|
||||
- Environment variable `_APP_FUNCTIONS_ENVS` renamed to `_APP_FUNCTIONS_RUNTIMES` (#1101)
|
||||
- Only logged in users can execute functions (for guests, use anonymous login) (#976)
|
||||
- Only the user who has triggered the execution get access to the relevant execution logs (#1045)
|
||||
- Function execution environment variable `APPWRITE_FUNCTION_EVENT_PAYLOAD` renamed to `APPWRITE_FUNCTION_EVENT_DATA` (#1045)
|
||||
- Function execution environment variable `APPWRITE_FUNCTION_ENV_NAME` renamed to `APPWRITE_FUNCTION_RUNTIME_NAME` (#1101)
|
||||
- Function execution environment variable `APPWRITE_FUNCTION_ENV_VERSION` renamed to `APPWRITE_FUNCTION_RUNTIME_VERSION` (#1101)
|
||||
- Introduces rate limits for:
|
||||
- Team invite (10 requests in every 60 minutes per IP address) (#1088)
|
||||
- Rename param `inviteId` to the more accurate `membershipId` in the Teams API (#1129)
|
||||
|
||||
# Version 0.7.2
|
||||
|
||||
|
|
|
@ -88,6 +88,13 @@ ENV _APP_SERVER=swoole \
|
|||
_APP_DOMAIN_TARGET=localhost \
|
||||
_APP_HOME=https://appwrite.io \
|
||||
_APP_EDITION=community \
|
||||
_APP_CONSOLE_WHITELIST_ROOT=enabled \
|
||||
_APP_CONSOLE_WHITELIST_EMAILS= \
|
||||
_APP_CONSOLE_WHITELIST_IPS= \
|
||||
_APP_SYSTEM_EMAIL_NAME= \
|
||||
_APP_SYSTEM_EMAIL_ADDRESS= \
|
||||
_APP_SYSTEM_RESPONSE_FORMAT= \
|
||||
_APP_SYSTEM_SECURITY_EMAIL_ADDRESS= \
|
||||
_APP_OPTIONS_ABUSE=enabled \
|
||||
_APP_OPTIONS_FORCE_HTTPS=disabled \
|
||||
_APP_OPENSSL_KEY_V1=your-secret-key \
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
<br />
|
||||
<p align="center">
|
||||
<a href="https://appwrite.io" target="_blank"><img width="260" height="39" src="https://appwrite.io/images/github-logo.png" alt="Appwrite Logo"></a>
|
||||
<br />
|
||||
|
|
|
@ -46,7 +46,7 @@ $collections = [
|
|||
'legalTaxId' => '',
|
||||
'authWhitelistEmails' => (!empty(App::getEnv('_APP_CONSOLE_WHITELIST_EMAILS', null))) ? \explode(',', App::getEnv('_APP_CONSOLE_WHITELIST_EMAILS', null)) : [],
|
||||
'authWhitelistIPs' => (!empty(App::getEnv('_APP_CONSOLE_WHITELIST_IPS', null))) ? \explode(',', App::getEnv('_APP_CONSOLE_WHITELIST_IPS', null)) : [],
|
||||
'authWhitelistDomains' => (!empty(App::getEnv('_APP_CONSOLE_WHITELIST_DOMAINS', null))) ? \explode(',', App::getEnv('_APP_CONSOLE_WHITELIST_DOMAINS', null)) : [],
|
||||
'usersAuthLimit' => (App::getEnv('_APP_CONSOLE_WHITELIST_ROOT', 'enabled') === 'enabled') ? 1 : 0, // limit signup to 1 user
|
||||
],
|
||||
Database::SYSTEM_COLLECTION_COLLECTIONS => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
|
|
|
@ -28,11 +28,41 @@ return [
|
|||
'gitUrl' => 'git@github.com:appwrite/sdk-for-web.git',
|
||||
'gitRepoName' => 'sdk-for-web',
|
||||
'gitUserName' => 'appwrite',
|
||||
'demos' => [
|
||||
[
|
||||
'icon' => 'react.svg',
|
||||
'name' => 'Todo App with React JS',
|
||||
'description' => 'A simple Todo app that uses both the Appwrite account and database APIs.',
|
||||
'source' => 'https://github.com/appwrite/todo-with-react',
|
||||
'url' => 'https://appwrite-todo-with-react.vercel.app/',
|
||||
],
|
||||
[
|
||||
'icon' => 'vue.svg',
|
||||
'name' => 'Todo App with Vue JS',
|
||||
'description' => 'A simple Todo app that uses both the Appwrite account and database APIs.',
|
||||
'source' => 'https://github.com/appwrite/todo-with-vue',
|
||||
'url' => 'https://appwrite-todo-with-vue.vercel.app/',
|
||||
],
|
||||
[
|
||||
'icon' => 'angular.svg',
|
||||
'name' => 'Todo App with Angular.js',
|
||||
'description' => 'A simple Todo app that uses both the Appwrite account and database APIs.',
|
||||
'source' => 'https://github.com/appwrite/todo-with-angular',
|
||||
'url' => 'https://appwrite-todo-with-angular.vercel.app/',
|
||||
],
|
||||
[
|
||||
'icon' => 'svelte.svg',
|
||||
'name' => 'Todo App with Svelte',
|
||||
'description' => 'A simple Todo app that uses both the Appwrite account and database APIs.',
|
||||
'source' => 'https://github.com/appwrite/todo-with-svelte',
|
||||
'url' => 'https://appwrite-todo-with-svelte.vercel.app/',
|
||||
],
|
||||
]
|
||||
],
|
||||
[
|
||||
'key' => 'flutter',
|
||||
'name' => 'Flutter',
|
||||
'version' => '0.4.0',
|
||||
'version' => '0.5.0-dev.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-flutter',
|
||||
'package' => 'https://pub.dev/packages/appwrite',
|
||||
'enabled' => true,
|
||||
|
@ -148,7 +178,7 @@ return [
|
|||
[
|
||||
'key' => 'nodejs',
|
||||
'name' => 'Node.js',
|
||||
'version' => '2.0.0',
|
||||
'version' => '2.1.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-node',
|
||||
'package' => 'https://www.npmjs.com/package/node-appwrite',
|
||||
'enabled' => true,
|
||||
|
@ -267,7 +297,7 @@ return [
|
|||
[
|
||||
'key' => 'dotnet',
|
||||
'name' => '.NET',
|
||||
'version' => '0.1.0',
|
||||
'version' => '0.2.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-dotnet',
|
||||
'package' => 'https://www.nuget.org/packages/Appwrite',
|
||||
'enabled' => true,
|
||||
|
@ -284,7 +314,7 @@ return [
|
|||
[
|
||||
'key' => 'dart',
|
||||
'name' => 'Dart',
|
||||
'version' => '0.4.0',
|
||||
'version' => '0.5.0-dev.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-dart',
|
||||
'package' => 'https://pub.dev/packages/dart_appwrite',
|
||||
'enabled' => true,
|
||||
|
@ -301,7 +331,7 @@ return [
|
|||
[
|
||||
'key' => 'cli',
|
||||
'name' => 'Command Line',
|
||||
'version' => '0.6.0',
|
||||
'version' => '0.8.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-cli',
|
||||
'package' => 'https://github.com/appwrite/sdk-for-cli',
|
||||
'enabled' => true,
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -63,9 +63,17 @@ return [
|
|||
'required' => true,
|
||||
'question' => 'Enter a DNS A record hostname to serve as a CNAME for your custom domains.\nYou can use the same value as used for the Appwrite hostname.',
|
||||
],
|
||||
[
|
||||
'name' => '_APP_CONSOLE_WHITELIST_ROOT',
|
||||
'description' => 'This option allows you to disable the creation of new users on the Appwrite console. When enabled only 1 user will be able to use the registration form. New users can be added by invting them to your project. By default this option is enabled.',
|
||||
'introduction' => '0.8.0',
|
||||
'default' => 'enabled',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
],
|
||||
[
|
||||
'name' => '_APP_CONSOLE_WHITELIST_EMAILS',
|
||||
'description' => 'This option allows you to limit creation of users to Appwrite console. This option is very useful for small teams or sole developers. To enable it, pass a list of allowed email addresses separated by a comma.',
|
||||
'description' => 'This option allows you to limit creation of new users on the Appwrite console. This option is very useful for small teams or sole developers. To enable it, pass a list of allowed email addresses separated by a comma.',
|
||||
'introduction' => '',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
|
|
|
@ -61,7 +61,6 @@ App::post('/v1/account')
|
|||
if ('console' === $project->getId()) {
|
||||
$whitlistEmails = $project->getAttribute('authWhitelistEmails');
|
||||
$whitlistIPs = $project->getAttribute('authWhitelistIPs');
|
||||
$whitlistDomains = $project->getAttribute('authWhitelistDomains');
|
||||
|
||||
if (!empty($whitlistEmails) && !\in_array($email, $whitlistEmails)) {
|
||||
throw new Exception('Console registration is restricted to specific emails. Contact your administrator for more information.', 401);
|
||||
|
@ -70,10 +69,6 @@ App::post('/v1/account')
|
|||
if (!empty($whitlistIPs) && !\in_array($request->getIP(), $whitlistIPs)) {
|
||||
throw new Exception('Console registration is restricted to specific IPs. Contact your administrator for more information.', 401);
|
||||
}
|
||||
|
||||
if (!empty($whitlistDomains) && !\in_array(\substr(\strrchr($email, '@'), 1), $whitlistDomains)) {
|
||||
throw new Exception('Console registration is restricted to specific domains. Contact your administrator for more information.', 401);
|
||||
}
|
||||
}
|
||||
|
||||
$limit = $project->getAttribute('usersAuthLimit', 0);
|
||||
|
|
|
@ -272,7 +272,7 @@ App::get('/v1/health/anti-virus')
|
|||
App::get('/v1/health/stats') // Currently only used internally
|
||||
->desc('Get System Stats')
|
||||
->groups(['api', 'health'])
|
||||
->label('scope', 'god')
|
||||
->label('scope', 'root')
|
||||
// ->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
// ->label('sdk.namespace', 'health')
|
||||
// ->label('sdk.method', 'getStats')
|
||||
|
|
|
@ -612,7 +612,7 @@ App::delete('/v1/storage/files/:fileId')
|
|||
// App::get('/v1/storage/files/:fileId/scan')
|
||||
// ->desc('Scan Storage')
|
||||
// ->groups(['api', 'storage'])
|
||||
// ->label('scope', 'god')
|
||||
// ->label('scope', 'root')
|
||||
// ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
// ->label('sdk.namespace', 'storage')
|
||||
// ->label('sdk.method', 'getFileScan')
|
||||
|
|
|
@ -294,7 +294,7 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
}
|
||||
|
||||
$memberships = $projectDB->getCollection([
|
||||
'limit' => 50,
|
||||
'limit' => 2000,
|
||||
'offset' => 0,
|
||||
'filters' => [
|
||||
'$collection='.Database::SYSTEM_COLLECTION_MEMBERSHIPS,
|
||||
|
@ -424,7 +424,7 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
}
|
||||
|
||||
$url = Template::parseURL($url);
|
||||
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['inviteId' => $membership->getId(), 'teamId' => $team->getId(), 'userId' => $invitee->getId(), 'secret' => $secret, 'teamId' => $teamId]);
|
||||
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['membershipId' => $membership->getId(), 'teamId' => $team->getId(), 'userId' => $invitee->getId(), 'secret' => $secret, 'teamId' => $teamId]);
|
||||
$url = Template::unParseURL($url);
|
||||
|
||||
$body = new Template(__DIR__.'/../../config/locale/templates/email-base.tpl');
|
||||
|
@ -451,7 +451,7 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
|
||||
if (!$isPrivilegedUser && !$isAppUser) { // No need in comfirmation when in admin or app mode
|
||||
$mails
|
||||
->setParam('event', 'teams.membership.create')
|
||||
->setParam('event', 'teams.memberships.create')
|
||||
->setParam('from', ($project->getId() === 'console') ? '' : \sprintf($locale->getText('account.emails.team'), $project->getAttribute('name')))
|
||||
->setParam('recipient', $email)
|
||||
->setParam('name', $name)
|
||||
|
@ -463,7 +463,7 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
|
||||
$audits
|
||||
->setParam('userId', $invitee->getId())
|
||||
->setParam('event', 'teams.membership.create')
|
||||
->setParam('event', 'teams.memberships.create')
|
||||
->setParam('resource', 'teams/'.$teamId)
|
||||
;
|
||||
|
||||
|
@ -529,7 +529,7 @@ App::get('/v1/teams/:teamId/memberships')
|
|||
$response->dynamic(new Document(['sum' => $projectDB->getSum(), 'memberships' => $users]), Response::MODEL_MEMBERSHIP_LIST);
|
||||
});
|
||||
|
||||
App::patch('/v1/teams/:teamId/memberships/:inviteId/status')
|
||||
App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
||||
->desc('Update Team Membership Status')
|
||||
->groups(['api', 'teams'])
|
||||
->label('event', 'teams.memberships.update.status')
|
||||
|
@ -542,7 +542,7 @@ App::patch('/v1/teams/:teamId/memberships/:inviteId/status')
|
|||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MEMBERSHIP)
|
||||
->param('teamId', '', new UID(), 'Team unique ID.')
|
||||
->param('inviteId', '', new UID(), 'Invite unique ID.')
|
||||
->param('membershipId', '', new UID(), 'Membership ID.')
|
||||
->param('userId', '', new UID(), 'User unique ID.')
|
||||
->param('secret', '', new Text(256), 'Secret key.')
|
||||
->inject('request')
|
||||
|
@ -551,7 +551,7 @@ App::patch('/v1/teams/:teamId/memberships/:inviteId/status')
|
|||
->inject('projectDB')
|
||||
->inject('geodb')
|
||||
->inject('audits')
|
||||
->action(function ($teamId, $inviteId, $userId, $secret, $request, $response, $user, $projectDB, $geodb, $audits) {
|
||||
->action(function ($teamId, $membershipId, $userId, $secret, $request, $response, $user, $projectDB, $geodb, $audits) {
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
|
@ -560,7 +560,7 @@ App::patch('/v1/teams/:teamId/memberships/:inviteId/status')
|
|||
/** @var Appwrite\Event\Event $audits */
|
||||
|
||||
$protocol = $request->getProtocol();
|
||||
$membership = $projectDB->getDocument($inviteId);
|
||||
$membership = $projectDB->getDocument($membershipId);
|
||||
|
||||
if (empty($membership->getId()) || Database::SYSTEM_COLLECTION_MEMBERSHIPS != $membership->getCollection()) {
|
||||
throw new Exception('Invite not found', 404);
|
||||
|
@ -655,7 +655,7 @@ App::patch('/v1/teams/:teamId/memberships/:inviteId/status')
|
|||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('event', 'teams.membership.update')
|
||||
->setParam('event', 'teams.memberships.update.status')
|
||||
->setParam('resource', 'teams/'.$teamId)
|
||||
;
|
||||
|
||||
|
@ -676,7 +676,7 @@ App::patch('/v1/teams/:teamId/memberships/:inviteId/status')
|
|||
])), Response::MODEL_MEMBERSHIP);
|
||||
});
|
||||
|
||||
App::delete('/v1/teams/:teamId/memberships/:inviteId')
|
||||
App::delete('/v1/teams/:teamId/memberships/:membershipId')
|
||||
->desc('Delete Team Membership')
|
||||
->groups(['api', 'teams'])
|
||||
->label('event', 'teams.memberships.delete')
|
||||
|
@ -688,18 +688,18 @@ App::delete('/v1/teams/:teamId/memberships/:inviteId')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
|
||||
->label('sdk.response.model', Response::MODEL_NONE)
|
||||
->param('teamId', '', new UID(), 'Team unique ID.')
|
||||
->param('inviteId', '', new UID(), 'Invite unique ID.')
|
||||
->param('membershipId', '', new UID(), 'Membership ID.')
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->inject('audits')
|
||||
->inject('events')
|
||||
->action(function ($teamId, $inviteId, $response, $projectDB, $audits, $events) {
|
||||
->action(function ($teamId, $membershipId, $response, $projectDB, $audits, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$membership = $projectDB->getDocument($inviteId);
|
||||
$membership = $projectDB->getDocument($membershipId);
|
||||
|
||||
if (empty($membership->getId()) || Database::SYSTEM_COLLECTION_MEMBERSHIPS != $membership->getCollection()) {
|
||||
throw new Exception('Invite not found', 404);
|
||||
|
@ -731,7 +731,7 @@ App::delete('/v1/teams/:teamId/memberships/:inviteId')
|
|||
|
||||
$audits
|
||||
->setParam('userId', $membership->getAttribute('userId'))
|
||||
->setParam('event', 'teams.membership.delete')
|
||||
->setParam('event', 'teams.memberships.delete')
|
||||
->setParam('resource', 'teams/'.$teamId)
|
||||
;
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use Utopia\App;
|
||||
use Utopia\Exception;
|
||||
use Utopia\Validator;
|
||||
use Utopia\Validator\Assoc;
|
||||
use Utopia\Validator\WhiteList;
|
||||
use Appwrite\Network\Validator\Email;
|
||||
|
@ -343,7 +344,7 @@ App::patch('/v1/users/:userId/status')
|
|||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_USER)
|
||||
->param('userId', '', new UID(), 'User unique ID.')
|
||||
->param('status', '', new WhiteList([Auth::USER_STATUS_ACTIVATED, Auth::USER_STATUS_BLOCKED, Auth::USER_STATUS_UNACTIVATED], true), 'User Status code. To activate the user pass '.Auth::USER_STATUS_ACTIVATED.', to block the user pass '.Auth::USER_STATUS_BLOCKED.' and for disabling the user pass '.Auth::USER_STATUS_UNACTIVATED)
|
||||
->param('status', '', new WhiteList([Auth::USER_STATUS_ACTIVATED, Auth::USER_STATUS_BLOCKED, Auth::USER_STATUS_UNACTIVATED], true, Validator::TYPE_INTEGER), 'User Status code. To activate the user pass '.Auth::USER_STATUS_ACTIVATED.', to block the user pass '.Auth::USER_STATUS_BLOCKED.' and for disabling the user pass '.Auth::USER_STATUS_UNACTIVATED)
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->action(function ($userId, $status, $response, $projectDB) {
|
||||
|
|
|
@ -14,8 +14,6 @@ use Appwrite\Database\Database;
|
|||
use Appwrite\Database\Document;
|
||||
use Appwrite\Database\Validator\Authorization;
|
||||
use Appwrite\Network\Validator\Origin;
|
||||
use Utopia\Storage\Device\Local;
|
||||
use Utopia\Storage\Storage;
|
||||
use Appwrite\Utopia\Response\Filters\V06;
|
||||
use Utopia\CLI\Console;
|
||||
|
||||
|
@ -23,15 +21,61 @@ Config::setParam('domainVerification', false);
|
|||
Config::setParam('cookieDomain', 'localhost');
|
||||
Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE);
|
||||
|
||||
App::init(function ($utopia, $request, $response, $console, $project, $user, $locale, $clients) {
|
||||
App::init(function ($utopia, $request, $response, $console, $project, $consoleDB, $user, $locale, $clients) {
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $consoleDB */
|
||||
/** @var Appwrite\Database\Document $console */
|
||||
/** @var Appwrite\Database\Document $project */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
/** @var bool $mode */
|
||||
/** @var array $clients */
|
||||
|
||||
$domain = $request->getHostname();
|
||||
$domains = Config::getParam('domains', []);
|
||||
if (!array_key_exists($domain, $domains)) {
|
||||
$domain = new Domain(!empty($domain) ? $domain : '');
|
||||
|
||||
if (empty($domain->get()) || !$domain->isKnown() || $domain->isTest()) {
|
||||
$domains[$domain->get()] = false;
|
||||
Console::warning($domain->get() . ' is not a publicly accessible domain. Skipping SSL certificate generation.');
|
||||
} else {
|
||||
Authorization::disable();
|
||||
$dbDomain = $consoleDB->getCollectionFirst([
|
||||
'limit' => 1,
|
||||
'offset' => 0,
|
||||
'filters' => [
|
||||
'$collection=' . Database::SYSTEM_COLLECTION_CERTIFICATES,
|
||||
'domain=' . $domain->get(),
|
||||
],
|
||||
]);
|
||||
|
||||
if (empty($dbDomain)) {
|
||||
$dbDomain = [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_CERTIFICATES,
|
||||
'$permissions' => [
|
||||
'read' => [],
|
||||
'write' => [],
|
||||
],
|
||||
'domain' => $domain->get(),
|
||||
];
|
||||
$dbDomain = $consoleDB->createDocument($dbDomain);
|
||||
Authorization::enable();
|
||||
|
||||
Console::info('Issuing a TLS certificate for the master domain (' . $domain->get() . ') in ~30 seconds..'); // TODO move this to installation script
|
||||
|
||||
ResqueScheduler::enqueueAt(\time() + 30, 'v1-certificates', 'CertificatesV1', [
|
||||
'document' => $dbDomain,
|
||||
'domain' => $domain->get(),
|
||||
'validateTarget' => false,
|
||||
'validateCNAME' => false,
|
||||
]);
|
||||
}
|
||||
$domains[$domain->get()] = true;
|
||||
}
|
||||
Config::setParam('domains', $domains);
|
||||
}
|
||||
|
||||
$localeParam = (string)$request->getParam('locale', $request->getHeader('x-appwrite-locale', ''));
|
||||
|
||||
|
@ -208,7 +252,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $user, $lo
|
|||
}
|
||||
}, $user->getAttribute('memberships', []));
|
||||
|
||||
// TDOO Check if user is god
|
||||
// TDOO Check if user is root
|
||||
|
||||
if (!\in_array($scope, $scopes)) {
|
||||
if (empty($project->getId()) || Database::SYSTEM_COLLECTION_PROJECTS !== $project->getCollection()) { // Check if permission is denied because project is missing
|
||||
|
@ -226,7 +270,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $user, $lo
|
|||
throw new Exception('Password reset is required', 412);
|
||||
}
|
||||
|
||||
}, ['utopia', 'request', 'response', 'console', 'project', 'user', 'locale', 'clients']);
|
||||
}, ['utopia', 'request', 'response', 'console', 'project', 'consoleDB', 'user', 'locale', 'clients']);
|
||||
|
||||
App::options(function ($request, $response) {
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
|
@ -424,4 +468,4 @@ include_once __DIR__ . '/shared/web.php';
|
|||
|
||||
foreach (Config::getParam('services', []) as $service) {
|
||||
include_once $service['controller'];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
global $utopia, $request, $response;
|
||||
|
||||
use Appwrite\Database\Document;
|
||||
use Appwrite\Network\Validator\Host;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Validator\Numeric;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\Host;
|
||||
use Utopia\Storage\Validator\File;
|
||||
|
||||
App::get('/v1/mock/tests/foo')
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
|
||||
use Appwrite\Database\Database;
|
||||
use Appwrite\Specification\Format\OpenAPI3;
|
||||
use Appwrite\Specification\Format\Swagger2;
|
||||
use Appwrite\Specification\Specification;
|
||||
|
@ -42,10 +43,38 @@ App::get('/')
|
|||
->label('permission', 'public')
|
||||
->label('scope', 'home')
|
||||
->inject('response')
|
||||
->action(function ($response) {
|
||||
->inject('consoleDB')
|
||||
->inject('project')
|
||||
->action(function ($response, $consoleDB, $project) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $consoleDB */
|
||||
/** @var Appwrite\Database\Document $project */
|
||||
|
||||
$response->redirect('/auth/signin');
|
||||
$response
|
||||
->addHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
|
||||
->addHeader('Expires', 0)
|
||||
->addHeader('Pragma', 'no-cache')
|
||||
;
|
||||
|
||||
if ('console' === $project->getId() || $project->isEmpty()) {
|
||||
$whitlistRoot = App::getEnv('_APP_CONSOLE_WHITELIST_ROOT', 'enabled');
|
||||
|
||||
if($whitlistRoot !== 'disabled') {
|
||||
$consoleDB->getCollection([ // Count users
|
||||
'filters' => [
|
||||
'$collection='.Database::SYSTEM_COLLECTION_USERS,
|
||||
],
|
||||
]);
|
||||
|
||||
$sum = $consoleDB->getSum();
|
||||
|
||||
if($sum !== 0) {
|
||||
return $response->redirect('/auth/signin');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$response->redirect('/auth/signup');
|
||||
});
|
||||
|
||||
App::get('/auth/signin')
|
||||
|
@ -58,6 +87,10 @@ App::get('/auth/signin')
|
|||
|
||||
$page = new View(__DIR__.'/../../views/home/auth/signin.phtml');
|
||||
|
||||
$page
|
||||
->setParam('root', App::getEnv('_APP_CONSOLE_WHITELIST_ROOT', 'enabled'))
|
||||
;
|
||||
|
||||
$layout
|
||||
->setParam('title', 'Sign In - '.APP_NAME)
|
||||
->setParam('body', $page);
|
||||
|
@ -72,6 +105,10 @@ App::get('/auth/signup')
|
|||
/** @var Utopia\View $layout */
|
||||
$page = new View(__DIR__.'/../../views/home/auth/signup.phtml');
|
||||
|
||||
$page
|
||||
->setParam('root', App::getEnv('_APP_CONSOLE_WHITELIST_ROOT', 'enabled'))
|
||||
;
|
||||
|
||||
$layout
|
||||
->setParam('title', 'Sign Up - '.APP_NAME)
|
||||
->setParam('body', $page);
|
||||
|
@ -87,6 +124,10 @@ App::get('/auth/recovery')
|
|||
|
||||
$page = new View(__DIR__.'/../../views/home/auth/recovery.phtml');
|
||||
|
||||
$page
|
||||
->setParam('smtpEnabled', (!empty(App::getEnv('_APP_SMTP_HOST'))))
|
||||
;
|
||||
|
||||
$layout
|
||||
->setParam('title', 'Password Recovery - '.APP_NAME)
|
||||
->setParam('body', $page);
|
||||
|
|
14
app/http.php
14
app/http.php
|
@ -12,6 +12,8 @@ use Swoole\Http\Request as SwooleRequest;
|
|||
use Swoole\Http\Response as SwooleResponse;
|
||||
use Utopia\App;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Domains\Domain;
|
||||
|
||||
// xdebug_start_trace('/tmp/trace');
|
||||
|
||||
|
@ -65,18 +67,6 @@ Files::load(__DIR__ . '/../public');
|
|||
|
||||
include __DIR__ . '/controllers/general.php';
|
||||
|
||||
$domain = App::getEnv('_APP_DOMAIN', '');
|
||||
|
||||
Console::info('Issuing a TLS certificate for the master domain ('.$domain.') in 30 seconds.
|
||||
Make sure your domain points to your server IP or restart your Appwrite server to try again.'); // TODO move this to installation script
|
||||
|
||||
ResqueScheduler::enqueueAt(\time() + 30, 'v1-certificates', 'CertificatesV1', [
|
||||
'document' => [],
|
||||
'domain' => $domain,
|
||||
'validateTarget' => false,
|
||||
'validateCNAME' => false,
|
||||
]);
|
||||
|
||||
$http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swooleResponse) {
|
||||
$request = new Request($swooleRequest);
|
||||
$response = new Response($swooleResponse);
|
||||
|
|
|
@ -53,6 +53,7 @@ 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://appwrite.io/discord';
|
||||
const APP_SOCIAL_DISCORD_CHANNEL = '564160730845151244';
|
||||
const APP_SOCIAL_DEV = 'https://dev.to/appwrite';
|
||||
const APP_SOCIAL_STACKSHARE = 'https://stackshare.io/appwrite';
|
||||
// Deletion Types
|
||||
|
|
|
@ -61,12 +61,12 @@ $cli
|
|||
Console::log('🟢 Abuse protection is enabled');
|
||||
}
|
||||
|
||||
$authWhitelistRoot = App::getEnv('_APP_CONSOLE_WHITELIST_ROOT', null);
|
||||
$authWhitelistEmails = App::getEnv('_APP_CONSOLE_WHITELIST_EMAILS', null);
|
||||
$authWhitelistIPs = App::getEnv('_APP_CONSOLE_WHITELIST_IPS', null);
|
||||
$authWhitelistDomains = App::getEnv('_APP_CONSOLE_WHITELIST_DOMAINS', null);
|
||||
|
||||
if(empty($authWhitelistEmails)
|
||||
&& empty($authWhitelistDomains)
|
||||
if(empty($authWhitelistRoot)
|
||||
&& empty($authWhitelistEmails)
|
||||
&& empty($authWhitelistIPs)
|
||||
) {
|
||||
Console::log('🔴 Console access limits are disabled');
|
||||
|
|
|
@ -143,8 +143,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|||
case 'dart':
|
||||
$config = new Dart();
|
||||
$config->setPackageName('dart_appwrite');
|
||||
$warning = $warning."\n\n > This is the Dart SDK for integrating with Appwrite from your Dart server-side code.
|
||||
If you're looking for the Flutter SDK you should check [appwrite/sdk-for-flutter](https://github.com/appwrite/sdk-for-flutter)";
|
||||
$warning = $warning."\n\n > This is the Dart SDK for integrating with Appwrite from your Dart server-side code. If you're looking for the Flutter SDK you should check [appwrite/sdk-for-flutter](https://github.com/appwrite/sdk-for-flutter)";
|
||||
break;
|
||||
case 'go':
|
||||
$config = new Go();
|
||||
|
@ -192,6 +191,8 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|||
->setGettingStarted($gettingStarted)
|
||||
->setChangelog($changelog)
|
||||
->setExamples($examples)
|
||||
->setTwitter(APP_SOCIAL_TWITTER_HANDLE)
|
||||
->setDiscord(APP_SOCIAL_DISCORD_CHANNEL, APP_SOCIAL_DISCORD)
|
||||
;
|
||||
|
||||
try {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
$home = $this->getParam('home', '');
|
||||
$version = $this->getParam('version', '').'.'.APP_CACHE_BUSTER;
|
||||
$version = $this->getParam('version', '') . '.' . APP_CACHE_BUSTER;
|
||||
?>
|
||||
<footer class="clear margin-top-large">
|
||||
<ul class="copyright pull-start">
|
||||
|
@ -12,6 +12,14 @@ $version = $this->getParam('version', '').'.'.APP_CACHE_BUSTER;
|
|||
data-analytics-label="GitHub Link"
|
||||
href="https://github.com/appwrite/appwrite" target="_blank" rel="noopener"><i class="icon-github-circled"></i> GitHub</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="link-animation-enabled"
|
||||
data-analytics
|
||||
data-analytics-event="click"
|
||||
data-analytics-category="console/footer"
|
||||
data-analytics-label="Discord Link"
|
||||
href="https://appwrite.io/discord" target="_blank" rel="noopener"><i class="icon-discord"></i> Discord</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="link-animation-enabled"
|
||||
data-analytics
|
||||
|
|
|
@ -93,7 +93,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled',true);
|
|||
|
||||
<div class="chart-metric">
|
||||
<div class="value margin-bottom-small"><span class="sum" data-ls-bind="{{usage.requests.total|statsTotal}}">N/A</span></div>
|
||||
<div class="metric margin-bottom-small">Requests <span class="tooltip" data-tooltip="Total number of API requests last 30 days"><i class="icon-info-circled"></i></span></div>
|
||||
<div class="metric margin-bottom-small">Requests <span class="tooltip" data-tooltip="Total number of API requests"><i class="icon-info-circled"></i></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col span-3">
|
||||
|
|
|
@ -415,7 +415,7 @@ $smtpEnabled = $this->getParam('smtpEnabled', false);
|
|||
data-failure-param-alert-classname="error">
|
||||
|
||||
<input name="teamId" data-ls-attrs="id=leave-teamId-{{member.$id}}" type="hidden" data-ls-bind="{{console-project.teamId}}">
|
||||
<input name="inviteId" data-ls-attrs="id=leave-inviteId-{{member.$id}}" type="hidden" data-ls-bind="{{member.$id}}">
|
||||
<input name="membershipId" data-ls-attrs="id=leave-membershipId-{{member.$id}}" type="hidden" data-ls-bind="{{member.$id}}">
|
||||
|
||||
<button class="danger">Leave</button>
|
||||
</form>
|
||||
|
@ -437,7 +437,7 @@ $smtpEnabled = $this->getParam('smtpEnabled', false);
|
|||
data-failure-param-alert-classname="error">
|
||||
|
||||
<input name="teamId" data-ls-attrs="id=resend-teamId-{{member.$id}}" type="hidden" data-ls-bind="{{console-project.teamId}}">
|
||||
<input name="inviteId" data-ls-attrs="id=resend-inviteId-{{member.$id}}" type="hidden" data-ls-bind="{{member.$id}}">
|
||||
<input name="membershipId" data-ls-attrs="id=resend-membershipId-{{member.$id}}" type="hidden" data-ls-bind="{{member.$id}}">
|
||||
|
||||
<button class="reverse">Resend</button>
|
||||
</form>
|
||||
|
|
|
@ -105,7 +105,7 @@
|
|||
data-failure-param-alert-classname="error">
|
||||
|
||||
<input name="teamId" data-ls-attrs="id={{member.$id}}" type="hidden" data-ls-bind="{{router.params.id}}">
|
||||
<input name="inviteId" data-ls-attrs="id=leave-inviteId-{{member.$id}}" type="hidden" data-ls-bind="{{member.$id}}">
|
||||
<input name="membershipId" data-ls-attrs="id=leave-membershipId-{{member.$id}}" type="hidden" data-ls-bind="{{member.$id}}">
|
||||
|
||||
<button class="danger">Remove</button>
|
||||
</form>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
data-scope="console"
|
||||
data-event="submit"
|
||||
data-param-team-id="{{router.params.teamId}}"
|
||||
data-param-invite-id="{{router.params.inviteId}}"
|
||||
data-param-invite-id="{{router.params.membershipId}}"
|
||||
data-param-user-id="{{router.params.userId}}"
|
||||
data-param-secret="{{router.params.secret}}"
|
||||
data-success="redirect,alert,trigger"
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
<?php
|
||||
$smtpEnabled = $this->getParam('smtpEnabled', false);
|
||||
?>
|
||||
<div class="zone medium">
|
||||
<h1 class="zone xl margin-bottom-large margin-top">
|
||||
Password Recovery
|
||||
|
@ -25,7 +28,13 @@
|
|||
|
||||
<input name="url" type="hidden" data-ls-bind="{{env.ENDPOINT}}/auth/recovery/reset" />
|
||||
|
||||
<button type="submit" class="btn btn-primary"><i class="fa fa-sign-in"></i> Recover</button>
|
||||
<?php if(!$smtpEnabled): ?>
|
||||
<div class="box note padding-tiny warning margin-bottom text-align-center">
|
||||
<i class="icon-warning"></i> SMTP connection is disabled. <a href="https://appwrite.io/docs/email-delivery" target="_blank" rel="noopener">Learn more <i class="icon-link-ext"></i></a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<button type="submit" class="btn btn-primary"<?php if(!$smtpEnabled): ?> disabled<?php endif; ?>><i class="fa fa-sign-in"></i> Recover</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
<?php
|
||||
$root = ($this->getParam('root') !== 'disabled');
|
||||
?>
|
||||
<div class="zone medium"
|
||||
data-service="account.get"
|
||||
data-name="account"
|
||||
|
@ -43,7 +46,7 @@
|
|||
<br />
|
||||
|
||||
<div class="text-line-high-large text-align-center">
|
||||
<a href="/auth/recovery">Forgot password?</a> or don't have an account? <b><a href="/auth/signup">Sign up now</a></b>
|
||||
<a href="/auth/recovery">Forgot password?</a><?php if(!$root): ?> or don't have an account? <b><a href="/auth/signup">Sign up now</a></b><?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
<?php
|
||||
$root = ($this->getParam('root') !== 'disabled');
|
||||
?>
|
||||
<div class="zone medium signup">
|
||||
<h1 class="zone xl margin-bottom-large margin-top">
|
||||
Sign Up
|
||||
|
@ -23,6 +26,10 @@
|
|||
data-failure-param-alert-text="Registration Failed. Please try again later"
|
||||
data-failure-param-alert-classname="error">
|
||||
|
||||
<?php if($root): ?>
|
||||
<p>Please create your root account</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<label>Name</label>
|
||||
<input name="name" type="text" autocomplete="name" placeholder="" required maxlength="128">
|
||||
|
||||
|
@ -44,6 +51,8 @@
|
|||
|
||||
</div>
|
||||
|
||||
<?php if(!$root): ?>
|
||||
<div class="zone medium text-align-center">
|
||||
<a href="/auth/signin">Already have an account?</a>
|
||||
</div>
|
||||
</div>
|
||||
<?PHP endif; ?>
|
|
@ -57,6 +57,7 @@ services:
|
|||
environment:
|
||||
- _APP_ENV
|
||||
- _APP_LOCALE
|
||||
- _APP_CONSOLE_WHITELIST_ROOT
|
||||
- _APP_CONSOLE_WHITELIST_EMAILS
|
||||
- _APP_CONSOLE_WHITELIST_IPS
|
||||
- _APP_SYSTEM_EMAIL_NAME
|
||||
|
|
|
@ -38,25 +38,25 @@
|
|||
"appwrite/php-clamav": "1.1.*",
|
||||
"appwrite/php-runtimes": "0.2.*",
|
||||
|
||||
"utopia-php/framework": "0.12.*",
|
||||
"utopia-php/framework": "0.14.*",
|
||||
"utopia-php/abuse": "0.4.*",
|
||||
"utopia-php/analytics": "0.2.*",
|
||||
"utopia-php/audit": "0.5.*",
|
||||
"utopia-php/cache": "0.2.*",
|
||||
"utopia-php/cli": "0.10.*",
|
||||
"utopia-php/cli": "0.11.*",
|
||||
"utopia-php/config": "0.2.*",
|
||||
"utopia-php/locale": "0.3.*",
|
||||
"utopia-php/registry": "0.4.*",
|
||||
"utopia-php/preloader": "0.2.*",
|
||||
"utopia-php/domains": "1.1.*",
|
||||
"utopia-php/swoole": "0.2.*",
|
||||
"utopia-php/storage": "0.4.*",
|
||||
"utopia-php/storage": "0.5.*",
|
||||
"utopia-php/image": "0.2.*",
|
||||
"resque/php-resque": "1.3.6",
|
||||
"matomo/device-detector": "4.2.2",
|
||||
"dragonmantank/cron-expression": "3.1.0",
|
||||
"influxdb/influxdb-php": "1.15.2",
|
||||
"phpmailer/phpmailer": "6.4.0",
|
||||
"phpmailer/phpmailer": "6.4.1",
|
||||
"chillerlan/php-qrcode": "4.3.0",
|
||||
"adhocore/jwt": "1.1.2",
|
||||
"slickdeals/statsd": "3.0.2"
|
||||
|
@ -65,7 +65,7 @@
|
|||
"appwrite/sdk-generator": "dev-feat-preps-for-0.8",
|
||||
"swoole/ide-helper": "4.6.6",
|
||||
"phpunit/phpunit": "9.5.4",
|
||||
"vimeo/psalm": "4.7.1"
|
||||
"vimeo/psalm": "4.7.2"
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
|
|
80
composer.lock
generated
80
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "32ceddda707fb8f625f84eec08dc3871",
|
||||
"content-hash": "407185a7ffb14acda25f4a449cdb5ffb",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
|
@ -834,16 +834,16 @@
|
|||
},
|
||||
{
|
||||
"name": "phpmailer/phpmailer",
|
||||
"version": "v6.4.0",
|
||||
"version": "v6.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPMailer/PHPMailer.git",
|
||||
"reference": "050d430203105c27c30efd1dce7aa421ad882d01"
|
||||
"reference": "9256f12d8fb0cd0500f93b19e18c356906cbed3d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/050d430203105c27c30efd1dce7aa421ad882d01",
|
||||
"reference": "050d430203105c27c30efd1dce7aa421ad882d01",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/9256f12d8fb0cd0500f93b19e18c356906cbed3d",
|
||||
"reference": "9256f12d8fb0cd0500f93b19e18c356906cbed3d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -898,7 +898,7 @@
|
|||
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
|
||||
"support": {
|
||||
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
|
||||
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.4.0"
|
||||
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.4.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -906,7 +906,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-03-31T20:06:42+00:00"
|
||||
"time": "2021-04-29T12:25:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-client",
|
||||
|
@ -1535,16 +1535,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/cli",
|
||||
"version": "0.10.0",
|
||||
"version": "0.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/cli.git",
|
||||
"reference": "69ae40187fb4b68ef14f0224a68d9cc016b83634"
|
||||
"reference": "c7a6908a8dbe9234b8b2c954e5487d34cb079af6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/cli/zipball/69ae40187fb4b68ef14f0224a68d9cc016b83634",
|
||||
"reference": "69ae40187fb4b68ef14f0224a68d9cc016b83634",
|
||||
"url": "https://api.github.com/repos/utopia-php/cli/zipball/c7a6908a8dbe9234b8b2c954e5487d34cb079af6",
|
||||
"reference": "c7a6908a8dbe9234b8b2c954e5487d34cb079af6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1582,9 +1582,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/cli/issues",
|
||||
"source": "https://github.com/utopia-php/cli/tree/0.10.0"
|
||||
"source": "https://github.com/utopia-php/cli/tree/0.11.0"
|
||||
},
|
||||
"time": "2021-01-26T16:35:15+00:00"
|
||||
"time": "2021-04-16T15:16:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/config",
|
||||
|
@ -1693,16 +1693,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/framework",
|
||||
"version": "0.12.3",
|
||||
"version": "0.14.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/framework.git",
|
||||
"reference": "78be43a0eb711f3677769dfb445e5111bfafaa88"
|
||||
"reference": "92d4a36f3b0e22393a31877c5317c96e01760339"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/framework/zipball/78be43a0eb711f3677769dfb445e5111bfafaa88",
|
||||
"reference": "78be43a0eb711f3677769dfb445e5111bfafaa88",
|
||||
"url": "https://api.github.com/repos/utopia-php/framework/zipball/92d4a36f3b0e22393a31877c5317c96e01760339",
|
||||
"reference": "92d4a36f3b0e22393a31877c5317c96e01760339",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1736,9 +1736,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/framework/issues",
|
||||
"source": "https://github.com/utopia-php/framework/tree/0.12.3"
|
||||
"source": "https://github.com/utopia-php/framework/tree/0.14.0"
|
||||
},
|
||||
"time": "2021-03-22T22:02:23+00:00"
|
||||
"time": "2021-04-15T21:01:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/image",
|
||||
|
@ -1951,16 +1951,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/storage",
|
||||
"version": "0.4.3",
|
||||
"version": "0.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/storage.git",
|
||||
"reference": "9db3ab713a6d392c3c2c799aeea751f6c8dc2ff7"
|
||||
"reference": "92ae20c7a2ac329f573a58a82dc245134cc63408"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/storage/zipball/9db3ab713a6d392c3c2c799aeea751f6c8dc2ff7",
|
||||
"reference": "9db3ab713a6d392c3c2c799aeea751f6c8dc2ff7",
|
||||
"url": "https://api.github.com/repos/utopia-php/storage/zipball/92ae20c7a2ac329f573a58a82dc245134cc63408",
|
||||
"reference": "92ae20c7a2ac329f573a58a82dc245134cc63408",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1997,9 +1997,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/storage/issues",
|
||||
"source": "https://github.com/utopia-php/storage/tree/0.4.3"
|
||||
"source": "https://github.com/utopia-php/storage/tree/0.5.0"
|
||||
},
|
||||
"time": "2021-03-02T20:25:02+00:00"
|
||||
"time": "2021-04-15T16:43:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/swoole",
|
||||
|
@ -2344,7 +2344,7 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-generator",
|
||||
"reference": "5bb8ceaf0ff9da85fcca840285d6896a7594f435"
|
||||
"reference": "a8d90fd59db39ec04914692bd6ab06e013977b77"
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
|
@ -2352,7 +2352,7 @@
|
|||
"ext-mbstring": "*",
|
||||
"matthiasmullie/minify": "^1.3",
|
||||
"php": ">=7.0.0",
|
||||
"twig/twig": "^2.12"
|
||||
"twig/twig": "^2.14"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.0"
|
||||
|
@ -2374,7 +2374,7 @@
|
|||
}
|
||||
],
|
||||
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
|
||||
"time": "2021-03-28T22:18:36+00:00"
|
||||
"time": "2021-05-05T12:50:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/package-versions-deprecated",
|
||||
|
@ -2532,16 +2532,16 @@
|
|||
},
|
||||
{
|
||||
"name": "composer/xdebug-handler",
|
||||
"version": "2.0.0",
|
||||
"version": "2.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/xdebug-handler.git",
|
||||
"reference": "31d57697eb1971712a08031cfaff5a846d10bdf5"
|
||||
"reference": "964adcdd3a28bf9ed5d9ac6450064e0d71ed7496"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/xdebug-handler/zipball/31d57697eb1971712a08031cfaff5a846d10bdf5",
|
||||
"reference": "31d57697eb1971712a08031cfaff5a846d10bdf5",
|
||||
"url": "https://api.github.com/repos/composer/xdebug-handler/zipball/964adcdd3a28bf9ed5d9ac6450064e0d71ed7496",
|
||||
"reference": "964adcdd3a28bf9ed5d9ac6450064e0d71ed7496",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2576,7 +2576,7 @@
|
|||
"support": {
|
||||
"irc": "irc://irc.freenode.org/composer",
|
||||
"issues": "https://github.com/composer/xdebug-handler/issues",
|
||||
"source": "https://github.com/composer/xdebug-handler/tree/2.0.0"
|
||||
"source": "https://github.com/composer/xdebug-handler/tree/2.0.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -2592,7 +2592,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-04-09T19:40:06+00:00"
|
||||
"time": "2021-05-05T19:37:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dnoegel/php-xdg-base-dir",
|
||||
|
@ -5768,16 +5768,16 @@
|
|||
},
|
||||
{
|
||||
"name": "vimeo/psalm",
|
||||
"version": "4.7.1",
|
||||
"version": "4.7.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/vimeo/psalm.git",
|
||||
"reference": "cd53e047a58f71f646dd6bf45476076ab07b5d44"
|
||||
"reference": "83a0325c0a95c0ab531d6b90c877068b464377b5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/vimeo/psalm/zipball/cd53e047a58f71f646dd6bf45476076ab07b5d44",
|
||||
"reference": "cd53e047a58f71f646dd6bf45476076ab07b5d44",
|
||||
"url": "https://api.github.com/repos/vimeo/psalm/zipball/83a0325c0a95c0ab531d6b90c877068b464377b5",
|
||||
"reference": "83a0325c0a95c0ab531d6b90c877068b464377b5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -5867,9 +5867,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/vimeo/psalm/issues",
|
||||
"source": "https://github.com/vimeo/psalm/tree/4.7.1"
|
||||
"source": "https://github.com/vimeo/psalm/tree/4.7.2"
|
||||
},
|
||||
"time": "2021-04-25T21:26:25+00:00"
|
||||
"time": "2021-05-01T20:56:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/path-util",
|
||||
|
|
|
@ -76,6 +76,9 @@ services:
|
|||
environment:
|
||||
- _APP_ENV
|
||||
- _APP_LOCALE
|
||||
- _APP_CONSOLE_WHITELIST_ROOT
|
||||
- _APP_CONSOLE_WHITELIST_EMAILS
|
||||
- _APP_CONSOLE_WHITELIST_IPS
|
||||
- _APP_SYSTEM_EMAIL_NAME
|
||||
- _APP_SYSTEM_EMAIL_ADDRESS
|
||||
- _APP_SYSTEM_SECURITY_EMAIL_ADDRESS
|
||||
|
|
|
@ -1 +1 @@
|
|||
appwrite database createCollection --name="[NAME]" "--read[]=" "--write[]=" "--rules[]="
|
||||
appwrite database createCollection --name="[NAME]" --read="" --write="" --rules=""
|
|
@ -1 +1 @@
|
|||
appwrite database createDocument --collectionId="[COLLECTION_ID]" --data="{}" "--read[]=" "--write[]=" --parentDocument="[PARENT_DOCUMENT]" --parentProperty="" --parentPropertyType="assign"
|
||||
appwrite database createDocument --collectionId="[COLLECTION_ID]" --data="{}" --read="" --write="" --parentDocument="[PARENT_DOCUMENT]" --parentProperty="" --parentPropertyType="assign"
|
|
@ -1 +1 @@
|
|||
appwrite database listDocuments --collectionId="[COLLECTION_ID]" "--filters[]=" --limit="0" --offset="0" --orderField="[ORDER_FIELD]" --orderType="DESC" --orderCast="int" --search="[SEARCH]"
|
||||
appwrite database listDocuments --collectionId="[COLLECTION_ID]" --filters="" --limit="0" --offset="0" --orderField="[ORDER_FIELD]" --orderType="DESC" --orderCast="int" --search="[SEARCH]"
|
|
@ -1 +1 @@
|
|||
appwrite database updateCollection --collectionId="[COLLECTION_ID]" --name="[NAME]" "--read[]=" "--write[]=" "--rules[]="
|
||||
appwrite database updateCollection --collectionId="[COLLECTION_ID]" --name="[NAME]" --read="" --write="" --rules=""
|
|
@ -1 +1 @@
|
|||
appwrite database updateDocument --collectionId="[COLLECTION_ID]" --documentId="[DOCUMENT_ID]" --data="{}" "--read[]=" "--write[]="
|
||||
appwrite database updateDocument --collectionId="[COLLECTION_ID]" --documentId="[DOCUMENT_ID]" --data="{}" --read="" --write=""
|
|
@ -1 +1 @@
|
|||
appwrite functions create --name="[NAME]" "--execute[]=" --env="node-14.5" --vars="{}" "--events[]=" --schedule="" --timeout="1"
|
||||
appwrite functions create --name="[NAME]" --execute="" --env="node-14.5" --vars="{}" --events="" --schedule="" --timeout="1"
|
|
@ -1 +1 @@
|
|||
appwrite functions update --functionId="[FUNCTION_ID]" --name="[NAME]" "--execute[]=" --vars="{}" "--events[]=" --schedule="" --timeout="1"
|
||||
appwrite functions update --functionId="[FUNCTION_ID]" --name="[NAME]" --execute="" --vars="{}" --events="" --schedule="" --timeout="1"
|
|
@ -1 +1 @@
|
|||
appwrite storage createFile --file="" "--read[]=" "--write[]="
|
||||
appwrite storage createFile --file="" --read="" --write=""
|
|
@ -1 +1 @@
|
|||
appwrite storage updateFile --fileId="[FILE_ID]" "--read[]=" "--write[]="
|
||||
appwrite storage updateFile --fileId="[FILE_ID]" --read="" --write=""
|
|
@ -1 +1 @@
|
|||
appwrite teams createMembership --teamId="[TEAM_ID]" --email="email@example.com" "--roles[]=" --url="https://example.com" --name="[NAME]"
|
||||
appwrite teams createMembership --teamId="[TEAM_ID]" --email="email@example.com" --roles="" --url="https://example.com" --name="[NAME]"
|
|
@ -1 +1 @@
|
|||
appwrite teams create --name="[NAME]" "--roles[]="
|
||||
appwrite teams create --name="[NAME]" --roles=""
|
|
@ -1 +1 @@
|
|||
Update currently logged in user password. For validation, user is required to pass the password twice. For users created with OAuth and Team Invites, oldPassword is optional.
|
||||
Update currently logged in user password. For validation, user is required to pass in the new password, and the old password. For users created with OAuth and Team Invites, oldPassword is optional.
|
|
@ -1,3 +1,8 @@
|
|||
## 0.5.0-dev.1
|
||||
|
||||
- Upgraded to Null-safety, minimum Dart SDK required 2.12.0
|
||||
- Upgraded all underlying dependencies to null safe version
|
||||
|
||||
## 0.3.1
|
||||
|
||||
- Minor fixes for custom exceptions
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
## 0.5.0-dev.1
|
||||
|
||||
- Upgraded to Null-safety, minimum Dart SDK required 2.12.0 and minimum Flutter SDK version required 2.0.0
|
||||
- Upgraded all underlying dependencies to null safe version
|
||||
- All of Avatars service now return Future<Response></Response> instead of String like the Storage getFilePreview, getFileView and getFileDownload
|
||||
- Upgraded to Null-safety, minimum Dart SDK required 2.12.0
|
||||
- Upgraded all underlying dependencies to null safe version
|
||||
|
||||
## 0.4.0
|
||||
|
||||
- Improved code quality
|
||||
|
|
9677
package-lock.json
generated
9677
package-lock.json
generated
File diff suppressed because it is too large
Load diff
11
package.json
11
package.json
|
@ -3,14 +3,19 @@
|
|||
"version": "0.1.0",
|
||||
"license": "BSD-3-Clause",
|
||||
"repository": "public",
|
||||
"scripts": {
|
||||
"build": "npm run gulp:less && npm run gulp:import && npm run gulp:build",
|
||||
"gulp:less": "gulp less",
|
||||
"gulp:import": "gulp import",
|
||||
"gulp:build": "gulp build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"yargs-parser": ">=20.2.0",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-clean-css": "^4.3.0",
|
||||
"gulp-concat": "^2.6.1",
|
||||
"gulp-jsmin": "^0.1.5",
|
||||
"gulp-less": "^4.0.1",
|
||||
"jest": "^26.4.2",
|
||||
"ls-service-form2json": "^1.0.0"
|
||||
"ls-service-form2json": "^1.0.0",
|
||||
"yargs-parser": "^20.2.7"
|
||||
}
|
||||
}
|
||||
|
|
BIN
public/images/clients/flutter-linux.png
Normal file
BIN
public/images/clients/flutter-linux.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
public/images/clients/flutter-macos.png
Normal file
BIN
public/images/clients/flutter-macos.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
public/images/clients/flutter-windows.png
Normal file
BIN
public/images/clients/flutter-windows.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
public/images/clients/linux.png
Normal file
BIN
public/images/clients/linux.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
BIN
public/images/clients/macos.png
Normal file
BIN
public/images/clients/macos.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
BIN
public/images/clients/windows.png
Normal file
BIN
public/images/clients/windows.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -40,4 +40,28 @@ class Password extends Validator
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is array
|
||||
*
|
||||
* Function will return true if object is array.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isArray(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* Returns validator type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return self::TYPE_STRING;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -188,4 +188,28 @@ class Authorization extends Validator
|
|||
{
|
||||
self::$status = self::$statusDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is array
|
||||
*
|
||||
* Function will return true if object is array.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isArray(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* Returns validator type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return self::TYPE_ARRAY;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,4 +78,28 @@ class DocumentId extends Validator
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is array
|
||||
*
|
||||
* Function will return true if object is array.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isArray(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* Returns validator type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return self::TYPE_STRING;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,4 +48,27 @@ class Key extends Validator
|
|||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Is array
|
||||
*
|
||||
* Function will return true if object is array.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isArray(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* Returns validator type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return self::TYPE_STRING;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,4 +74,27 @@ class Permissions extends Validator
|
|||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Is array
|
||||
*
|
||||
* Function will return true if object is array.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isArray(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* Returns validator type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return self::TYPE_ARRAY;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Appwrite\Database\Validator;
|
|||
|
||||
use Appwrite\Database\Database;
|
||||
use Appwrite\Database\Document;
|
||||
use Appwrite\Network\Validator as NetworkValidator;
|
||||
use Utopia\Validator;
|
||||
|
||||
class Structure extends Validator
|
||||
|
@ -187,16 +188,16 @@ class Structure extends Validator
|
|||
$validator = new Validator\Boolean();
|
||||
break;
|
||||
case self::RULE_TYPE_EMAIL:
|
||||
$validator = new Validator\Email();
|
||||
$validator = new NetworkValidator\Email();
|
||||
break;
|
||||
case self::RULE_TYPE_URL:
|
||||
$validator = new Validator\URL();
|
||||
$validator = new NetworkValidator\URL();
|
||||
break;
|
||||
case self::RULE_TYPE_IP:
|
||||
$validator = new Validator\IP();
|
||||
$validator = new NetworkValidator\IP();
|
||||
break;
|
||||
case self::RULE_TYPE_WILDCARD:
|
||||
$validator = new Validator\Mock();
|
||||
$validator = new Validator\Wildcard();
|
||||
break;
|
||||
case self::RULE_TYPE_DOCUMENT:
|
||||
$validator = new Collection($this->database, (isset($rule['list'])) ? $rule['list'] : []);
|
||||
|
@ -285,4 +286,28 @@ class Structure extends Validator
|
|||
{
|
||||
return $this->database->getDocument($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is array
|
||||
*
|
||||
* Function will return true if object is array.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isArray(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* Returns validator type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return self::TYPE_OBJECT;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,4 +43,28 @@ class UID extends Validator
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is array
|
||||
*
|
||||
* Function will return true if object is array.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isArray(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* Returns validator type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return self::TYPE_STRING;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,4 +54,28 @@ class CNAME extends Validator
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is array
|
||||
*
|
||||
* Function will return true if object is array.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isArray(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* Returns validator type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return self::TYPE_STRING;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,4 +51,28 @@ class Domain extends Validator
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is array
|
||||
*
|
||||
* Function will return true if object is array.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isArray(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* Returns validator type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return self::TYPE_STRING;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,18 +25,6 @@ class Email extends Validator
|
|||
return 'Value must be a valid email address';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* Returns validator type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return 'string';
|
||||
}
|
||||
|
||||
/**
|
||||
* Is valid
|
||||
*
|
||||
|
@ -53,4 +41,28 @@ class Email extends Validator
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is array
|
||||
*
|
||||
* Function will return true if object is array.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isArray(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* Returns validator type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return self::TYPE_STRING;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,18 +35,6 @@ class Host extends Validator
|
|||
return 'URL host must be one of: ' . \implode(', ', $this->whitelist);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* Returns validator type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return 'string';
|
||||
}
|
||||
|
||||
/**
|
||||
* Is valid
|
||||
*
|
||||
|
@ -69,4 +57,28 @@ class Host extends Validator
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is array
|
||||
*
|
||||
* Function will return true if object is array.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isArray(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* Returns validator type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return self::TYPE_STRING;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,18 +51,6 @@ class IP extends Validator
|
|||
return 'Value must be a valid IP address';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* Returns validator type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return 'string';
|
||||
}
|
||||
|
||||
/**
|
||||
* Is valid
|
||||
*
|
||||
|
@ -99,4 +87,28 @@ class IP extends Validator
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is array
|
||||
*
|
||||
* Function will return true if object is array.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isArray(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* Returns validator type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return self::TYPE_STRING;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -119,4 +119,28 @@ class Origin extends Validator
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is array
|
||||
*
|
||||
* Function will return true if object is array.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isArray(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* Returns validator type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return self::TYPE_STRING;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,18 +25,6 @@ class URL extends Validator
|
|||
return 'Value must be a valid URL';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* Returns validator type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return 'string';
|
||||
}
|
||||
|
||||
/**
|
||||
* Is valid
|
||||
*
|
||||
|
@ -53,4 +41,28 @@ class URL extends Validator
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is array
|
||||
*
|
||||
* Function will return true if object is array.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isArray(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* Returns validator type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return self::TYPE_STRING;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -218,12 +218,12 @@ class OpenAPI3 extends Format
|
|||
$node['schema']['type'] = 'string';
|
||||
$node['schema']['x-example'] = '['.\strtoupper(Template::fromCamelCaseToSnake($node['name'])).']';
|
||||
break;
|
||||
case 'Utopia\Validator\Email':
|
||||
case 'Appwrite\Network\Validator\Email':
|
||||
$node['schema']['type'] = 'string';
|
||||
$node['schema']['format'] = 'email';
|
||||
$node['schema']['x-example'] = 'email@example.com';
|
||||
break;
|
||||
case 'Utopia\Validator\URL':
|
||||
case 'Appwrite\Network\Validator\URL':
|
||||
$node['schema']['type'] = 'string';
|
||||
$node['schema']['format'] = 'url';
|
||||
$node['schema']['x-example'] = 'https://example.com';
|
||||
|
@ -264,14 +264,18 @@ class OpenAPI3 extends Format
|
|||
case 'Utopia\Validator\Length':
|
||||
$node['schema']['type'] = 'string';
|
||||
break;
|
||||
case 'Utopia\Validator\Host':
|
||||
case 'Appwrite\Network\Validator\Host':
|
||||
$node['schema']['type'] = 'string';
|
||||
$node['schema']['format'] = 'url';
|
||||
$node['schema']['x-example'] = 'https://example.com';
|
||||
break;
|
||||
case 'Utopia\Validator\WhiteList': /** @var \Utopia\Validator\WhiteList $validator */
|
||||
$node['schema']['type'] = 'string';
|
||||
$node['schema']['type'] = $validator->getType();
|
||||
$node['schema']['x-example'] = $validator->getList()[0];
|
||||
|
||||
if ($validator->getType() === 'integer') {
|
||||
$node['format'] = 'int32';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$node['schema']['type'] = 'string';
|
||||
|
|
|
@ -215,12 +215,12 @@ class Swagger2 extends Format
|
|||
$node['type'] = 'string';
|
||||
$node['x-example'] = '['.\strtoupper(Template::fromCamelCaseToSnake($node['name'])).']';
|
||||
break;
|
||||
case 'Utopia\Validator\Email':
|
||||
case 'Appwrite\Network\Validator\Email':
|
||||
$node['type'] = 'string';
|
||||
$node['format'] = 'email';
|
||||
$node['x-example'] = 'email@example.com';
|
||||
break;
|
||||
case 'Utopia\Validator\URL':
|
||||
case 'Appwrite\Network\Validator\URL':
|
||||
$node['type'] = 'string';
|
||||
$node['format'] = 'url';
|
||||
$node['x-example'] = 'https://example.com';
|
||||
|
@ -261,14 +261,18 @@ class Swagger2 extends Format
|
|||
case 'Utopia\Validator\Length':
|
||||
$node['type'] = 'string';
|
||||
break;
|
||||
case 'Utopia\Validator\Host':
|
||||
case 'Appwrite\Network\Validator\Host':
|
||||
$node['type'] = 'string';
|
||||
$node['format'] = 'url';
|
||||
$node['x-example'] = 'https://example.com';
|
||||
break;
|
||||
case 'Utopia\Validator\WhiteList': /** @var \Utopia\Validator\WhiteList $validator */
|
||||
$node['type'] = 'string';
|
||||
$node['type'] = $validator->getType();
|
||||
$node['x-example'] = $validator->getList()[0];
|
||||
|
||||
if ($validator->getType() === 'integer') {
|
||||
$node['format'] = 'int32';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$node['type'] = 'string';
|
||||
|
|
|
@ -40,4 +40,28 @@ class Cron extends Validator
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is array
|
||||
*
|
||||
* Function will return true if object is array.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isArray(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* Returns validator type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return self::TYPE_STRING;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ trait TeamsBaseClient
|
|||
$this->assertEquals('Invitation to '.$teamName.' Team at '.$this->getProject()['name'], $lastEmail['subject']);
|
||||
|
||||
$secret = substr($lastEmail['text'], strpos($lastEmail['text'], '&secret=', 0) + 8, 256);
|
||||
$inviteUid = substr($lastEmail['text'], strpos($lastEmail['text'], '?inviteId=', 0) + 10, 13);
|
||||
$membershipUid = substr($lastEmail['text'], strpos($lastEmail['text'], '?membershipId=', 0) + 14, 13);
|
||||
$userUid = substr($lastEmail['text'], strpos($lastEmail['text'], '&userId=', 0) + 8, 13);
|
||||
|
||||
/**
|
||||
|
@ -118,7 +118,7 @@ trait TeamsBaseClient
|
|||
return [
|
||||
'teamUid' => $teamUid,
|
||||
'secret' => $secret,
|
||||
'inviteUid' => $inviteUid,
|
||||
'membershipUid' => $membershipUid,
|
||||
'userUid' => $userUid,
|
||||
'email' => $email,
|
||||
'name' => $name
|
||||
|
@ -132,7 +132,7 @@ trait TeamsBaseClient
|
|||
{
|
||||
$teamUid = $data['teamUid'] ?? '';
|
||||
$secret = $data['secret'] ?? '';
|
||||
$inviteUid = $data['inviteUid'] ?? '';
|
||||
$membershipUid = $data['membershipUid'] ?? '';
|
||||
$userUid = $data['userUid'] ?? '';
|
||||
$email = $data['email'] ?? '';
|
||||
$name = $data['name'] ?? '';
|
||||
|
@ -140,7 +140,7 @@ trait TeamsBaseClient
|
|||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/teams/'.$teamUid.'/memberships/'.$inviteUid.'/status', array_merge([
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/teams/'.$teamUid.'/memberships/'.$membershipUid.'/status', array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
|
@ -215,7 +215,7 @@ trait TeamsBaseClient
|
|||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/teams/'.$teamUid.'/memberships/'.$inviteUid.'/status', array_merge([
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/teams/'.$teamUid.'/memberships/'.$membershipUid.'/status', array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
|
@ -226,7 +226,7 @@ trait TeamsBaseClient
|
|||
|
||||
$this->assertEquals(401, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/teams/'.$teamUid.'/memberships/'.$inviteUid.'/status', array_merge([
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/teams/'.$teamUid.'/memberships/'.$membershipUid.'/status', array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
|
@ -237,7 +237,7 @@ trait TeamsBaseClient
|
|||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/teams/'.$teamUid.'/memberships/'.$inviteUid.'/status', array_merge([
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/teams/'.$teamUid.'/memberships/'.$membershipUid.'/status', array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
|
@ -248,7 +248,7 @@ trait TeamsBaseClient
|
|||
|
||||
$this->assertEquals(401, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/teams/'.$teamUid.'/memberships/'.$inviteUid.'/status', array_merge([
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/teams/'.$teamUid.'/memberships/'.$membershipUid.'/status', array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
|
@ -268,12 +268,12 @@ trait TeamsBaseClient
|
|||
public function testDeleteTeamMembership($data):array
|
||||
{
|
||||
$teamUid = $data['teamUid'] ?? '';
|
||||
$inviteUid = $data['inviteUid'] ?? '';
|
||||
$membershipUid = $data['membershipUid'] ?? '';
|
||||
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/teams/'.$teamUid.'/memberships/'.$inviteUid, array_merge([
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/teams/'.$teamUid.'/memberships/'.$membershipUid, array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
|
@ -285,7 +285,7 @@ trait TeamsBaseClient
|
|||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/teams/'.$teamUid.'/memberships/'.$inviteUid, array_merge([
|
||||
$response = $this->client->call(Client::METHOD_GET, '/teams/'.$teamUid.'/memberships/'.$membershipUid, array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
|
|
|
@ -464,7 +464,7 @@ trait WebhooksBase
|
|||
$lastEmail = $this->getLastEmail();
|
||||
|
||||
$secret = substr($lastEmail['text'], strpos($lastEmail['text'], '&secret=', 0) + 8, 256);
|
||||
$inviteUid = substr($lastEmail['text'], strpos($lastEmail['text'], '?inviteId=', 0) + 10, 13);
|
||||
$membershipUid = substr($lastEmail['text'], strpos($lastEmail['text'], '?membershipId=', 0) + 14, 13);
|
||||
$userUid = substr($lastEmail['text'], strpos($lastEmail['text'], '&userId=', 0) + 8, 13);
|
||||
|
||||
$webhook = $this->getLastRequest();
|
||||
|
@ -490,7 +490,7 @@ trait WebhooksBase
|
|||
return [
|
||||
'teamId' => $teamUid,
|
||||
'secret' => $secret,
|
||||
'inviteId' => $inviteUid,
|
||||
'membershipId' => $membershipUid,
|
||||
'userId' => $webhook['data']['userId'],
|
||||
];
|
||||
}
|
||||
|
|
|
@ -714,13 +714,13 @@ class WebhooksCustomClientTest extends Scope
|
|||
{
|
||||
$teamUid = $data['teamId'] ?? '';
|
||||
$secret = $data['secret'] ?? '';
|
||||
$inviteUid = $data['inviteId'] ?? '';
|
||||
$membershipUid = $data['membershipId'] ?? '';
|
||||
$userUid = $data['userId'] ?? '';
|
||||
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$team = $this->client->call(Client::METHOD_PATCH, '/teams/'.$teamUid.'/memberships/'.$inviteUid.'/status', array_merge([
|
||||
$team = $this->client->call(Client::METHOD_PATCH, '/teams/'.$teamUid.'/memberships/'.$membershipUid.'/status', array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
|
|
Loading…
Reference in a new issue