2019-12-15 08:33:29 +13:00
< ? php
2020-03-25 06:56:32 +13:00
use Appwrite\Auth\Auth ;
2021-12-02 04:09:57 +13:00
use Appwrite\Auth\Validator\Password ;
2022-10-08 18:42:53 +13:00
use Appwrite\Database\Pools ;
2022-04-14 00:39:31 +12:00
use Appwrite\Event\Certificate ;
2022-05-09 03:25:01 +12:00
use Appwrite\Event\Delete ;
2022-04-04 18:30:07 +12:00
use Appwrite\Event\Validator\Event ;
2020-06-12 07:36:10 +12:00
use Appwrite\Network\Validator\CNAME ;
2020-07-08 10:11:02 +12:00
use Appwrite\Network\Validator\Domain as DomainValidator ;
2022-03-06 12:35:44 +13:00
use Appwrite\Network\Validator\Origin ;
2021-06-07 17:17:29 +12:00
use Appwrite\Network\Validator\URL ;
2022-01-19 00:05:04 +13:00
use Appwrite\Utopia\Database\Validator\CustomId ;
2020-08-15 09:56:50 +12:00
use Appwrite\Utopia\Response ;
2021-08-17 01:27:15 +12:00
use Utopia\Abuse\Adapters\TimeLimit ;
2021-06-07 17:17:29 +12:00
use Utopia\App ;
2021-08-17 01:27:15 +12:00
use Utopia\Audit\Audit ;
2021-06-07 17:17:29 +12:00
use Utopia\Config\Config ;
2021-08-17 01:27:15 +12:00
use Utopia\Database\Database ;
2021-05-16 10:41:42 +12:00
use Utopia\Database\Document ;
2022-08-14 22:33:36 +12:00
use Utopia\Database\ID ;
2022-07-13 01:32:39 +12:00
use Utopia\Database\DateTime ;
2022-08-14 17:21:11 +12:00
use Utopia\Database\Permission ;
2021-05-27 22:09:14 +12:00
use Utopia\Database\Query ;
2022-08-14 17:21:11 +12:00
use Utopia\Database\Role ;
2021-08-17 01:27:15 +12:00
use Utopia\Database\Validator\Authorization ;
2022-07-14 02:07:03 +12:00
use Utopia\Database\Validator\DatetimeValidator ;
2021-05-16 10:41:42 +12:00
use Utopia\Database\Validator\UID ;
2021-06-07 17:17:29 +12:00
use Utopia\Domains\Domain ;
2022-05-07 04:51:02 +12:00
use Utopia\Registry\Registry ;
2022-02-07 06:11:02 +13:00
use Appwrite\Extend\Exception ;
2022-08-13 04:09:45 +12:00
use Utopia\Cache\Adapter\Redis ;
use Utopia\Cache\Cache ;
use Utopia\Database\Adapter\MariaDB ;
2022-09-01 00:30:16 +12:00
use Appwrite\Utopia\Database\Validator\Queries\Projects ;
2021-06-07 17:17:29 +12:00
use Utopia\Validator\ArrayList ;
use Utopia\Validator\Boolean ;
2022-04-20 21:31:17 +12:00
use Utopia\Validator\Hostname ;
2021-06-07 17:17:29 +12:00
use Utopia\Validator\Range ;
use Utopia\Validator\Text ;
use Utopia\Validator\WhiteList ;
2019-12-15 08:33:29 +13:00
2022-07-22 18:00:42 +12:00
App :: init ()
-> groups ([ 'projects' ])
2022-08-02 13:10:48 +12:00
-> inject ( 'project' )
2022-07-22 18:00:42 +12:00
-> action ( function ( Document $project ) {
if ( $project -> getId () !== 'console' ) {
2022-08-09 02:03:01 +12:00
throw new Exception ( Exception :: GENERAL_ACCESS_FORBIDDEN );
2022-07-22 18:00:42 +12:00
}
});
2021-08-01 09:36:18 +12:00
2020-06-29 05:31:21 +12:00
App :: post ( '/v1/projects' )
2020-02-01 11:34:07 +13:00
-> desc ( 'Create Project' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2020-02-01 11:34:07 +13:00
-> label ( 'scope' , 'projects.write' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2020-02-01 11:34:07 +13:00
-> label ( 'sdk.namespace' , 'projects' )
-> label ( 'sdk.method' , 'create' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_CREATED )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_PROJECT )
2022-01-13 11:05:25 +13:00
-> param ( 'projectId' , '' , new CustomId (), 'Unique Id. Choose your own unique ID or pass the string "unique()" to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.' )
2020-09-11 02:40:14 +12:00
-> param ( 'name' , null , new Text ( 128 ), 'Project name. Max length: 128 chars.' )
-> param ( 'teamId' , '' , new UID (), 'Team unique ID.' )
2022-09-09 13:22:04 +12:00
-> param ( 'region' , '' , new Whitelist ( array_keys ( array_filter ( Config :: getParam ( 'regions' ), fn ( $config ) => ! $config [ 'disabled' ]))), 'Project Region.' )
2020-09-11 02:40:14 +12:00
-> param ( 'description' , '' , new Text ( 256 ), 'Project description. Max length: 256 chars.' , true )
-> param ( 'logo' , '' , new Text ( 1024 ), 'Project logo.' , true )
2022-02-17 04:20:54 +13:00
-> param ( 'url' , '' , new URL (), 'Project URL.' , true )
2020-09-11 02:40:14 +12:00
-> param ( 'legalName' , '' , new Text ( 256 ), 'Project legal Name. Max length: 256 chars.' , true )
-> param ( 'legalCountry' , '' , new Text ( 256 ), 'Project legal Country. Max length: 256 chars.' , true )
-> param ( 'legalState' , '' , new Text ( 256 ), 'Project legal State. Max length: 256 chars.' , true )
-> param ( 'legalCity' , '' , new Text ( 256 ), 'Project legal City. Max length: 256 chars.' , true )
-> param ( 'legalAddress' , '' , new Text ( 256 ), 'Project legal Address. Max length: 256 chars.' , true )
-> param ( 'legalTaxId' , '' , new Text ( 256 ), 'Project legal Tax ID. Max length: 256 chars.' , true )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-06-23 20:50:00 +12:00
-> inject ( 'cache' )
-> inject ( 'dbPool' )
2022-10-08 18:48:06 +13:00
-> action ( function ( string $projectId , string $name , string $teamId , string $region , string $description , string $logo , string $url , string $legalName , string $legalCountry , string $legalState , string $legalCity , string $legalAddress , string $legalTaxId , Response $response , Database $dbForConsole , \Redis $cache , Pools $dbPool ) {
2021-06-07 05:54:01 +12:00
$team = $dbForConsole -> getDocument ( 'teams' , $teamId );
2020-02-01 11:34:07 +13:00
2021-05-07 10:31:05 +12:00
if ( $team -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: TEAM_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2021-08-17 01:27:15 +12:00
2021-08-06 19:42:31 +12:00
$auth = Config :: getParam ( 'auth' , []);
2021-08-07 17:12:33 +12:00
$auths = [ 'limit' => 0 ];
2021-08-06 19:42:31 +12:00
foreach ( $auth as $index => $method ) {
$auths [ $method [ 'key' ] ? ? '' ] = true ;
}
2020-02-01 11:34:07 +13:00
2022-08-15 02:22:38 +12:00
$projectId = ( $projectId == 'unique()' ) ? ID :: unique () : $projectId ;
2022-06-16 19:50:52 +12:00
2022-05-24 02:54:50 +12:00
if ( $projectId === 'console' ) {
2022-07-27 02:56:59 +12:00
throw new Exception ( Exception :: PROJECT_RESERVED_PROJECT , " 'console' is a reserved project. " );
2022-04-17 22:18:00 +12:00
}
2022-06-23 20:50:00 +12:00
2022-08-13 04:09:45 +12:00
$pdo = $dbPool -> getAnyFromPool ();
2022-07-14 11:42:26 +12:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> createDocument ( 'projects' , new Document ([
2022-07-01 03:38:47 +12:00
'$id' => $projectId ,
2022-08-02 21:21:53 +12:00
'$permissions' => [
2022-08-14 22:33:36 +12:00
Permission :: read ( Role :: team ( ID :: custom ( $teamId ))),
Permission :: update ( Role :: team ( ID :: custom ( $teamId ), 'owner' )),
Permission :: update ( Role :: team ( ID :: custom ( $teamId ), 'developer' )),
Permission :: delete ( Role :: team ( ID :: custom ( $teamId ), 'owner' )),
Permission :: delete ( Role :: team ( ID :: custom ( $teamId ), 'developer' )),
2022-08-02 21:21:53 +12:00
],
2021-05-16 10:41:42 +12:00
'name' => $name ,
2022-06-16 19:50:52 +12:00
'teamInternalId' => $team -> getInternalId (),
2021-07-19 02:17:29 +12:00
'teamId' => $team -> getId (),
2022-09-08 17:04:16 +12:00
'region' => $region ,
2021-05-16 10:41:42 +12:00
'description' => $description ,
'logo' => $logo ,
'url' => $url ,
2021-07-19 02:17:29 +12:00
'version' => APP_VERSION_STABLE ,
2021-05-16 10:41:42 +12:00
'legalName' => $legalName ,
'legalCountry' => $legalCountry ,
'legalState' => $legalState ,
'legalCity' => $legalCity ,
'legalAddress' => $legalAddress ,
2022-08-14 22:33:36 +12:00
'legalTaxId' => ID :: custom ( $legalTaxId ),
2021-09-02 21:38:24 +12:00
'services' => new stdClass (),
2021-08-31 02:24:50 +12:00
'platforms' => null ,
2022-04-14 21:54:29 +12:00
'authProviders' => [],
2021-08-31 02:24:50 +12:00
'webhooks' => null ,
'keys' => null ,
'domains' => null ,
2021-08-06 19:42:31 +12:00
'auths' => $auths ,
2021-08-15 06:56:28 +12:00
'search' => implode ( ' ' , [ $projectId , $name ]),
2022-08-13 04:09:45 +12:00
'database' => $pdo -> getName ()
2021-05-16 10:41:42 +12:00
]));
2020-07-01 03:46:42 +12:00
2022-08-25 03:22:54 +12:00
$dbForProject = DatabasePool :: getDatabase ( $pdo -> getConnection (), $cache , " _ { $project -> getInternalId () } " );
2022-07-07 05:04:29 +12:00
$dbForProject -> create ( App :: getEnv ( '_APP_DB_SCHEMA' , 'appwrite' ));
2021-05-03 20:28:31 +12:00
2021-12-28 01:45:23 +13:00
$audit = new Audit ( $dbForProject );
2021-06-07 17:52:40 +12:00
$audit -> setup ();
2021-12-28 01:45:23 +13:00
$adapter = new TimeLimit ( '' , 0 , 1 , $dbForProject );
2021-06-07 17:52:40 +12:00
$adapter -> setup ();
2022-06-23 20:50:00 +12:00
/** @var array $collections */
$collections = Config :: getParam ( 'collections' , []);
2021-05-03 20:28:31 +12:00
foreach ( $collections as $key => $collection ) {
2022-05-24 02:54:50 +12:00
if (( $collection [ '$collection' ] ? ? '' ) !== Database :: METADATA ) {
2021-12-23 21:31:32 +13:00
continue ;
}
2022-06-20 23:44:04 +12:00
2021-07-05 00:05:46 +12:00
$attributes = [];
$indexes = [];
foreach ( $collection [ 'attributes' ] as $attribute ) {
$attributes [] = new Document ([
'$id' => $attribute [ '$id' ],
'type' => $attribute [ 'type' ],
'size' => $attribute [ 'size' ],
'required' => $attribute [ 'required' ],
'signed' => $attribute [ 'signed' ],
'array' => $attribute [ 'array' ],
'filters' => $attribute [ 'filters' ],
2022-03-27 21:01:50 +13:00
'default' => $attribute [ 'default' ] ? ? null ,
'format' => $attribute [ 'format' ] ? ? ''
2021-07-05 00:05:46 +12:00
]);
2021-05-03 20:28:31 +12:00
}
2021-07-05 00:05:46 +12:00
foreach ( $collection [ 'indexes' ] as $index ) {
$indexes [] = new Document ([
'$id' => $index [ '$id' ],
'type' => $index [ 'type' ],
'attributes' => $index [ 'attributes' ],
'lengths' => $index [ 'lengths' ],
'orders' => $index [ 'orders' ],
]);
2021-05-03 20:28:31 +12:00
}
2021-12-28 01:45:23 +13:00
$dbForProject -> createCollection ( $key , $attributes , $indexes );
2021-05-03 20:28:31 +12:00
}
2022-09-07 23:02:36 +12:00
$response
-> setStatusCode ( Response :: STATUS_CODE_CREATED )
-> dynamic ( $project , Response :: MODEL_PROJECT );
2020-12-27 05:33:36 +13:00
});
2020-02-01 11:34:07 +13:00
2020-06-29 05:31:21 +12:00
App :: get ( '/v1/projects' )
2019-12-15 08:33:29 +13:00
-> desc ( 'List Projects' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2019-12-15 08:33:29 +13:00
-> label ( 'scope' , 'projects.read' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2019-12-15 08:33:29 +13:00
-> label ( 'sdk.namespace' , 'projects' )
2020-01-31 05:18:46 +13:00
-> label ( 'sdk.method' , 'list' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_PROJECT_LIST )
2022-09-01 00:30:16 +12:00
-> param ( 'queries' , [], new Projects (), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/databases#querying-documents). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following attributes: ' . implode ( ', ' , Projects :: ALLOWED_ATTRIBUTES ), true )
2020-09-11 02:40:14 +12:00
-> param ( 'search' , '' , new Text ( 256 ), 'Search term to filter your list results. Max length: 256 chars.' , true )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-09-01 00:30:16 +12:00
-> action ( function ( array $queries , string $search , Response $response , Database $dbForConsole ) {
2020-07-09 03:07:52 +12:00
2022-09-01 00:30:16 +12:00
$queries = Query :: parseQueries ( $queries );
2021-08-07 00:36:17 +12:00
2022-08-12 11:53:52 +12:00
if ( ! empty ( $search )) {
2022-09-01 00:30:16 +12:00
$queries [] = Query :: search ( 'search' , $search );
2021-08-07 00:36:17 +12:00
}
2022-09-01 00:30:16 +12:00
// Get cursor document if there was a cursor query
2022-09-03 02:19:36 +12:00
$cursor = Query :: getByType ( $queries , Query :: TYPE_CURSORAFTER , Query :: TYPE_CURSORBEFORE );
$cursor = reset ( $cursor );
2022-09-01 00:30:16 +12:00
if ( $cursor ) {
/** @var Query $cursor */
$projectId = $cursor -> getValue ();
$cursorDocument = $dbForConsole -> getDocument ( 'projects' , $projectId );
2021-08-19 01:42:03 +12:00
2022-08-12 11:53:52 +12:00
if ( $cursorDocument -> isEmpty ()) {
2022-09-01 00:30:16 +12:00
throw new Exception ( Exception :: GENERAL_CURSOR_NOT_FOUND , " Project ' { $projectId } ' for the 'cursor' value not found. " );
2022-08-12 11:53:52 +12:00
}
2022-09-01 00:30:16 +12:00
$cursor -> setValue ( $cursorDocument );
2021-08-19 01:42:03 +12:00
}
2022-09-01 00:30:16 +12:00
$filterQueries = Query :: groupByType ( $queries )[ 'filters' ];
2020-07-01 03:46:42 +12:00
2021-07-26 02:47:18 +12:00
$response -> dynamic ( new Document ([
2022-09-01 00:30:16 +12:00
'projects' => $dbForConsole -> find ( 'projects' , $queries ),
'total' => $dbForConsole -> count ( 'projects' , $filterQueries , APP_LIMIT_COUNT ),
2020-09-12 20:07:28 +12:00
]), Response :: MODEL_PROJECT_LIST );
2020-12-27 05:33:36 +13:00
});
2019-12-15 08:33:29 +13:00
2020-06-29 05:31:21 +12:00
App :: get ( '/v1/projects/:projectId' )
2019-12-15 08:33:29 +13:00
-> desc ( 'Get Project' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2019-12-15 08:33:29 +13:00
-> label ( 'scope' , 'projects.read' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2019-12-15 08:33:29 +13:00
-> label ( 'sdk.namespace' , 'projects' )
2020-01-31 05:18:46 +13:00
-> label ( 'sdk.method' , 'get' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_PROJECT )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , '' , new UID (), 'Project unique ID.' )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , Response $response , Database $dbForConsole ) {
2019-12-15 08:33:29 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2019-12-15 08:33:29 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-15 08:33:29 +13:00
2021-07-26 02:47:18 +12:00
$response -> dynamic ( $project , Response :: MODEL_PROJECT );
2020-12-27 05:33:36 +13:00
});
2019-12-15 08:33:29 +13:00
2020-06-29 05:31:21 +12:00
App :: get ( '/v1/projects/:projectId/usage' )
2021-08-21 00:17:56 +12:00
-> desc ( 'Get usage stats for a project' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2019-12-15 08:33:29 +13:00
-> label ( 'scope' , 'projects.read' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2019-12-15 08:33:29 +13:00
-> label ( 'sdk.namespace' , 'projects' )
2020-01-31 05:18:46 +13:00
-> label ( 'sdk.method' , 'getUsage' )
2021-08-27 07:31:37 +12:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
2021-08-28 05:34:43 +12:00
-> label ( 'sdk.response.model' , Response :: MODEL_USAGE_PROJECT )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , '' , new UID (), 'Project unique ID.' )
2020-09-12 06:08:41 +12:00
-> param ( 'range' , '30d' , new WhiteList ([ '24h' , '7d' , '30d' , '90d' ], true ), 'Date range.' , true )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2021-12-28 01:45:23 +13:00
-> inject ( 'dbForProject' )
2020-12-27 05:33:36 +13:00
-> inject ( 'register' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , string $range , Response $response , Database $dbForConsole , Database $dbForProject , Registry $register ) {
2020-07-01 03:46:42 +12:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2020-07-01 03:46:42 +12:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-15 08:33:29 +13:00
2021-08-27 07:31:37 +12:00
$usage = [];
2021-06-07 17:17:29 +12:00
if ( App :: getEnv ( '_APP_USAGE_STATS' , 'enabled' ) == 'enabled' ) {
2021-10-28 11:17:15 +13:00
$periods = [
2021-01-13 02:35:17 +13:00
'24h' => [
2021-09-06 18:43:20 +12:00
'period' => '30m' ,
2021-08-17 01:27:15 +12:00
'limit' => 48 ,
2021-01-13 02:35:17 +13:00
],
'7d' => [
2021-08-17 01:27:15 +12:00
'period' => '1d' ,
'limit' => 7 ,
2021-01-13 02:35:17 +13:00
],
'30d' => [
2021-08-17 01:27:15 +12:00
'period' => '1d' ,
'limit' => 30 ,
2021-01-13 02:35:17 +13:00
],
'90d' => [
2021-08-17 01:27:15 +12:00
'period' => '1d' ,
'limit' => 90 ,
2021-01-13 02:35:17 +13:00
],
];
2021-06-07 17:17:29 +12:00
2022-06-16 19:50:52 +12:00
$dbForProject -> setNamespace ( " _ { $project -> getInternalId () } " );
2021-08-17 01:27:15 +12:00
2021-08-27 07:31:37 +12:00
$metrics = [
2022-08-11 18:05:38 +12:00
'project.$all.network.requests' ,
'project.$all.network.bandwidth' ,
2022-08-13 17:00:22 +12:00
'project.$all.storage.size' ,
2022-08-11 18:05:38 +12:00
'users.$all.count.total' ,
'collections.$all.count.total' ,
2022-08-13 17:00:22 +12:00
'documents.$all.count.total' ,
'executions.$all.compute.total' ,
2021-08-27 07:31:37 +12:00
];
$stats = [];
2021-08-29 04:25:48 +12:00
2022-05-24 02:54:50 +12:00
Authorization :: skip ( function () use ( $dbForProject , $periods , $range , $metrics , & $stats ) {
2021-08-29 04:25:48 +12:00
foreach ( $metrics as $metric ) {
2021-10-28 11:17:15 +13:00
$limit = $periods [ $range ][ 'limit' ];
$period = $periods [ $range ][ 'period' ];
2021-10-28 08:57:20 +13:00
2021-12-28 01:45:23 +13:00
$requestDocs = $dbForProject -> find ( 'stats' , [
2022-08-12 11:53:52 +12:00
Query :: equal ( 'period' , [ $period ]),
Query :: equal ( 'metric' , [ $metric ]),
Query :: limit ( $limit ),
Query :: orderDesc ( 'time' ),
]);
2021-10-27 02:19:28 +13:00
2021-08-29 04:25:48 +12:00
$stats [ $metric ] = [];
foreach ( $requestDocs as $requestDoc ) {
$stats [ $metric ][] = [
'value' => $requestDoc -> getAttribute ( 'value' ),
'date' => $requestDoc -> getAttribute ( 'time' ),
];
}
2021-10-28 08:57:20 +13:00
// backfill metrics with empty values for graphs
$backfill = $limit - \count ( $requestDocs );
while ( $backfill > 0 ) {
$last = $limit - $backfill - 1 ; // array index of last added metric
2022-05-24 02:54:50 +12:00
$diff = match ( $period ) { // convert period to seconds for unix timestamp math
2021-10-28 08:57:20 +13:00
'30m' => 1800 ,
'1d' => 86400 ,
};
$stats [ $metric ][] = [
'value' => 0 ,
2022-07-14 02:02:49 +12:00
'date' => DateTime :: addSeconds ( new \DateTime ( $stats [ $metric ][ $last ][ 'date' ] ? ? null ), - 1 * $diff ),
2021-10-28 08:57:20 +13:00
];
$backfill -- ;
}
2021-08-29 04:25:48 +12:00
$stats [ $metric ] = array_reverse ( $stats [ $metric ]);
2021-10-27 02:19:28 +13:00
}
2021-08-29 04:25:48 +12:00
});
2021-08-27 07:31:37 +12:00
$usage = new Document ([
'range' => $range ,
2022-08-20 23:20:31 +12:00
'requests' => $stats [ $metrics [ 0 ]] ? ? [],
'network' => $stats [ $metrics [ 1 ]] ? ? [],
'storage' => $stats [ $metrics [ 2 ]] ? ? [],
'users' => $stats [ $metrics [ 3 ]] ? ? [],
'collections' => $stats [ $metrics [ 4 ]] ? ? [],
'documents' => $stats [ $metrics [ 5 ]] ? ? [],
'executions' => $stats [ $metrics [ 6 ]] ? ? [],
2021-08-27 07:31:37 +12:00
]);
2020-07-01 03:46:42 +12:00
}
2019-12-15 08:33:29 +13:00
2021-08-28 05:34:43 +12:00
$response -> dynamic ( $usage , Response :: MODEL_USAGE_PROJECT );
2020-12-27 05:33:36 +13:00
});
2019-12-15 08:33:29 +13:00
2020-06-29 05:31:21 +12:00
App :: patch ( '/v1/projects/:projectId' )
2019-12-15 08:33:29 +13:00
-> desc ( 'Update Project' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2019-12-15 08:33:29 +13:00
-> label ( 'scope' , 'projects.write' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2019-12-15 08:33:29 +13:00
-> label ( 'sdk.namespace' , 'projects' )
2020-01-31 05:18:46 +13:00
-> label ( 'sdk.method' , 'update' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_PROJECT )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , '' , new UID (), 'Project unique ID.' )
-> param ( 'name' , null , new Text ( 128 ), 'Project name. Max length: 128 chars.' )
-> param ( 'description' , '' , new Text ( 256 ), 'Project description. Max length: 256 chars.' , true )
-> param ( 'logo' , '' , new Text ( 1024 ), 'Project logo.' , true )
2022-02-17 04:20:54 +13:00
-> param ( 'url' , '' , new URL (), 'Project URL.' , true )
2020-09-11 02:40:14 +12:00
-> param ( 'legalName' , '' , new Text ( 256 ), 'Project legal name. Max length: 256 chars.' , true )
-> param ( 'legalCountry' , '' , new Text ( 256 ), 'Project legal country. Max length: 256 chars.' , true )
-> param ( 'legalState' , '' , new Text ( 256 ), 'Project legal state. Max length: 256 chars.' , true )
-> param ( 'legalCity' , '' , new Text ( 256 ), 'Project legal city. Max length: 256 chars.' , true )
-> param ( 'legalAddress' , '' , new Text ( 256 ), 'Project legal address. Max length: 256 chars.' , true )
-> param ( 'legalTaxId' , '' , new Text ( 256 ), 'Project legal tax ID. Max length: 256 chars.' , true )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , string $name , string $description , string $logo , string $url , string $legalName , string $legalCountry , string $legalState , string $legalCity , string $legalAddress , string $legalTaxId , Response $response , Database $dbForConsole ) {
2019-12-15 08:33:29 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2019-12-15 08:33:29 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-15 08:33:29 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> updateDocument ( 'projects' , $project -> getId (), $project
2021-06-07 17:17:29 +12:00
-> setAttribute ( 'name' , $name )
-> setAttribute ( 'description' , $description )
-> setAttribute ( 'logo' , $logo )
-> setAttribute ( 'url' , $url )
-> setAttribute ( 'legalName' , $legalName )
-> setAttribute ( 'legalCountry' , $legalCountry )
-> setAttribute ( 'legalState' , $legalState )
-> setAttribute ( 'legalCity' , $legalCity )
-> setAttribute ( 'legalAddress' , $legalAddress )
-> setAttribute ( 'legalTaxId' , $legalTaxId )
2022-05-24 02:54:50 +12:00
-> setAttribute ( 'search' , implode ( ' ' , [ $projectId , $name ])));
2020-07-01 03:46:42 +12:00
2021-07-26 02:47:18 +12:00
$response -> dynamic ( $project , Response :: MODEL_PROJECT );
2020-12-27 05:33:36 +13:00
});
2019-12-15 08:33:29 +13:00
2021-07-29 22:28:17 +12:00
App :: patch ( '/v1/projects/:projectId/service' )
-> desc ( 'Update service status' )
-> groups ([ 'api' , 'projects' ])
-> label ( 'scope' , 'projects.write' )
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
-> label ( 'sdk.namespace' , 'projects' )
2021-08-01 08:54:50 +12:00
-> label ( 'sdk.method' , 'updateServiceStatus' )
2021-07-29 22:28:17 +12:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_PROJECT )
-> param ( 'projectId' , '' , new UID (), 'Project unique ID.' )
2022-05-24 04:42:27 +12:00
-> param ( 'service' , '' , new WhiteList ( array_keys ( array_filter ( Config :: getParam ( 'services' ), fn ( $element ) => $element [ 'optional' ])), true ), 'Service name.' )
2021-08-01 09:36:18 +12:00
-> param ( 'status' , null , new Boolean (), 'Service status.' )
2021-07-29 22:28:17 +12:00
-> inject ( 'response' )
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , string $service , bool $status , Response $response , Database $dbForConsole ) {
2021-07-29 22:28:17 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2021-07-29 22:56:25 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2021-07-29 22:28:17 +12:00
}
2021-08-01 08:54:50 +12:00
$services = $project -> getAttribute ( 'services' , []);
$services [ $service ] = $status ;
2021-07-29 22:28:17 +12:00
2021-08-01 08:54:50 +12:00
$project = $dbForConsole -> updateDocument ( 'projects' , $project -> getId (), $project -> setAttribute ( 'services' , $services ));
2021-07-29 22:28:17 +12:00
$response -> dynamic ( $project , Response :: MODEL_PROJECT );
});
2020-06-29 05:31:21 +12:00
App :: patch ( '/v1/projects/:projectId/oauth2' )
2020-02-17 00:41:03 +13:00
-> desc ( 'Update Project OAuth2' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2019-12-15 08:33:29 +13:00
-> label ( 'scope' , 'projects.write' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2019-12-15 08:33:29 +13:00
-> label ( 'sdk.namespace' , 'projects' )
2020-02-17 00:41:03 +13:00
-> label ( 'sdk.method' , 'updateOAuth2' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_PROJECT )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , '' , new UID (), 'Project unique ID.' )
-> param ( 'provider' , '' , new WhiteList ( \array_keys ( Config :: getParam ( 'providers' )), true ), 'Provider Name' , false )
-> param ( 'appId' , '' , new Text ( 256 ), 'Provider app ID. Max length: 256 chars.' , true )
-> param ( 'secret' , '' , new text ( 512 ), 'Provider secret key. Max length: 512 chars.' , true )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , string $provider , string $appId , string $secret , Response $response , Database $dbForConsole ) {
2019-12-15 08:33:29 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2019-12-15 08:33:29 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-15 08:33:29 +13:00
2022-04-14 21:54:29 +12:00
$providers = $project -> getAttribute ( 'authProviders' , []);
2021-08-06 22:35:50 +12:00
$providers [ $provider . 'Appid' ] = $appId ;
$providers [ $provider . 'Secret' ] = $secret ;
2022-04-14 21:54:29 +12:00
$project = $dbForConsole -> updateDocument ( 'projects' , $project -> getId (), $project -> setAttribute ( 'authProviders' , $providers ));
2020-07-01 03:46:42 +12:00
2021-07-26 02:47:18 +12:00
$response -> dynamic ( $project , Response :: MODEL_PROJECT );
2020-12-27 05:33:36 +13:00
});
2019-12-15 08:33:29 +13:00
2021-03-01 04:00:27 +13:00
App :: patch ( '/v1/projects/:projectId/auth/limit' )
-> desc ( 'Update Project users limit' )
2021-03-01 00:40:59 +13:00
-> groups ([ 'api' , 'projects' ])
-> label ( 'scope' , 'projects.write' )
2021-04-23 18:31:22 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2021-03-01 00:40:59 +13:00
-> label ( 'sdk.namespace' , 'projects' )
2021-03-01 04:00:27 +13:00
-> label ( 'sdk.method' , 'updateAuthLimit' )
2021-03-01 00:40:59 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_PROJECT )
-> param ( 'projectId' , '' , new UID (), 'Project unique ID.' )
2022-01-16 12:25:00 +13:00
-> param ( 'limit' , false , new Range ( 0 , APP_LIMIT_USERS ), 'Set the max number of users allowed in this project. Use 0 for unlimited.' )
2021-03-01 00:40:59 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , int $limit , Response $response , Database $dbForConsole ) {
2021-03-01 00:40:59 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2021-03-01 00:40:59 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2021-03-01 00:40:59 +13:00
}
2021-08-06 20:34:17 +12:00
$auths = $project -> getAttribute ( 'auths' , []);
$auths [ 'limit' ] = $limit ;
2021-05-16 10:41:42 +12:00
$dbForConsole -> updateDocument ( 'projects' , $project -> getId (), $project
2022-05-24 02:54:50 +12:00
-> setAttribute ( 'auths' , $auths ));
2021-03-01 00:40:59 +13:00
2021-07-26 02:47:18 +12:00
$response -> dynamic ( $project , Response :: MODEL_PROJECT );
2021-03-01 00:40:59 +13:00
});
2021-03-01 04:00:27 +13:00
App :: patch ( '/v1/projects/:projectId/auth/:method' )
-> desc ( 'Update Project auth method status. Use this endpoint to enable or disable a given auth method for this project.' )
2021-03-01 00:40:59 +13:00
-> groups ([ 'api' , 'projects' ])
-> label ( 'scope' , 'projects.write' )
2021-04-23 18:31:22 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2021-03-01 00:40:59 +13:00
-> label ( 'sdk.namespace' , 'projects' )
2021-03-01 04:00:27 +13:00
-> label ( 'sdk.method' , 'updateAuthStatus' )
2021-03-01 00:40:59 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_PROJECT )
-> param ( 'projectId' , '' , new UID (), 'Project unique ID.' )
2021-06-07 17:17:29 +12:00
-> param ( 'method' , '' , new WhiteList ( \array_keys ( Config :: getParam ( 'auth' )), true ), 'Auth Method. Possible values: ' . implode ( ',' , \array_keys ( Config :: getParam ( 'auth' ))), false )
2021-03-01 04:00:27 +13:00
-> param ( 'status' , false , new Boolean ( true ), 'Set the status of this auth method.' )
2021-03-01 00:40:59 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , string $method , bool $status , Response $response , Database $dbForConsole ) {
2021-03-01 00:40:59 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2021-03-01 04:00:27 +13:00
$auth = Config :: getParam ( 'auth' )[ $method ] ? ? [];
$authKey = $auth [ 'key' ] ? ? '' ;
$status = ( $status === '1' || $status === 'true' || $status === 1 || $status === true );
2021-03-01 00:40:59 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2021-03-01 00:40:59 +13:00
}
2021-08-06 19:42:31 +12:00
$auths = $project -> getAttribute ( 'auths' , []);
$auths [ $authKey ] = $status ;
$project = $dbForConsole -> updateDocument ( 'projects' , $project -> getId (), $project -> setAttribute ( 'auths' , $auths ));
2021-03-01 00:40:59 +13:00
2021-07-26 02:47:18 +12:00
$response -> dynamic ( $project , Response :: MODEL_PROJECT );
2021-03-01 00:40:59 +13:00
});
2020-06-29 05:31:21 +12:00
App :: delete ( '/v1/projects/:projectId' )
2019-12-15 08:33:29 +13:00
-> desc ( 'Delete Project' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2019-12-15 08:33:29 +13:00
-> label ( 'scope' , 'projects.write' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2019-12-15 08:33:29 +13:00
-> label ( 'sdk.namespace' , 'projects' )
2020-01-31 05:18:46 +13:00
-> label ( 'sdk.method' , 'delete' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_NOCONTENT )
-> label ( 'sdk.response.model' , Response :: MODEL_NONE )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , '' , new UID (), 'Project unique ID.' )
2021-11-26 09:03:11 +13:00
-> param ( 'password' , '' , new Password (), 'Your user password for confirmation. Must be at least 8 chars.' )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
-> inject ( 'user' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2020-12-27 05:33:36 +13:00
-> inject ( 'deletes' )
2022-05-09 03:25:01 +12:00
-> action ( function ( string $projectId , string $password , Response $response , Document $user , Database $dbForConsole , Delete $deletes ) {
2020-07-01 03:46:42 +12:00
2022-05-05 23:21:31 +12:00
if ( ! Auth :: passwordVerify ( $password , $user -> getAttribute ( 'password' ), $user -> getAttribute ( 'hash' ), $user -> getAttribute ( 'hashOptions' ))) { // Double check user password
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: USER_INVALID_CREDENTIALS );
2020-07-01 03:46:42 +12:00
}
2020-01-31 12:50:17 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2019-12-15 08:33:29 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-15 08:33:29 +13:00
2020-12-19 00:08:58 +13:00
$deletes
2022-04-18 08:34:32 +12:00
-> setType ( DELETE_TYPE_DOCUMENT )
-> setDocument ( $project )
2020-12-19 00:08:58 +13:00
;
2021-06-07 17:17:29 +12:00
2021-05-16 10:41:42 +12:00
if ( ! $dbForConsole -> deleteDocument ( 'teams' , $project -> getAttribute ( 'teamId' , null ))) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: GENERAL_SERVER_ERROR , 'Failed to remove project team from DB' );
2020-07-01 03:46:42 +12:00
}
2019-12-15 08:33:29 +13:00
2021-05-16 10:41:42 +12:00
if ( ! $dbForConsole -> deleteDocument ( 'projects' , $projectId )) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: GENERAL_SERVER_ERROR , 'Failed to remove project from DB' );
2019-12-18 23:24:54 +13:00
}
2020-07-01 03:46:42 +12:00
$response -> noContent ();
2020-12-27 05:33:36 +13:00
});
2019-12-18 23:24:54 +13:00
// Webhooks
2020-06-29 05:31:21 +12:00
App :: post ( '/v1/projects/:projectId/webhooks' )
2020-02-01 11:34:07 +13:00
-> desc ( 'Create Webhook' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2020-02-01 11:34:07 +13:00
-> label ( 'scope' , 'projects.write' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2020-02-01 11:34:07 +13:00
-> label ( 'sdk.namespace' , 'projects' )
-> label ( 'sdk.method' , 'createWebhook' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_CREATED )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_WEBHOOK )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , null , new UID (), 'Project unique ID.' )
-> param ( 'name' , null , new Text ( 128 ), 'Webhook name. Max length: 128 chars.' )
2022-05-13 06:41:04 +12:00
-> param ( 'events' , null , new ArrayList ( new Event (), APP_LIMIT_ARRAY_PARAMS_SIZE ), 'Events list. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' events are allowed.' )
2022-02-17 04:16:37 +13:00
-> param ( 'url' , null , new URL ([ 'http' , 'https' ]), 'Webhook URL.' )
2020-09-11 02:40:14 +12:00
-> param ( 'security' , false , new Boolean ( true ), 'Certificate verification, false for disabled or true for enabled.' )
-> param ( 'httpUser' , '' , new Text ( 256 ), 'Webhook HTTP user. Max length: 256 chars.' , true )
-> param ( 'httpPass' , '' , new Text ( 256 ), 'Webhook HTTP password. Max length: 256 chars.' , true )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , string $name , array $events , string $url , bool $security , string $httpUser , string $httpPass , Response $response , Database $dbForConsole ) {
2020-02-01 11:34:07 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2020-02-01 11:34:07 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2020-02-01 11:34:07 +13:00
2022-02-22 00:11:48 +13:00
$security = ( bool ) filter_var ( $security , FILTER_VALIDATE_BOOLEAN );
2020-07-01 03:46:42 +12:00
2021-05-16 10:41:42 +12:00
$webhook = new Document ([
2022-08-15 02:22:38 +12:00
'$id' => ID :: unique (),
2022-08-02 21:21:53 +12:00
'$permissions' => [
2022-08-14 17:21:11 +12:00
Permission :: read ( Role :: any ()),
Permission :: update ( Role :: any ()),
Permission :: delete ( Role :: any ()),
2022-08-02 21:21:53 +12:00
],
2022-06-16 19:50:52 +12:00
'projectInternalId' => $project -> getInternalId (),
2021-08-31 02:24:50 +12:00
'projectId' => $project -> getId (),
2020-07-01 03:46:42 +12:00
'name' => $name ,
'events' => $events ,
'url' => $url ,
2020-07-09 21:11:42 +12:00
'security' => $security ,
2020-07-01 03:46:42 +12:00
'httpUser' => $httpUser ,
'httpPass' => $httpPass ,
2022-06-08 03:11:07 +12:00
'signatureKey' => \bin2hex ( \random_bytes ( 64 )),
2020-07-01 03:46:42 +12:00
]);
2021-09-01 20:43:35 +12:00
$webhook = $dbForConsole -> createDocument ( 'webhooks' , $webhook );
2021-08-31 02:24:50 +12:00
2021-10-07 00:56:44 +13:00
$dbForConsole -> deleteCachedDocument ( 'projects' , $project -> getId ());
2020-07-01 03:46:42 +12:00
2022-09-07 23:02:36 +12:00
$response
-> setStatusCode ( Response :: STATUS_CODE_CREATED )
-> dynamic ( $webhook , Response :: MODEL_WEBHOOK );
2020-12-27 05:33:36 +13:00
});
2020-02-01 11:34:07 +13:00
2020-06-29 05:31:21 +12:00
App :: get ( '/v1/projects/:projectId/webhooks' )
2019-12-18 23:24:54 +13:00
-> desc ( 'List Webhooks' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2019-12-18 23:24:54 +13:00
-> label ( 'scope' , 'projects.read' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2019-12-18 23:24:54 +13:00
-> label ( 'sdk.namespace' , 'projects' )
-> label ( 'sdk.method' , 'listWebhooks' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_WEBHOOK_LIST )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , '' , new UID (), 'Project unique ID.' )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , Response $response , Database $dbForConsole ) {
2019-12-18 23:24:54 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2019-12-18 23:24:54 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-18 23:24:54 +13:00
2021-09-01 20:43:35 +12:00
$webhooks = $dbForConsole -> find ( 'webhooks' , [
2022-08-12 11:53:52 +12:00
Query :: equal ( 'projectInternalId' , [ $project -> getInternalId ()]),
Query :: limit ( 5000 ),
]);
2019-12-18 23:24:54 +13:00
2021-07-26 02:47:18 +12:00
$response -> dynamic ( new Document ([
2021-05-27 22:09:14 +12:00
'webhooks' => $webhooks ,
2022-02-27 22:57:09 +13:00
'total' => count ( $webhooks ),
2020-08-15 09:56:50 +12:00
]), Response :: MODEL_WEBHOOK_LIST );
2020-12-27 05:33:36 +13:00
});
2019-12-18 23:24:54 +13:00
2020-06-29 05:31:21 +12:00
App :: get ( '/v1/projects/:projectId/webhooks/:webhookId' )
2019-12-18 23:24:54 +13:00
-> desc ( 'Get Webhook' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2019-12-18 23:24:54 +13:00
-> label ( 'scope' , 'projects.read' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2019-12-18 23:24:54 +13:00
-> label ( 'sdk.namespace' , 'projects' )
-> label ( 'sdk.method' , 'getWebhook' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_WEBHOOK )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , null , new UID (), 'Project unique ID.' )
-> param ( 'webhookId' , null , new UID (), 'Webhook unique ID.' )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , string $webhookId , Response $response , Database $dbForConsole ) {
2019-12-18 23:24:54 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2019-12-18 23:24:54 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-18 23:24:54 +13:00
2021-09-01 20:43:35 +12:00
$webhook = $dbForConsole -> findOne ( 'webhooks' , [
2022-08-12 11:53:52 +12:00
Query :: equal ( '_uid' , [ $webhookId ]),
Query :: equal ( 'projectInternalId' , [ $project -> getInternalId ()]),
2021-09-01 20:25:54 +12:00
]);
2019-12-18 23:24:54 +13:00
2021-09-14 18:57:55 +12:00
if ( $webhook === false || $webhook -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: WEBHOOK_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-18 23:24:54 +13:00
2021-07-26 02:47:18 +12:00
$response -> dynamic ( $webhook , Response :: MODEL_WEBHOOK );
2020-12-27 05:33:36 +13:00
});
2019-12-18 23:24:54 +13:00
2020-06-29 05:31:21 +12:00
App :: put ( '/v1/projects/:projectId/webhooks/:webhookId' )
2019-12-18 23:24:54 +13:00
-> desc ( 'Update Webhook' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2019-12-18 23:24:54 +13:00
-> label ( 'scope' , 'projects.write' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2019-12-18 23:24:54 +13:00
-> label ( 'sdk.namespace' , 'projects' )
-> label ( 'sdk.method' , 'updateWebhook' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_WEBHOOK )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , null , new UID (), 'Project unique ID.' )
-> param ( 'webhookId' , null , new UID (), 'Webhook unique ID.' )
-> param ( 'name' , null , new Text ( 128 ), 'Webhook name. Max length: 128 chars.' )
2022-05-13 06:41:04 +12:00
-> param ( 'events' , null , new ArrayList ( new Event (), APP_LIMIT_ARRAY_PARAMS_SIZE ), 'Events list. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' events are allowed.' )
2022-02-17 04:16:37 +13:00
-> param ( 'url' , null , new URL ([ 'http' , 'https' ]), 'Webhook URL.' )
2020-09-11 02:40:14 +12:00
-> param ( 'security' , false , new Boolean ( true ), 'Certificate verification, false for disabled or true for enabled.' )
-> param ( 'httpUser' , '' , new Text ( 256 ), 'Webhook HTTP user. Max length: 256 chars.' , true )
-> param ( 'httpPass' , '' , new Text ( 256 ), 'Webhook HTTP password. Max length: 256 chars.' , true )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-06-21 06:35:33 +12:00
-> action ( function ( string $projectId , string $webhookId , string $name , array $events , string $url , bool $security , string $httpUser , string $httpPass , Response $response , Database $dbForConsole ) {
2019-12-18 23:24:54 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2019-12-18 23:24:54 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-18 23:24:54 +13:00
2020-07-01 03:46:42 +12:00
$security = ( $security === '1' || $security === 'true' || $security === 1 || $security === true );
2021-09-01 20:43:35 +12:00
$webhook = $dbForConsole -> findOne ( 'webhooks' , [
2022-08-12 11:53:52 +12:00
Query :: equal ( '_uid' , [ $webhookId ]),
Query :: equal ( 'projectInternalId' , [ $project -> getInternalId ()]),
2021-09-01 20:25:54 +12:00
]);
2020-07-01 03:46:42 +12:00
2021-09-14 18:57:55 +12:00
if ( $webhook === false || $webhook -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: WEBHOOK_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-18 23:24:54 +13:00
2021-08-31 02:24:50 +12:00
$webhook
-> setAttribute ( 'name' , $name )
-> setAttribute ( 'events' , $events )
-> setAttribute ( 'url' , $url )
-> setAttribute ( 'security' , $security )
-> setAttribute ( 'httpUser' , $httpUser )
2021-09-14 18:57:55 +12:00
-> setAttribute ( 'httpPass' , $httpPass )
;
2020-07-01 03:46:42 +12:00
2022-06-21 06:35:33 +12:00
$dbForConsole -> updateDocument ( 'webhooks' , $webhook -> getId (), $webhook );
$dbForConsole -> deleteCachedDocument ( 'projects' , $project -> getId ());
$response -> dynamic ( $webhook , Response :: MODEL_WEBHOOK );
});
App :: patch ( '/v1/projects/:projectId/webhooks/:webhookId/signature' )
-> desc ( 'Update Webhook Signature Key' )
-> groups ([ 'api' , 'projects' ])
-> label ( 'scope' , 'projects.write' )
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
-> label ( 'sdk.namespace' , 'projects' )
-> label ( 'sdk.method' , 'updateWebhookSignature' )
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_WEBHOOK )
-> param ( 'projectId' , null , new UID (), 'Project unique ID.' )
-> param ( 'webhookId' , null , new UID (), 'Webhook unique ID.' )
-> inject ( 'response' )
-> inject ( 'dbForConsole' )
-> action ( function ( string $projectId , string $webhookId , Response $response , Database $dbForConsole ) {
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2022-06-08 19:19:50 +12:00
}
2020-07-01 03:46:42 +12:00
2022-06-21 06:35:33 +12:00
$webhook = $dbForConsole -> findOne ( 'webhooks' , [
2022-08-12 11:53:52 +12:00
Query :: equal ( '_uid' , [ $webhookId ]),
Query :: equal ( 'projectInternalId' , [ $project -> getInternalId ()]),
2022-06-21 06:35:33 +12:00
]);
if ( $webhook === false || $webhook -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: WEBHOOK_NOT_FOUND );
2022-06-08 19:19:50 +12:00
}
2020-07-01 03:46:42 +12:00
2022-06-21 06:35:33 +12:00
$webhook -> setAttribute ( 'signatureKey' , \bin2hex ( \random_bytes ( 64 )));
2022-06-08 19:19:50 +12:00
$dbForConsole -> updateDocument ( 'webhooks' , $webhook -> getId (), $webhook );
2021-10-07 00:56:44 +13:00
$dbForConsole -> deleteCachedDocument ( 'projects' , $project -> getId ());
2021-06-07 17:17:29 +12:00
2021-07-26 02:47:18 +12:00
$response -> dynamic ( $webhook , Response :: MODEL_WEBHOOK );
2020-12-27 05:33:36 +13:00
});
2019-12-18 23:24:54 +13:00
2020-06-29 05:31:21 +12:00
App :: delete ( '/v1/projects/:projectId/webhooks/:webhookId' )
2019-12-18 23:24:54 +13:00
-> desc ( 'Delete Webhook' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2019-12-18 23:24:54 +13:00
-> label ( 'scope' , 'projects.write' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2019-12-18 23:24:54 +13:00
-> label ( 'sdk.namespace' , 'projects' )
-> label ( 'sdk.method' , 'deleteWebhook' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_NOCONTENT )
-> label ( 'sdk.response.model' , Response :: MODEL_NONE )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , null , new UID (), 'Project unique ID.' )
-> param ( 'webhookId' , null , new UID (), 'Webhook unique ID.' )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , string $webhookId , Response $response , Database $dbForConsole ) {
2019-12-18 23:24:54 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2019-12-18 23:24:54 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-18 23:24:54 +13:00
2021-09-01 20:43:35 +12:00
$webhook = $dbForConsole -> findOne ( 'webhooks' , [
2022-08-12 11:53:52 +12:00
Query :: equal ( '_uid' , [ $webhookId ]),
Query :: equal ( 'projectInternalId' , [ $project -> getInternalId ()]),
2021-09-01 20:25:54 +12:00
]);
2021-08-31 02:24:50 +12:00
2022-05-24 02:54:50 +12:00
if ( $webhook === false || $webhook -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: WEBHOOK_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-18 23:24:54 +13:00
2021-09-01 20:43:35 +12:00
$dbForConsole -> deleteDocument ( 'webhooks' , $webhook -> getId ());
2021-08-31 02:24:50 +12:00
2021-10-07 00:56:44 +13:00
$dbForConsole -> deleteCachedDocument ( 'projects' , $project -> getId ());
2020-07-01 03:46:42 +12:00
$response -> noContent ();
2020-12-27 05:33:36 +13:00
});
2019-12-18 23:24:54 +13:00
// Keys
2020-06-29 05:31:21 +12:00
App :: post ( '/v1/projects/:projectId/keys' )
2020-02-01 11:34:07 +13:00
-> desc ( 'Create Key' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2020-02-01 11:34:07 +13:00
-> label ( 'scope' , 'projects.write' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2019-12-18 23:24:54 +13:00
-> label ( 'sdk.namespace' , 'projects' )
2020-02-01 11:34:07 +13:00
-> label ( 'sdk.method' , 'createKey' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_CREATED )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_KEY )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , null , new UID (), 'Project unique ID.' )
-> param ( 'name' , null , new Text ( 128 ), 'Key name. Max length: 128 chars.' )
2022-05-01 19:54:58 +12:00
-> param ( 'scopes' , null , new ArrayList ( new WhiteList ( array_keys ( Config :: getParam ( 'scopes' )), true ), APP_LIMIT_ARRAY_PARAMS_SIZE ), 'Key scopes list. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' scopes are allowed.' )
2022-09-05 09:33:52 +12:00
-> param ( 'expire' , null , new DatetimeValidator (), 'Expiration time in ISO 8601 format. Use null for unlimited expiration.' , true )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-07-14 01:55:57 +12:00
-> action ( function ( string $projectId , string $name , array $scopes , ? string $expire , Response $response , Database $dbForConsole ) {
2019-12-18 23:24:54 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2019-12-18 23:24:54 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-18 23:24:54 +13:00
2021-05-16 10:41:42 +12:00
$key = new Document ([
2022-08-15 02:22:38 +12:00
'$id' => ID :: unique (),
2022-08-02 21:21:53 +12:00
'$permissions' => [
2022-08-14 17:21:11 +12:00
Permission :: read ( Role :: any ()),
Permission :: update ( Role :: any ()),
Permission :: delete ( Role :: any ()),
2022-08-02 21:21:53 +12:00
],
2022-06-16 19:50:52 +12:00
'projectInternalId' => $project -> getInternalId (),
2021-08-31 02:24:50 +12:00
'projectId' => $project -> getId (),
2020-07-01 03:46:42 +12:00
'name' => $name ,
'scopes' => $scopes ,
2022-06-01 03:41:12 +12:00
'expire' => $expire ,
2022-08-05 22:20:48 +12:00
'sdks' => [],
2022-08-19 21:54:26 +12:00
'accessedAt' => null ,
2020-07-01 03:46:42 +12:00
'secret' => \bin2hex ( \random_bytes ( 128 )),
]);
2021-09-01 20:43:35 +12:00
$key = $dbForConsole -> createDocument ( 'keys' , $key );
2021-08-31 02:24:50 +12:00
2021-10-07 00:56:44 +13:00
$dbForConsole -> deleteCachedDocument ( 'projects' , $project -> getId ());
2020-07-01 03:46:42 +12:00
2022-09-07 23:02:36 +12:00
$response
-> setStatusCode ( Response :: STATUS_CODE_CREATED )
-> dynamic ( $key , Response :: MODEL_KEY );
2020-12-27 05:33:36 +13:00
});
2019-12-18 23:24:54 +13:00
2020-06-29 05:31:21 +12:00
App :: get ( '/v1/projects/:projectId/keys' )
2020-02-01 11:34:07 +13:00
-> desc ( 'List Keys' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2020-02-01 11:34:07 +13:00
-> label ( 'scope' , 'projects.read' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2020-02-01 11:34:07 +13:00
-> label ( 'sdk.namespace' , 'projects' )
-> label ( 'sdk.method' , 'listKeys' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_KEY_LIST )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , null , new UID (), 'Project unique ID.' )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , Response $response , Database $dbForConsole ) {
2021-06-07 17:17:29 +12:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2020-07-01 03:46:42 +12:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-02-01 11:34:07 +13:00
}
2020-07-01 03:46:42 +12:00
2021-09-01 20:43:35 +12:00
$keys = $dbForConsole -> find ( 'keys' , [
2022-08-12 11:53:52 +12:00
Query :: equal ( 'projectInternalId' , [ $project -> getInternalId ()]),
Query :: limit ( 5000 ),
]);
2020-08-15 09:56:50 +12:00
2021-07-26 02:47:18 +12:00
$response -> dynamic ( new Document ([
2021-05-27 22:09:14 +12:00
'keys' => $keys ,
2022-02-27 22:57:09 +13:00
'total' => count ( $keys ),
2020-08-15 09:56:50 +12:00
]), Response :: MODEL_KEY_LIST );
2020-12-27 05:33:36 +13:00
});
2020-02-01 11:34:07 +13:00
2020-06-29 05:31:21 +12:00
App :: get ( '/v1/projects/:projectId/keys/:keyId' )
2020-02-01 11:34:07 +13:00
-> desc ( 'Get Key' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2020-02-01 11:34:07 +13:00
-> label ( 'scope' , 'projects.read' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2020-02-01 11:34:07 +13:00
-> label ( 'sdk.namespace' , 'projects' )
-> label ( 'sdk.method' , 'getKey' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_KEY )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , null , new UID (), 'Project unique ID.' )
-> param ( 'keyId' , null , new UID (), 'Key unique ID.' )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , string $keyId , Response $response , Database $dbForConsole ) {
2021-08-31 02:24:50 +12:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2020-02-01 11:34:07 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2020-02-01 11:34:07 +13:00
2021-09-01 20:43:35 +12:00
$key = $dbForConsole -> findOne ( 'keys' , [
2022-08-12 11:53:52 +12:00
Query :: equal ( '_uid' , [ $keyId ]),
Query :: equal ( 'projectInternalId' , [ $project -> getInternalId ()]),
2021-09-01 20:25:54 +12:00
]);
2020-02-01 11:34:07 +13:00
2021-09-14 18:57:55 +12:00
if ( $key === false || $key -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: KEY_NOT_FOUND );
2020-02-01 11:34:07 +13:00
}
2020-07-01 03:46:42 +12:00
2021-07-26 02:47:18 +12:00
$response -> dynamic ( $key , Response :: MODEL_KEY );
2020-12-27 05:33:36 +13:00
});
2020-02-01 11:34:07 +13:00
2020-06-29 05:31:21 +12:00
App :: put ( '/v1/projects/:projectId/keys/:keyId' )
2019-12-18 23:24:54 +13:00
-> desc ( 'Update Key' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2019-12-18 23:24:54 +13:00
-> label ( 'scope' , 'projects.write' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2019-12-18 23:24:54 +13:00
-> label ( 'sdk.namespace' , 'projects' )
-> label ( 'sdk.method' , 'updateKey' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_KEY )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , null , new UID (), 'Project unique ID.' )
-> param ( 'keyId' , null , new UID (), 'Key unique ID.' )
-> param ( 'name' , null , new Text ( 128 ), 'Key name. Max length: 128 chars.' )
2022-05-01 19:54:58 +12:00
-> param ( 'scopes' , null , new ArrayList ( new WhiteList ( array_keys ( Config :: getParam ( 'scopes' )), true ), APP_LIMIT_ARRAY_PARAMS_SIZE ), 'Key scopes list. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' events are allowed.' )
2022-09-05 09:33:52 +12:00
-> param ( 'expire' , null , new DatetimeValidator (), 'Expiration time in ISO 8601 format. Use null for unlimited expiration.' , true )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-07-14 01:55:57 +12:00
-> action ( function ( string $projectId , string $keyId , string $name , array $scopes , ? string $expire , Response $response , Database $dbForConsole ) {
2019-12-18 23:24:54 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2019-12-18 23:24:54 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-18 23:24:54 +13:00
2021-09-01 20:43:35 +12:00
$key = $dbForConsole -> findOne ( 'keys' , [
2022-08-12 11:53:52 +12:00
Query :: equal ( '_uid' , [ $keyId ]),
Query :: equal ( 'projectInternalId' , [ $project -> getInternalId ()]),
2021-09-01 20:25:54 +12:00
]);
2019-12-18 23:24:54 +13:00
2021-09-14 18:57:55 +12:00
if ( $key === false || $key -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: KEY_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-18 23:24:54 +13:00
2021-09-14 18:57:55 +12:00
$key
-> setAttribute ( 'name' , $name )
-> setAttribute ( 'scopes' , $scopes )
2022-06-01 03:41:12 +12:00
-> setAttribute ( 'expire' , $expire )
2021-09-14 18:57:55 +12:00
;
2019-12-18 23:24:54 +13:00
2021-09-01 20:43:35 +12:00
$dbForConsole -> updateDocument ( 'keys' , $key -> getId (), $key );
2019-12-18 23:24:54 +13:00
2021-10-07 00:56:44 +13:00
$dbForConsole -> deleteCachedDocument ( 'projects' , $project -> getId ());
2021-06-07 17:17:29 +12:00
2021-07-26 02:47:18 +12:00
$response -> dynamic ( $key , Response :: MODEL_KEY );
2020-12-27 05:33:36 +13:00
});
2019-12-18 23:24:54 +13:00
2020-06-29 05:31:21 +12:00
App :: delete ( '/v1/projects/:projectId/keys/:keyId' )
2019-12-18 23:24:54 +13:00
-> desc ( 'Delete Key' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2019-12-18 23:24:54 +13:00
-> label ( 'scope' , 'projects.write' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2019-12-18 23:24:54 +13:00
-> label ( 'sdk.namespace' , 'projects' )
-> label ( 'sdk.method' , 'deleteKey' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_NOCONTENT )
-> label ( 'sdk.response.model' , Response :: MODEL_NONE )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , null , new UID (), 'Project unique ID.' )
-> param ( 'keyId' , null , new UID (), 'Key unique ID.' )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , string $keyId , Response $response , Database $dbForConsole ) {
2019-12-18 23:24:54 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2019-12-18 23:24:54 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-18 23:24:54 +13:00
2021-09-01 20:43:35 +12:00
$key = $dbForConsole -> findOne ( 'keys' , [
2022-08-12 11:53:52 +12:00
Query :: equal ( '_uid' , [ $keyId ]),
Query :: equal ( 'projectInternalId' , [ $project -> getInternalId ()]),
2021-09-01 20:25:54 +12:00
]);
2021-08-31 02:24:50 +12:00
2022-05-24 02:54:50 +12:00
if ( $key === false || $key -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: KEY_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-18 23:24:54 +13:00
2021-09-01 20:43:35 +12:00
$dbForConsole -> deleteDocument ( 'keys' , $key -> getId ());
2021-08-31 02:24:50 +12:00
2021-10-07 00:56:44 +13:00
$dbForConsole -> deleteCachedDocument ( 'projects' , $project -> getId ());
2020-07-01 03:46:42 +12:00
$response -> noContent ();
2020-12-27 05:33:36 +13:00
});
2019-12-18 23:24:54 +13:00
// Platforms
2020-06-29 05:31:21 +12:00
App :: post ( '/v1/projects/:projectId/platforms' )
2019-12-18 23:24:54 +13:00
-> desc ( 'Create Platform' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2019-12-18 23:24:54 +13:00
-> label ( 'scope' , 'projects.write' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2019-12-18 23:24:54 +13:00
-> label ( 'sdk.namespace' , 'projects' )
-> label ( 'sdk.method' , 'createPlatform' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_CREATED )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_PLATFORM )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , null , new UID (), 'Project unique ID.' )
2022-03-06 12:35:44 +13:00
-> param ( 'type' , null , new WhiteList ([ Origin :: CLIENT_TYPE_WEB , Origin :: CLIENT_TYPE_FLUTTER_IOS , Origin :: CLIENT_TYPE_FLUTTER_ANDROID , Origin :: CLIENT_TYPE_FLUTTER_LINUX , Origin :: CLIENT_TYPE_FLUTTER_MACOS , Origin :: CLIENT_TYPE_FLUTTER_WINDOWS , Origin :: CLIENT_TYPE_APPLE_IOS , Origin :: CLIENT_TYPE_APPLE_MACOS , Origin :: CLIENT_TYPE_APPLE_WATCHOS , Origin :: CLIENT_TYPE_APPLE_TVOS , Origin :: CLIENT_TYPE_ANDROID , Origin :: CLIENT_TYPE_UNITY ], true ), 'Platform type.' )
2020-09-11 02:40:14 +12:00
-> param ( 'name' , null , new Text ( 128 ), 'Platform name. Max length: 128 chars.' )
2021-09-28 23:24:54 +13:00
-> param ( 'key' , '' , new Text ( 256 ), 'Package name for Android or bundle ID for iOS or macOS. Max length: 256 chars.' , true )
2020-09-11 02:40:14 +12:00
-> param ( 'store' , '' , new Text ( 256 ), 'App store or Google Play store ID. Max length: 256 chars.' , true )
2022-05-13 06:53:54 +12:00
-> param ( 'hostname' , '' , new Hostname (), 'Platform client hostname. Max length: 256 chars.' , true )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , string $type , string $name , string $key , string $store , string $hostname , Response $response , Database $dbForConsole ) {
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2019-12-18 23:24:54 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-18 23:24:54 +13:00
2021-05-16 10:41:42 +12:00
$platform = new Document ([
2022-08-15 02:22:38 +12:00
'$id' => ID :: unique (),
2022-08-02 21:21:53 +12:00
'$permissions' => [
2022-08-15 22:11:17 +12:00
Permission :: read ( Role :: any ()),
Permission :: update ( Role :: any ()),
Permission :: delete ( Role :: any ()),
2022-08-02 21:21:53 +12:00
],
2022-06-16 19:50:52 +12:00
'projectInternalId' => $project -> getInternalId (),
2021-08-31 02:24:50 +12:00
'projectId' => $project -> getId (),
2020-07-01 03:46:42 +12:00
'type' => $type ,
'name' => $name ,
'key' => $key ,
'store' => $store ,
2022-06-16 00:46:52 +12:00
'hostname' => $hostname
2020-07-01 03:46:42 +12:00
]);
2021-09-01 20:43:35 +12:00
$platform = $dbForConsole -> createDocument ( 'platforms' , $platform );
2021-08-31 02:24:50 +12:00
2021-10-07 00:56:44 +13:00
$dbForConsole -> deleteCachedDocument ( 'projects' , $project -> getId ());
2020-07-01 03:46:42 +12:00
2022-09-07 23:02:36 +12:00
$response
-> setStatusCode ( Response :: STATUS_CODE_CREATED )
-> dynamic ( $platform , Response :: MODEL_PLATFORM );
2020-12-27 05:33:36 +13:00
});
2021-06-07 17:17:29 +12:00
2020-06-29 05:31:21 +12:00
App :: get ( '/v1/projects/:projectId/platforms' )
2020-02-01 11:34:07 +13:00
-> desc ( 'List Platforms' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2020-02-01 11:34:07 +13:00
-> label ( 'scope' , 'projects.read' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2020-02-01 11:34:07 +13:00
-> label ( 'sdk.namespace' , 'projects' )
-> label ( 'sdk.method' , 'listPlatforms' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_PLATFORM_LIST )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , '' , new UID (), 'Project unique ID.' )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , Response $response , Database $dbForConsole ) {
2020-02-01 11:34:07 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2020-02-01 11:34:07 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-02-01 11:34:07 +13:00
}
2020-07-01 03:46:42 +12:00
2021-09-01 20:43:35 +12:00
$platforms = $dbForConsole -> find ( 'platforms' , [
2022-08-12 11:53:52 +12:00
Query :: equal ( 'projectId' , [ $project -> getId ()]),
Query :: limit ( 5000 ),
]);
2020-07-01 03:46:42 +12:00
2021-07-26 02:47:18 +12:00
$response -> dynamic ( new Document ([
2021-05-27 22:09:14 +12:00
'platforms' => $platforms ,
2022-02-27 22:57:09 +13:00
'total' => count ( $platforms ),
2020-08-15 09:56:50 +12:00
]), Response :: MODEL_PLATFORM_LIST );
2020-12-27 05:33:36 +13:00
});
2020-02-01 11:34:07 +13:00
2020-06-29 05:31:21 +12:00
App :: get ( '/v1/projects/:projectId/platforms/:platformId' )
2020-02-01 11:34:07 +13:00
-> desc ( 'Get Platform' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2020-02-01 11:34:07 +13:00
-> label ( 'scope' , 'projects.read' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2020-02-01 11:34:07 +13:00
-> label ( 'sdk.namespace' , 'projects' )
-> label ( 'sdk.method' , 'getPlatform' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_PLATFORM )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , null , new UID (), 'Project unique ID.' )
-> param ( 'platformId' , null , new UID (), 'Platform unique ID.' )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , string $platformId , Response $response , Database $dbForConsole ) {
2020-02-01 11:34:07 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2020-02-01 11:34:07 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2020-02-01 11:34:07 +13:00
2021-09-01 20:43:35 +12:00
$platform = $dbForConsole -> findOne ( 'platforms' , [
2022-08-12 11:53:52 +12:00
Query :: equal ( '_uid' , [ $platformId ]),
Query :: equal ( 'projectInternalId' , [ $project -> getInternalId ()]),
2021-09-01 20:25:54 +12:00
]);
2020-02-01 11:34:07 +13:00
2021-09-14 18:57:55 +12:00
if ( $platform === false || $platform -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PLATFORM_NOT_FOUND );
2020-02-01 11:34:07 +13:00
}
2020-07-01 03:46:42 +12:00
2021-07-26 02:47:18 +12:00
$response -> dynamic ( $platform , Response :: MODEL_PLATFORM );
2020-12-27 05:33:36 +13:00
});
2019-12-18 23:24:54 +13:00
2020-06-29 05:31:21 +12:00
App :: put ( '/v1/projects/:projectId/platforms/:platformId' )
2019-12-18 23:24:54 +13:00
-> desc ( 'Update Platform' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2019-12-18 23:24:54 +13:00
-> label ( 'scope' , 'projects.write' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2019-12-18 23:24:54 +13:00
-> label ( 'sdk.namespace' , 'projects' )
-> label ( 'sdk.method' , 'updatePlatform' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_PLATFORM )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , null , new UID (), 'Project unique ID.' )
-> param ( 'platformId' , null , new UID (), 'Platform unique ID.' )
-> param ( 'name' , null , new Text ( 128 ), 'Platform name. Max length: 128 chars.' )
-> param ( 'key' , '' , new Text ( 256 ), 'Package name for android or bundle ID for iOS. Max length: 256 chars.' , true )
-> param ( 'store' , '' , new Text ( 256 ), 'App store or Google Play store ID. Max length: 256 chars.' , true )
2022-05-13 06:53:54 +12:00
-> param ( 'hostname' , '' , new Hostname (), 'Platform client URL. Max length: 256 chars.' , true )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , string $platformId , string $name , string $key , string $store , string $hostname , Response $response , Database $dbForConsole ) {
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2019-12-18 23:24:54 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-18 23:24:54 +13:00
2021-09-01 20:43:35 +12:00
$platform = $dbForConsole -> findOne ( 'platforms' , [
2022-08-12 11:53:52 +12:00
Query :: equal ( '_uid' , [ $platformId ]),
Query :: equal ( 'projectInternalId' , [ $project -> getInternalId ()]),
2021-09-01 20:25:54 +12:00
]);
2019-12-18 23:24:54 +13:00
2021-09-14 18:57:55 +12:00
if ( $platform === false || $platform -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PLATFORM_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-18 23:24:54 +13:00
2020-07-01 03:46:42 +12:00
$platform
-> setAttribute ( 'name' , $name )
-> setAttribute ( 'key' , $key )
-> setAttribute ( 'store' , $store )
-> setAttribute ( 'hostname' , $hostname )
;
2019-12-18 23:24:54 +13:00
2021-09-01 20:43:35 +12:00
$dbForConsole -> updateDocument ( 'platforms' , $platform -> getId (), $platform );
2020-07-01 03:46:42 +12:00
2021-10-07 00:56:44 +13:00
$dbForConsole -> deleteCachedDocument ( 'projects' , $project -> getId ());
2021-05-16 10:41:42 +12:00
2021-07-26 02:47:18 +12:00
$response -> dynamic ( $platform , Response :: MODEL_PLATFORM );
2020-12-27 05:33:36 +13:00
});
2019-12-18 23:24:54 +13:00
2020-06-29 05:31:21 +12:00
App :: delete ( '/v1/projects/:projectId/platforms/:platformId' )
2019-12-18 23:24:54 +13:00
-> desc ( 'Delete Platform' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2019-12-18 23:24:54 +13:00
-> label ( 'scope' , 'projects.write' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2019-12-18 23:24:54 +13:00
-> label ( 'sdk.namespace' , 'projects' )
-> label ( 'sdk.method' , 'deletePlatform' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_NOCONTENT )
-> label ( 'sdk.response.model' , Response :: MODEL_NONE )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , null , new UID (), 'Project unique ID.' )
-> param ( 'platformId' , null , new UID (), 'Platform unique ID.' )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , string $platformId , Response $response , Database $dbForConsole ) {
2019-12-18 23:24:54 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2019-12-18 23:24:54 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-18 23:24:54 +13:00
2021-09-01 20:43:35 +12:00
$platform = $dbForConsole -> findOne ( 'platforms' , [
2022-08-12 11:53:52 +12:00
Query :: equal ( '_uid' , [ $platformId ]),
Query :: equal ( 'projectInternalId' , [ $project -> getInternalId ()]),
2021-09-01 20:25:54 +12:00
]);
2021-08-30 19:33:45 +12:00
2021-09-14 18:57:55 +12:00
if ( $platform === false || $platform -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PLATFORM_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2019-12-18 23:24:54 +13:00
2021-09-01 20:43:35 +12:00
$dbForConsole -> deleteDocument ( 'platforms' , $platformId );
2021-09-01 20:25:54 +12:00
2021-10-07 00:56:44 +13:00
$dbForConsole -> deleteCachedDocument ( 'projects' , $project -> getId ());
2020-07-01 03:46:42 +12:00
$response -> noContent ();
2020-12-27 05:33:36 +13:00
});
2020-02-22 21:10:30 +13:00
// Domains
2020-06-29 05:31:21 +12:00
App :: post ( '/v1/projects/:projectId/domains' )
2020-02-22 21:10:30 +13:00
-> desc ( 'Create Domain' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2020-02-22 21:10:30 +13:00
-> label ( 'scope' , 'projects.write' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2020-02-22 21:10:30 +13:00
-> label ( 'sdk.namespace' , 'projects' )
-> label ( 'sdk.method' , 'createDomain' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_CREATED )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_DOMAIN )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , null , new UID (), 'Project unique ID.' )
-> param ( 'domain' , null , new DomainValidator (), 'Domain name.' )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , string $domain , Response $response , Database $dbForConsole ) {
2020-02-22 21:10:30 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2020-02-22 21:10:30 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2020-02-24 06:05:42 +13:00
2021-09-01 20:43:35 +12:00
$document = $dbForConsole -> findOne ( 'domains' , [
2022-08-12 11:53:52 +12:00
Query :: equal ( 'domain' , [ $domain ]),
Query :: equal ( 'projectInternalId' , [ $project -> getInternalId ()]),
2021-08-31 02:24:50 +12:00
]);
2020-02-24 06:05:42 +13:00
2021-08-31 02:24:50 +12:00
if ( $document && ! $document -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: DOMAIN_ALREADY_EXISTS );
2020-07-01 03:46:42 +12:00
}
2020-02-23 21:59:29 +13:00
2020-07-01 03:46:42 +12:00
$target = new Domain ( App :: getEnv ( '_APP_DOMAIN_TARGET' , '' ));
2020-02-22 21:10:30 +13:00
2020-07-01 03:46:42 +12:00
if ( ! $target -> isKnown () || $target -> isTest ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: GENERAL_SERVER_ERROR , 'Unreachable CNAME target (' . $target -> get () . '), please use a domain with a public suffix.' );
2020-07-01 03:46:42 +12:00
}
2020-02-22 21:10:30 +13:00
2020-07-01 03:46:42 +12:00
$domain = new Domain ( $domain );
2021-05-16 10:41:42 +12:00
$domain = new Document ([
2022-08-15 02:22:38 +12:00
'$id' => ID :: unique (),
2022-08-02 21:21:53 +12:00
'$permissions' => [
2022-08-15 22:11:17 +12:00
Permission :: read ( Role :: any ()),
Permission :: update ( Role :: any ()),
Permission :: delete ( Role :: any ()),
2022-08-02 21:21:53 +12:00
],
2022-06-16 19:50:52 +12:00
'projectInternalId' => $project -> getInternalId (),
2021-08-31 02:24:50 +12:00
'projectId' => $project -> getId (),
2022-07-14 02:02:49 +12:00
'updated' => DateTime :: now (),
2020-07-01 03:46:42 +12:00
'domain' => $domain -> get (),
'tld' => $domain -> getSuffix (),
'registerable' => $domain -> getRegisterable (),
'verification' => false ,
'certificateId' => null ,
]);
2021-09-01 20:43:35 +12:00
$domain = $dbForConsole -> createDocument ( 'domains' , $domain );
2021-08-31 02:24:50 +12:00
2021-10-07 00:56:44 +13:00
$dbForConsole -> deleteCachedDocument ( 'projects' , $project -> getId ());
2020-07-01 03:46:42 +12:00
2022-09-07 23:02:36 +12:00
$response
-> setStatusCode ( Response :: STATUS_CODE_CREATED )
-> dynamic ( $domain , Response :: MODEL_DOMAIN );
2020-12-27 05:33:36 +13:00
});
2020-02-22 21:10:30 +13:00
2020-06-29 05:31:21 +12:00
App :: get ( '/v1/projects/:projectId/domains' )
2020-02-22 21:10:30 +13:00
-> desc ( 'List Domains' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2020-02-22 21:10:30 +13:00
-> label ( 'scope' , 'projects.read' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2020-02-22 21:10:30 +13:00
-> label ( 'sdk.namespace' , 'projects' )
-> label ( 'sdk.method' , 'listDomains' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_DOMAIN_LIST )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , '' , new UID (), 'Project unique ID.' )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , Response $response , Database $dbForConsole ) {
2020-02-22 21:10:30 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2020-02-22 21:10:30 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-02-22 21:10:30 +13:00
}
2020-07-01 03:46:42 +12:00
2021-09-01 20:43:35 +12:00
$domains = $dbForConsole -> find ( 'domains' , [
2022-08-12 11:53:52 +12:00
Query :: equal ( 'projectInternalId' , [ $project -> getInternalId ()]),
Query :: limit ( 5000 ),
]);
2021-06-07 17:17:29 +12:00
2021-07-26 02:47:18 +12:00
$response -> dynamic ( new Document ([
2021-05-27 22:09:14 +12:00
'domains' => $domains ,
2022-02-27 22:57:09 +13:00
'total' => count ( $domains ),
2020-08-15 09:56:50 +12:00
]), Response :: MODEL_DOMAIN_LIST );
2020-12-27 05:33:36 +13:00
});
2020-02-22 21:10:30 +13:00
2020-06-29 05:31:21 +12:00
App :: get ( '/v1/projects/:projectId/domains/:domainId' )
2020-02-22 21:10:30 +13:00
-> desc ( 'Get Domain' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2020-02-22 21:10:30 +13:00
-> label ( 'scope' , 'projects.read' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2020-02-22 21:10:30 +13:00
-> label ( 'sdk.namespace' , 'projects' )
-> label ( 'sdk.method' , 'getDomain' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_DOMAIN )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , null , new UID (), 'Project unique ID.' )
-> param ( 'domainId' , null , new UID (), 'Domain unique ID.' )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , string $domainId , Response $response , Database $dbForConsole ) {
2020-02-22 21:10:30 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2020-02-22 21:10:30 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2020-02-22 21:10:30 +13:00
2021-09-01 20:43:35 +12:00
$domain = $dbForConsole -> findOne ( 'domains' , [
2022-08-12 11:53:52 +12:00
Query :: equal ( '_uid' , [ $domainId ]),
Query :: equal ( 'projectInternalId' , [ $project -> getInternalId ()]),
2021-09-01 20:25:54 +12:00
]);
2020-02-22 21:10:30 +13:00
2021-09-14 18:57:55 +12:00
if ( $domain === false || $domain -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: DOMAIN_NOT_FOUND );
2020-02-22 21:10:30 +13:00
}
2020-07-01 03:46:42 +12:00
2021-07-26 02:47:18 +12:00
$response -> dynamic ( $domain , Response :: MODEL_DOMAIN );
2020-12-27 05:33:36 +13:00
});
2020-02-22 21:10:30 +13:00
2020-06-29 05:31:21 +12:00
App :: patch ( '/v1/projects/:projectId/domains/:domainId/verification' )
2020-02-22 21:10:30 +13:00
-> desc ( 'Update Domain Verification Status' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2020-02-22 21:10:30 +13:00
-> label ( 'scope' , 'projects.write' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2020-02-22 21:10:30 +13:00
-> label ( 'sdk.namespace' , 'projects' )
2020-02-23 21:59:29 +13:00
-> label ( 'sdk.method' , 'updateDomainVerification' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_OK )
-> label ( 'sdk.response.type' , Response :: CONTENT_TYPE_JSON )
-> label ( 'sdk.response.model' , Response :: MODEL_DOMAIN )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , null , new UID (), 'Project unique ID.' )
-> param ( 'domainId' , null , new UID (), 'Domain unique ID.' )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2022-05-07 04:51:02 +12:00
-> action ( function ( string $projectId , string $domainId , Response $response , Database $dbForConsole ) {
2020-02-22 21:10:30 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2020-02-22 21:10:30 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2020-02-22 21:10:30 +13:00
2021-09-01 20:43:35 +12:00
$domain = $dbForConsole -> findOne ( 'domains' , [
2022-08-12 11:53:52 +12:00
Query :: equal ( '_uid' , [ $domainId ]),
Query :: equal ( 'projectInternalId' , [ $project -> getInternalId ()]),
2021-09-01 20:25:54 +12:00
]);
2020-02-23 21:59:29 +13:00
2021-09-14 18:57:55 +12:00
if ( $domain === false || $domain -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: DOMAIN_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2020-02-23 21:59:29 +13:00
2020-07-01 03:46:42 +12:00
$target = new Domain ( App :: getEnv ( '_APP_DOMAIN_TARGET' , '' ));
2020-02-23 22:10:32 +13:00
2020-07-01 03:46:42 +12:00
if ( ! $target -> isKnown () || $target -> isTest ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: GENERAL_SERVER_ERROR , 'Unreachable CNAME target (' . $target -> get () . '), please use a domain with a public suffix.' );
2020-07-01 03:46:42 +12:00
}
2020-02-22 21:10:30 +13:00
2020-07-01 03:46:42 +12:00
if ( $domain -> getAttribute ( 'verification' ) === true ) {
2021-07-26 02:47:18 +12:00
return $response -> dynamic ( $domain , Response :: MODEL_DOMAIN );
2020-07-01 03:46:42 +12:00
}
2020-02-22 21:10:30 +13:00
2021-05-16 10:41:42 +12:00
$validator = new CNAME ( $target -> get ()); // Verify Domain with DNS records
2020-02-22 21:10:30 +13:00
2020-07-01 03:46:42 +12:00
if ( ! $validator -> isValid ( $domain -> getAttribute ( 'domain' , '' ))) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: DOMAIN_VERIFICATION_FAILED );
2020-07-01 03:46:42 +12:00
}
2020-02-22 21:10:30 +13:00
2021-09-14 18:57:55 +12:00
$dbForConsole -> updateDocument ( 'domains' , $domain -> getId (), $domain -> setAttribute ( 'verification' , true ));
2021-10-07 00:56:44 +13:00
$dbForConsole -> deleteCachedDocument ( 'projects' , $project -> getId ());
2020-07-01 03:46:42 +12:00
// Issue a TLS certificate when domain is verified
2022-04-14 00:39:31 +12:00
$event = new Certificate ();
$event
-> setDomain ( $domain )
-> trigger ();
2020-07-01 03:46:42 +12:00
2021-07-26 02:47:18 +12:00
$response -> dynamic ( $domain , Response :: MODEL_DOMAIN );
2020-12-27 05:33:36 +13:00
});
2020-02-22 21:10:30 +13:00
2020-06-29 05:31:21 +12:00
App :: delete ( '/v1/projects/:projectId/domains/:domainId' )
2020-02-22 21:10:30 +13:00
-> desc ( 'Delete Domain' )
2020-06-26 06:32:12 +12:00
-> groups ([ 'api' , 'projects' ])
2020-02-22 21:10:30 +13:00
-> label ( 'scope' , 'projects.write' )
2021-04-16 19:22:17 +12:00
-> label ( 'sdk.auth' , [ APP_AUTH_TYPE_ADMIN ])
2020-02-22 21:10:30 +13:00
-> label ( 'sdk.namespace' , 'projects' )
-> label ( 'sdk.method' , 'deleteDomain' )
2020-11-12 10:02:24 +13:00
-> label ( 'sdk.response.code' , Response :: STATUS_CODE_NOCONTENT )
-> label ( 'sdk.response.model' , Response :: MODEL_NONE )
2020-09-11 02:40:14 +12:00
-> param ( 'projectId' , null , new UID (), 'Project unique ID.' )
-> param ( 'domainId' , null , new UID (), 'Domain unique ID.' )
2020-12-27 05:33:36 +13:00
-> inject ( 'response' )
2021-05-16 10:41:42 +12:00
-> inject ( 'dbForConsole' )
2021-02-05 22:05:46 +13:00
-> inject ( 'deletes' )
2022-05-09 03:25:01 +12:00
-> action ( function ( string $projectId , string $domainId , Response $response , Database $dbForConsole , Delete $deletes ) {
2020-02-22 21:10:30 +13:00
2021-05-16 10:41:42 +12:00
$project = $dbForConsole -> getDocument ( 'projects' , $projectId );
2020-02-22 21:10:30 +13:00
2021-05-16 10:41:42 +12:00
if ( $project -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: PROJECT_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2020-02-22 21:10:30 +13:00
2021-09-01 20:43:35 +12:00
$domain = $dbForConsole -> findOne ( 'domains' , [
2022-08-12 11:53:52 +12:00
Query :: equal ( '_uid' , [ $domainId ]),
Query :: equal ( 'projectInternalId' , [ $project -> getInternalId ()]),
2021-09-01 20:25:54 +12:00
]);
2020-02-22 21:10:30 +13:00
2021-09-14 18:57:55 +12:00
if ( $domain === false || $domain -> isEmpty ()) {
2022-07-27 02:24:32 +12:00
throw new Exception ( Exception :: DOMAIN_NOT_FOUND );
2020-07-01 03:46:42 +12:00
}
2020-02-22 21:10:30 +13:00
2021-09-01 20:43:35 +12:00
$dbForConsole -> deleteDocument ( 'domains' , $domain -> getId ());
2021-08-31 02:24:50 +12:00
2021-10-07 00:56:44 +13:00
$dbForConsole -> deleteCachedDocument ( 'projects' , $project -> getId ());
2021-05-16 10:41:42 +12:00
$deletes
2022-04-18 08:34:32 +12:00
-> setType ( DELETE_TYPE_CERTIFICATES )
-> setDocument ( $domain );
2020-07-01 03:46:42 +12:00
$response -> noContent ();
2021-06-07 17:17:29 +12:00
});