mirror of
https://github.com/appwrite/appwrite
synced 2026-05-12 19:48:41 +00:00
Merge remote-tracking branch 'origin/1.3.x' into feat-db-update-migrations
# Conflicts: # src/Appwrite/Migration/Version/V18.php
This commit is contained in:
commit
5689d47d41
236 changed files with 558 additions and 326 deletions
4
.github/workflows/codeql-analysis.yml
vendored
4
.github/workflows/codeql-analysis.yml
vendored
|
|
@ -1,5 +1,9 @@
|
|||
name: "CodeQL"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
|
|
|
|||
4
.github/workflows/linter.yml
vendored
4
.github/workflows/linter.yml
vendored
|
|
@ -1,5 +1,9 @@
|
|||
name: "Linter"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on: [pull_request]
|
||||
jobs:
|
||||
lint:
|
||||
|
|
|
|||
4
.github/workflows/tests.yml
vendored
4
.github/workflows/tests.yml
vendored
|
|
@ -1,5 +1,9 @@
|
|||
name: "Tests"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on: [pull_request]
|
||||
jobs:
|
||||
tests:
|
||||
|
|
|
|||
|
|
@ -3,10 +3,11 @@
|
|||
## Features
|
||||
- Password dictionary setting allows to compare user's password against command password database [4906](https://github.com/appwrite/appwrite/pull/4906)
|
||||
- Password history setting allows to save user's last used password so that it may not be used again. Maximum number of history saved is 20, which can be configured. Minimum is 0 which means disabled. [#4866](https://github.com/appwrite/appwrite/pull/4866)
|
||||
- Update APIs to check X-Appwrite-Timestamp header [#5024](https://github.com/appwrite/appwrite/pull/5024)
|
||||
|
||||
## Bugs
|
||||
|
||||
- Fix not storing function's response on response codes 5xx [#4610](https://github.com/appwrite/appwrite/pull/4610)
|
||||
- Fix expire to formatTz in create account session [#4985](https://github.com/appwrite/appwrite/pull/4985)
|
||||
|
||||
# Version 1.2.1
|
||||
## Changes
|
||||
|
|
|
|||
|
|
@ -436,6 +436,14 @@ composer lint
|
|||
composer lint <your file path>
|
||||
```
|
||||
|
||||
## Clearing the Cache
|
||||
|
||||
If you need to clear the cache, you can do so by running the following command:
|
||||
|
||||
```bash
|
||||
docker compose exec redis redis-cli FLUSHALL
|
||||
```
|
||||
|
||||
## Tutorials
|
||||
|
||||
From time to time, our team will add tutorials that will help contributors find their way in the Appwrite source code. Below is a list of currently available tutorials:
|
||||
|
|
|
|||
|
|
@ -408,6 +408,11 @@ return [
|
|||
'description' => 'Document with the requested ID already exists.',
|
||||
'code' => 409,
|
||||
],
|
||||
Exception::DOCUMENT_UPDATE_CONFLICT => [
|
||||
'name' => Exception::DOCUMENT_UPDATE_CONFLICT,
|
||||
'description' => 'Remote document is newer than local.',
|
||||
'code' => 409,
|
||||
],
|
||||
|
||||
/** Attributes */
|
||||
Exception::ATTRIBUTE_NOT_FOUND => [
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ return [
|
|||
'description' => 'Client libraries for integrating with Appwrite to build client-based applications and websites. Read the [getting started for web](/docs/getting-started-for-web) or [getting started for Flutter](/docs/getting-started-for-flutter) tutorials to start building your first application.',
|
||||
'enabled' => true,
|
||||
'beta' => false,
|
||||
'languages' => [ // TODO change key to 'sdks'
|
||||
'sdks' => [
|
||||
[
|
||||
'key' => 'web',
|
||||
'name' => 'Web',
|
||||
|
|
@ -181,11 +181,11 @@ return [
|
|||
'name' => 'Console',
|
||||
'enabled' => false,
|
||||
'beta' => false,
|
||||
'languages' => [
|
||||
'sdks' => [
|
||||
[
|
||||
'key' => 'web',
|
||||
'name' => 'Console',
|
||||
'version' => '7.2.0',
|
||||
'version' => '0.0.2-preview-0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-console',
|
||||
'package' => '',
|
||||
'enabled' => true,
|
||||
|
|
@ -193,10 +193,10 @@ return [
|
|||
'dev' => false,
|
||||
'hidden' => true,
|
||||
'family' => APP_PLATFORM_CONSOLE,
|
||||
'prism' => 'console',
|
||||
'prism' => 'javascript',
|
||||
'source' => \realpath(__DIR__ . '/../sdks/console-web'),
|
||||
'gitUrl' => '',
|
||||
'gitBranch' => '',
|
||||
'gitUrl' => 'git@github.com:appwrite/sdk-for-console.git',
|
||||
'gitBranch' => 'main',
|
||||
'gitRepoName' => 'sdk-for-console',
|
||||
'gitUserName' => 'appwrite',
|
||||
],
|
||||
|
|
@ -227,7 +227,7 @@ return [
|
|||
'description' => 'Libraries for integrating with Appwrite to build server side integrations. Read the [getting started for server](/docs/getting-started-for-server) tutorial to start building your first server integration.',
|
||||
'enabled' => true,
|
||||
'beta' => false,
|
||||
'languages' => [
|
||||
'sdks' => [
|
||||
[
|
||||
'key' => 'nodejs',
|
||||
'name' => 'Node.js',
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -62,7 +62,7 @@ App::post('/v1/account')
|
|||
->label('sdk.description', '/docs/references/account/create.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_ACCOUNT)
|
||||
->label('sdk.response.model', Response::MODEL_USER)
|
||||
->label('abuse-limit', 10)
|
||||
->param('userId', '', new CustomId(), 'Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. 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.')
|
||||
->param('email', '', new Email(), 'User email.')
|
||||
|
|
@ -192,7 +192,7 @@ App::post('/v1/account/sessions/email')
|
|||
|
||||
$detector = new Detector($request->getUserAgent('UNKNOWN'));
|
||||
$record = $geodb->get($request->getIP());
|
||||
$expire = DateTime::addSeconds(new \DateTime(), $duration);
|
||||
$expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), $duration));
|
||||
$secret = Auth::tokenGenerator();
|
||||
$session = new Document(array_merge(
|
||||
[
|
||||
|
|
@ -381,6 +381,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
->label('scope', 'public')
|
||||
->label('audits.event', 'session.create')
|
||||
->label('audits.resource', 'user/{user.$id}')
|
||||
->label('audits.userId', '{user.$id}')
|
||||
->label('abuse-limit', 50)
|
||||
->label('abuse-key', 'ip:{ip}')
|
||||
->label('docs', false)
|
||||
|
|
@ -1327,7 +1328,9 @@ App::get('/v1/account')
|
|||
->label('sdk.description', '/docs/references/account/get.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_ACCOUNT)
|
||||
->label('sdk.response.model', Response::MODEL_USER)
|
||||
->label('sdk.offline.model', '/account')
|
||||
->label('sdk.offline.key', 'current')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->action(function (Response $response, Document $user) {
|
||||
|
|
@ -1347,6 +1350,8 @@ App::get('/v1/account/prefs')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_PREFERENCES)
|
||||
->label('sdk.offline.model', '/account/prefs')
|
||||
->label('sdk.offline.key', 'current')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->action(function (Response $response, Document $user) {
|
||||
|
|
@ -1368,6 +1373,7 @@ App::get('/v1/account/sessions')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_SESSION_LIST)
|
||||
->label('sdk.offline.model', '/account/sessions')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('locale')
|
||||
|
|
@ -1466,6 +1472,8 @@ App::get('/v1/account/sessions/:sessionId')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_SESSION)
|
||||
->label('sdk.offline.model', '/account/sessions')
|
||||
->label('sdk.offline.key', '{sessionId}')
|
||||
->param('sessionId', '', new UID(), 'Session ID. Use the string \'current\' to get the current device session.')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
|
|
@ -1504,6 +1512,7 @@ App::patch('/v1/account/name')
|
|||
->label('scope', 'account')
|
||||
->label('audits.event', 'user.update')
|
||||
->label('audits.resource', 'user/{response.$id}')
|
||||
->label('audits.userId', '{response.$id}')
|
||||
->label('usage.metric', 'users.{scope}.requests.update')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'account')
|
||||
|
|
@ -1511,17 +1520,22 @@ App::patch('/v1/account/name')
|
|||
->label('sdk.description', '/docs/references/account/update-name.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_ACCOUNT)
|
||||
->label('sdk.response.model', Response::MODEL_USER)
|
||||
->label('sdk.offline.model', '/account')
|
||||
->label('sdk.offline.key', 'current')
|
||||
->param('name', '', new Text(128), 'User name. Max length: 128 chars.')
|
||||
->inject('requestTimestamp')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('dbForProject')
|
||||
->inject('events')
|
||||
->action(function (string $name, Response $response, Document $user, Database $dbForProject, Event $events) {
|
||||
->action(function (string $name, ?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $events) {
|
||||
|
||||
$user = $dbForProject->updateDocument('users', $user->getId(), $user
|
||||
$user
|
||||
->setAttribute('name', $name)
|
||||
->setAttribute('search', implode(' ', [$user->getId(), $name, $user->getAttribute('email', ''), $user->getAttribute('phone', '')])));
|
||||
->setAttribute('search', implode(' ', [$user->getId(), $name, $user->getAttribute('email', ''), $user->getAttribute('phone', '')]));
|
||||
|
||||
$user = $dbForProject->withRequestTimestamp($requestTimestamp, fn () => $dbForProject->updateDocument('users', $user->getId(), $user));
|
||||
|
||||
$events->setParam('userId', $user->getId());
|
||||
|
||||
|
|
@ -1544,14 +1558,17 @@ App::patch('/v1/account/password')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_ACCOUNT)
|
||||
->label('sdk.offline.model', '/account')
|
||||
->label('sdk.offline.key', 'current')
|
||||
->param('password', '', fn ($project, $passwordsDictionary) => new PasswordDictionary($passwordsDictionary, $project->getAttribute('auths', [])['passwordDictionary'] ?? false), 'New user password. Must be at least 8 chars.', false, ['project', 'passwordsDictionary'])
|
||||
->param('oldPassword', '', new Password(), 'Current user password. Must be at least 8 chars.', true)
|
||||
->inject('requestTimestamp')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('events')
|
||||
->action(function (string $password, string $oldPassword, Response $response, Document $user, Document $project, Database $dbForProject, Event $events) {
|
||||
->action(function (string $password, string $oldPassword, ?\DateTime $requestTimestamp, Response $response, Document $user, Document $project, Database $dbForProject, Event $events) {
|
||||
|
||||
// Check old password only if its an existing user.
|
||||
if (!empty($user->getAttribute('passwordUpdate')) && !Auth::passwordVerify($oldPassword, $user->getAttribute('password'), $user->getAttribute('hash'), $user->getAttribute('hashOptions'))) { // Double check user password
|
||||
|
|
@ -1572,12 +1589,14 @@ App::patch('/v1/account/password')
|
|||
array_slice($history, (count($history) - $historyLimit), $historyLimit);
|
||||
}
|
||||
|
||||
$user = $dbForProject->updateDocument('users', $user->getId(), $user
|
||||
->setAttribute('password', $newPassword)
|
||||
->setAttribute('passwordHistory', $history)
|
||||
->setAttribute('passwordUpdate', DateTime::now()))
|
||||
->setAttribute('hash', Auth::DEFAULT_ALGO)
|
||||
->setAttribute('hashOptions', Auth::DEFAULT_ALGO_OPTIONS);
|
||||
$user
|
||||
->setAttribute('password', $newPassword)
|
||||
->setAttribute('passwordHistory', $history)
|
||||
->setAttribute('passwordUpdate', DateTime::now())
|
||||
->setAttribute('hash', Auth::DEFAULT_ALGO)
|
||||
->setAttribute('hashOptions', Auth::DEFAULT_ALGO_OPTIONS);
|
||||
|
||||
$user = $dbForProject->withRequestTimestamp($requestTimestamp, fn () => $dbForProject->updateDocument('users', $user->getId(), $user));
|
||||
|
||||
$events->setParam('userId', $user->getId());
|
||||
|
||||
|
|
@ -1591,6 +1610,7 @@ App::patch('/v1/account/email')
|
|||
->label('scope', 'account')
|
||||
->label('audits.event', 'user.update')
|
||||
->label('audits.resource', 'user/{response.$id}')
|
||||
->label('audits.userId', '{response.$id}')
|
||||
->label('usage.metric', 'users.{scope}.requests.update')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'account')
|
||||
|
|
@ -1598,14 +1618,17 @@ App::patch('/v1/account/email')
|
|||
->label('sdk.description', '/docs/references/account/update-email.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_ACCOUNT)
|
||||
->label('sdk.response.model', Response::MODEL_USER)
|
||||
->label('sdk.offline.model', '/account')
|
||||
->label('sdk.offline.key', 'current')
|
||||
->param('email', '', new Email(), 'User email.')
|
||||
->param('password', '', new Password(), 'User password. Must be at least 8 chars.')
|
||||
->inject('requestTimestamp')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('dbForProject')
|
||||
->inject('events')
|
||||
->action(function (string $email, string $password, Response $response, Document $user, Database $dbForProject, Event $events) {
|
||||
->action(function (string $email, string $password, ?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $events) {
|
||||
$isAnonymousUser = Auth::isAnonymousUser($user); // Check if request is from an anonymous account for converting
|
||||
|
||||
if (
|
||||
|
|
@ -1626,7 +1649,7 @@ App::patch('/v1/account/email')
|
|||
->setAttribute('search', implode(' ', [$user->getId(), $user->getAttribute('name', ''), $email, $user->getAttribute('phone', '')]));
|
||||
|
||||
try {
|
||||
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
|
||||
$user = $dbForProject->withRequestTimestamp($requestTimestamp, fn () => $dbForProject->updateDocument('users', $user->getId(), $user));
|
||||
} catch (Duplicate $th) {
|
||||
throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS);
|
||||
}
|
||||
|
|
@ -1643,6 +1666,7 @@ App::patch('/v1/account/phone')
|
|||
->label('scope', 'account')
|
||||
->label('audits.event', 'user.update')
|
||||
->label('audits.resource', 'user/{response.$id}')
|
||||
->label('audits.userId', '{response.$id}')
|
||||
->label('usage.metric', 'users.{scope}.requests.update')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'account')
|
||||
|
|
@ -1650,14 +1674,17 @@ App::patch('/v1/account/phone')
|
|||
->label('sdk.description', '/docs/references/account/update-phone.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_ACCOUNT)
|
||||
->label('sdk.response.model', Response::MODEL_USER)
|
||||
->label('sdk.offline.model', '/account')
|
||||
->label('sdk.offline.key', 'current')
|
||||
->param('phone', '', new Phone(), 'Phone number. Format this number with a leading \'+\' and a country code, e.g., +16175551212.')
|
||||
->param('password', '', new Password(), 'User password. Must be at least 8 chars.')
|
||||
->inject('requestTimestamp')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('dbForProject')
|
||||
->inject('events')
|
||||
->action(function (string $phone, string $password, Response $response, Document $user, Database $dbForProject, Event $events) {
|
||||
->action(function (string $phone, string $password, ?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $events) {
|
||||
|
||||
$isAnonymousUser = Auth::isAnonymousUser($user); // Check if request is from an anonymous account for converting
|
||||
|
||||
|
|
@ -1674,7 +1701,7 @@ App::patch('/v1/account/phone')
|
|||
->setAttribute('search', implode(' ', [$user->getId(), $user->getAttribute('name', ''), $user->getAttribute('email', ''), $phone]));
|
||||
|
||||
try {
|
||||
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
|
||||
$user = $dbForProject->withRequestTimestamp($requestTimestamp, fn () => $dbForProject->updateDocument('users', $user->getId(), $user));
|
||||
} catch (Duplicate $th) {
|
||||
throw new Exception(Exception::USER_PHONE_ALREADY_EXISTS);
|
||||
}
|
||||
|
|
@ -1691,6 +1718,7 @@ App::patch('/v1/account/prefs')
|
|||
->label('scope', 'account')
|
||||
->label('audits.event', 'user.update')
|
||||
->label('audits.resource', 'user/{response.$id}')
|
||||
->label('audits.userId', '{response.$id}')
|
||||
->label('usage.metric', 'users.{scope}.requests.update')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'account')
|
||||
|
|
@ -1698,15 +1726,20 @@ App::patch('/v1/account/prefs')
|
|||
->label('sdk.description', '/docs/references/account/update-prefs.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_ACCOUNT)
|
||||
->label('sdk.response.model', Response::MODEL_USER)
|
||||
->label('sdk.offline.model', '/account/prefs')
|
||||
->label('sdk.offline.key', 'current')
|
||||
->param('prefs', [], new Assoc(), 'Prefs key-value JSON object.')
|
||||
->inject('requestTimestamp')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('dbForProject')
|
||||
->inject('events')
|
||||
->action(function (array $prefs, Response $response, Document $user, Database $dbForProject, Event $events) {
|
||||
->action(function (array $prefs, ?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $events) {
|
||||
|
||||
$user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('prefs', $prefs));
|
||||
$user->setAttribute('prefs', $prefs);
|
||||
|
||||
$user = $dbForProject->withRequestTimestamp($requestTimestamp, fn () => $dbForProject->updateDocument('users', $user->getId(), $user));
|
||||
|
||||
$events->setParam('userId', $user->getId());
|
||||
|
||||
|
|
@ -1720,6 +1753,7 @@ App::patch('/v1/account/status')
|
|||
->label('scope', 'account')
|
||||
->label('audits.event', 'user.update')
|
||||
->label('audits.resource', 'user/{response.$id}')
|
||||
->label('audits.userId', '{response.$id}')
|
||||
->label('usage.metric', 'users.{scope}.requests.delete')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'account')
|
||||
|
|
@ -1728,14 +1762,16 @@ App::patch('/v1/account/status')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_ACCOUNT)
|
||||
->inject('request')
|
||||
->inject('requestTimestamp')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('dbForProject')
|
||||
->inject('events')
|
||||
->action(function (Request $request, Response $response, Document $user, Database $dbForProject, Event $events) {
|
||||
->action(function (?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $events) {
|
||||
|
||||
$user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('status', false));
|
||||
$user->setAttribute('status', false);
|
||||
|
||||
$user = $dbForProject->withRequestTimestamp($requestTimestamp, fn () => $dbForProject->updateDocument('users', $user->getId(), $user));
|
||||
|
||||
$events
|
||||
->setParam('userId', $user->getId())
|
||||
|
|
@ -1755,6 +1791,7 @@ App::delete('/v1/account/sessions/:sessionId')
|
|||
->label('event', 'users.[userId].sessions.[sessionId].delete')
|
||||
->label('audits.event', 'session.delete')
|
||||
->label('audits.resource', 'user/{user.$id}')
|
||||
->label('audits.userId', '{user.$id}')
|
||||
->label('usage.metric', 'sessions.{scope}.requests.delete')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'account')
|
||||
|
|
@ -1764,6 +1801,7 @@ App::delete('/v1/account/sessions/:sessionId')
|
|||
->label('sdk.response.model', Response::MODEL_NONE)
|
||||
->label('abuse-limit', 100)
|
||||
->param('sessionId', '', new UID(), 'Session ID. Use the string \'current\' to delete the current device session.')
|
||||
->inject('requestTimestamp')
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
|
|
@ -1771,7 +1809,7 @@ App::delete('/v1/account/sessions/:sessionId')
|
|||
->inject('locale')
|
||||
->inject('events')
|
||||
->inject('project')
|
||||
->action(function (?string $sessionId, Request $request, Response $response, Document $user, Database $dbForProject, Locale $locale, Event $events, Document $project) {
|
||||
->action(function (?string $sessionId, ?\DateTime $requestTimestamp, Request $request, Response $response, Document $user, Database $dbForProject, Locale $locale, Event $events, Document $project) {
|
||||
|
||||
$protocol = $request->getProtocol();
|
||||
$authDuration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
|
||||
|
|
@ -1783,9 +1821,11 @@ App::delete('/v1/account/sessions/:sessionId')
|
|||
|
||||
foreach ($sessions as $key => $session) {/** @var Document $session */
|
||||
if ($sessionId == $session->getId()) {
|
||||
unset($sessions[$key]);
|
||||
$dbForProject->withRequestTimestamp($requestTimestamp, function () use ($dbForProject, $session) {
|
||||
return $dbForProject->deleteDocument('sessions', $session->getId());
|
||||
});
|
||||
|
||||
$dbForProject->deleteDocument('sessions', $session->getId());
|
||||
unset($sessions[$key]);
|
||||
|
||||
$session->setAttribute('current', false);
|
||||
|
||||
|
|
@ -1914,6 +1954,7 @@ App::delete('/v1/account/sessions')
|
|||
->label('event', 'users.[userId].sessions.[sessionId].delete')
|
||||
->label('audits.event', 'session.delete')
|
||||
->label('audits.resource', 'user/{user.$id}')
|
||||
->label('audits.userId', '{user.$id}')
|
||||
->label('usage.metric', 'sessions.{scope}.requests.delete')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'account')
|
||||
|
|
@ -2174,6 +2215,7 @@ App::post('/v1/account/verification')
|
|||
->label('event', 'users.[userId].verification.[tokenId].create')
|
||||
->label('audits.event', 'verification.create')
|
||||
->label('audits.resource', 'user/{response.userId}')
|
||||
->label('audits.userId', '{response.userId}')
|
||||
->label('usage.metric', 'users.{scope}.requests.update')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'account')
|
||||
|
|
@ -2285,6 +2327,7 @@ App::put('/v1/account/verification')
|
|||
->label('event', 'users.[userId].verification.[tokenId].update')
|
||||
->label('audits.event', 'verification.update')
|
||||
->label('audits.resource', 'user/{response.userId}')
|
||||
->label('audits.userId', '{response.userId}')
|
||||
->label('usage.metric', 'users.{scope}.requests.update')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'account')
|
||||
|
|
@ -2344,6 +2387,7 @@ App::post('/v1/account/verification/phone')
|
|||
->label('event', 'users.[userId].verification.[tokenId].create')
|
||||
->label('audits.event', 'verification.create')
|
||||
->label('audits.resource', 'user/{response.userId}')
|
||||
->label('audits.userId', '{response.userId}')
|
||||
->label('usage.metric', 'users.{scope}.requests.update')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'account')
|
||||
|
|
@ -2429,6 +2473,7 @@ App::put('/v1/account/verification/phone')
|
|||
->label('event', 'users.[userId].verification.[tokenId].update')
|
||||
->label('audits.event', 'verification.update')
|
||||
->label('audits.resource', 'user/{response.userId}')
|
||||
->label('audits.userId', '{response.userId}')
|
||||
->label('usage.metric', 'users.{scope}.requests.update')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'account')
|
||||
|
|
|
|||
|
|
@ -1852,6 +1852,8 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_DOCUMENT)
|
||||
->label('sdk.offline.model', '/databases/{databaseId}/collections/{collectionId}/documents')
|
||||
->label('sdk.offline.key', '{documentId}')
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('documentId', '', new CustomId(), 'Document ID. Choose a custom ID or generate a random ID with `ID.unique()`. 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.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). Make sure to define attributes before creating documents.')
|
||||
|
|
@ -1974,6 +1976,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_DOCUMENT_LIST)
|
||||
->label('sdk.offline.model', '/databases/{databaseId}/collections/{collectionId}/documents')
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('queries', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), '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.', true)
|
||||
|
|
@ -2004,7 +2007,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
|
|||
}
|
||||
|
||||
// Validate queries
|
||||
$queriesValidator = new Documents($collection->getAttribute('attributes'), $collection->getAttribute('indexes'));
|
||||
$queriesValidator = new Documents($collection->getAttribute('attributes'));
|
||||
$validQueries = $queriesValidator->isValid($queries);
|
||||
if (!$validQueries) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $queriesValidator->getDescription());
|
||||
|
|
@ -2071,6 +2074,8 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_DOCUMENT)
|
||||
->label('sdk.offline.model', '/databases/{databaseId}/collections/{collectionId}/documents')
|
||||
->label('sdk.offline.key', '{documentId}')
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('documentId', '', new UID(), 'Document ID.')
|
||||
|
|
@ -2240,16 +2245,19 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_DOCUMENT)
|
||||
->label('sdk.offline.model', '/databases/{databaseId}/collections/{collectionId}/documents')
|
||||
->label('sdk.offline.key', '{documentId}')
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID.')
|
||||
->param('documentId', '', new UID(), 'Document ID.')
|
||||
->param('data', [], new JSON(), 'Document data as JSON object. Include only attribute and value pairs to be updated.', true)
|
||||
->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE, Database::PERMISSION_WRITE]), 'An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](/docs/permissions).', true)
|
||||
->inject('requestTimestamp')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('events')
|
||||
->inject('mode')
|
||||
->action(function (string $databaseId, string $collectionId, string $documentId, string|array $data, ?array $permissions, Response $response, Database $dbForProject, Event $events, string $mode) {
|
||||
->action(function (string $databaseId, string $collectionId, string $documentId, string|array $data, ?array $permissions, ?\DateTime $requestTimestamp, Response $response, Database $dbForProject, Event $events, string $mode) {
|
||||
|
||||
$data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array
|
||||
|
||||
|
|
@ -2279,6 +2287,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
|
|||
}
|
||||
|
||||
// Read permission should not be required for update
|
||||
/** @var Document */
|
||||
$document = Authorization::skip(fn() => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId));
|
||||
|
||||
if ($document->isEmpty()) {
|
||||
|
|
@ -2324,10 +2333,31 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
|
|||
$data['$permissions'] = $permissions;
|
||||
|
||||
try {
|
||||
$privateCollectionId = 'database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId();
|
||||
if ($documentSecurity && !$valid) {
|
||||
$document = $dbForProject->updateDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $document->getId(), new Document($data));
|
||||
$document = $dbForProject->withRequestTimestamp(
|
||||
$requestTimestamp,
|
||||
function () use ($dbForProject, $privateCollectionId, $document, $data) {
|
||||
return $dbForProject->updateDocument(
|
||||
$privateCollectionId,
|
||||
$document->getId(),
|
||||
new Document($data)
|
||||
);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
$document = Authorization::skip(fn() => $dbForProject->updateDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $document->getId(), new Document($data)));
|
||||
$document = Authorization::skip(function () use ($dbForProject, $requestTimestamp, $privateCollectionId, $document, $data) {
|
||||
return $dbForProject->withRequestTimestamp(
|
||||
$requestTimestamp,
|
||||
function () use ($dbForProject, $privateCollectionId, $document, $data) {
|
||||
return $dbForProject->updateDocument(
|
||||
$privateCollectionId,
|
||||
$document->getId(),
|
||||
new Document($data)
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2373,15 +2403,18 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:docu
|
|||
->label('sdk.description', '/docs/references/databases/delete-document.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
|
||||
->label('sdk.response.model', Response::MODEL_NONE)
|
||||
->label('sdk.offline.model', '/databases/{databaseId}/collections/{collectionId}/documents')
|
||||
->label('sdk.offline.key', '{documentId}')
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('documentId', '', new UID(), 'Document ID.')
|
||||
->inject('requestTimestamp')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('events')
|
||||
->inject('deletes')
|
||||
->inject('mode')
|
||||
->action(function (string $databaseId, string $collectionId, string $documentId, Response $response, Database $dbForProject, Event $events, Delete $deletes, string $mode) {
|
||||
->action(function (string $databaseId, string $collectionId, string $documentId, ?\DateTime $requestTimestamp, Response $response, Database $dbForProject, Event $events, Delete $deletes, string $mode) {
|
||||
|
||||
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
|
||||
|
||||
|
|
@ -2411,17 +2444,25 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:docu
|
|||
throw new Exception(Exception::DOCUMENT_NOT_FOUND);
|
||||
}
|
||||
|
||||
$privateCollectionId = 'database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId();
|
||||
|
||||
if ($documentSecurity && !$valid) {
|
||||
try {
|
||||
$dbForProject->deleteDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId);
|
||||
$dbForProject->withRequestTimestamp($requestTimestamp, function () use ($dbForProject, $privateCollectionId, $documentId) {
|
||||
return $dbForProject->deleteDocument($privateCollectionId, $documentId);
|
||||
});
|
||||
} catch (AuthorizationException) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
} else {
|
||||
Authorization::skip(fn() => $dbForProject->deleteDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId));
|
||||
Authorization::skip(function () use ($dbForProject, $requestTimestamp, $privateCollectionId, $documentId) {
|
||||
return $dbForProject->withRequestTimestamp($requestTimestamp, function () use ($dbForProject, $privateCollectionId, $documentId) {
|
||||
return $dbForProject->deleteDocument($privateCollectionId, $documentId);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$dbForProject->deleteCachedDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId);
|
||||
$dbForProject->deleteCachedDocument($privateCollectionId, $documentId);
|
||||
|
||||
/**
|
||||
* Reset $collection attribute to remove prefix.
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ App::get('/v1/locale')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_LOCALE)
|
||||
->label('sdk.offline.model', '/locale')
|
||||
->label('sdk.offline.key', 'current')
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('locale')
|
||||
|
|
@ -77,6 +79,8 @@ App::get('/v1/locale/countries')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_COUNTRY_LIST)
|
||||
->label('sdk.offline.model', '/locale/countries')
|
||||
->label('sdk.offline.response.key', 'code')
|
||||
->inject('response')
|
||||
->inject('locale')
|
||||
->action(function (Response $response, Locale $locale) {
|
||||
|
|
@ -108,6 +112,8 @@ App::get('/v1/locale/countries/eu')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_COUNTRY_LIST)
|
||||
->label('sdk.offline.model', '/locale/countries/eu')
|
||||
->label('sdk.offline.response.key', 'code')
|
||||
->inject('response')
|
||||
->inject('locale')
|
||||
->action(function (Response $response, Locale $locale) {
|
||||
|
|
@ -141,6 +147,8 @@ App::get('/v1/locale/countries/phones')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_PHONE_LIST)
|
||||
->label('sdk.offline.model', '/locale/countries/phones')
|
||||
->label('sdk.offline.response.key', 'countryCode')
|
||||
->inject('response')
|
||||
->inject('locale')
|
||||
->action(function (Response $response, Locale $locale) {
|
||||
|
|
@ -173,6 +181,8 @@ App::get('/v1/locale/continents')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_CONTINENT_LIST)
|
||||
->label('sdk.offline.model', '/locale/continents')
|
||||
->label('sdk.offline.response.key', 'code')
|
||||
->inject('response')
|
||||
->inject('locale')
|
||||
->action(function (Response $response, Locale $locale) {
|
||||
|
|
@ -203,6 +213,8 @@ App::get('/v1/locale/currencies')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_CURRENCY_LIST)
|
||||
->label('sdk.offline.model', '/locale/currencies')
|
||||
->label('sdk.offline.response.key', 'code')
|
||||
->inject('response')
|
||||
->action(function (Response $response) {
|
||||
$list = Config::getParam('locale-currencies');
|
||||
|
|
@ -224,6 +236,8 @@ App::get('/v1/locale/languages')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_LANGUAGE_LIST)
|
||||
->label('sdk.offline.model', '/locale/languages')
|
||||
->label('sdk.offline.response.key', 'code')
|
||||
->inject('response')
|
||||
->action(function (Response $response) {
|
||||
$list = Config::getParam('locale-languages');
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use Appwrite\Detector\Detector;
|
|||
use Appwrite\Event\Delete;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Phone as EventPhone;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Network\Validator\Email;
|
||||
use Utopia\Validator\Host;
|
||||
|
|
@ -21,7 +22,6 @@ use Appwrite\Utopia\Response;
|
|||
use MaxMind\Db\Reader;
|
||||
use Utopia\App;
|
||||
use Utopia\Audit\Audit;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
|
|
@ -37,10 +37,7 @@ use Utopia\Database\Validator\Key;
|
|||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Locale\Locale;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\Range;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\WhiteList;
|
||||
use Appwrite\Event\Phone as EventPhone;
|
||||
|
||||
App::post('/v1/teams')
|
||||
->desc('Create Team')
|
||||
|
|
@ -135,6 +132,7 @@ App::get('/v1/teams')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_TEAM_LIST)
|
||||
->label('sdk.offline.model', '/teams')
|
||||
->param('queries', [], new Teams(), '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(', ', Teams::ALLOWED_ATTRIBUTES), true)
|
||||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->inject('response')
|
||||
|
|
@ -184,6 +182,8 @@ App::get('/v1/teams/:teamId')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_TEAM)
|
||||
->label('sdk.offline.model', '/teams')
|
||||
->label('sdk.offline.key', '{teamId}')
|
||||
->param('teamId', '', new UID(), 'Team ID.')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
|
|
@ -212,12 +212,15 @@ App::put('/v1/teams/:teamId')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_TEAM)
|
||||
->label('sdk.offline.model', '/teams')
|
||||
->label('sdk.offline.key', '{teamId}')
|
||||
->param('teamId', '', new UID(), 'Team ID.')
|
||||
->param('name', null, new Text(128), 'New team name. Max length: 128 chars.')
|
||||
->inject('requestTimestamp')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('events')
|
||||
->action(function (string $teamId, string $name, Response $response, Database $dbForProject, Event $events) {
|
||||
->action(function (string $teamId, string $name, ?\DateTime $requestTimestamp, Response $response, Database $dbForProject, Event $events) {
|
||||
|
||||
$team = $dbForProject->getDocument('teams', $teamId);
|
||||
|
||||
|
|
@ -225,9 +228,13 @@ App::put('/v1/teams/:teamId')
|
|||
throw new Exception(Exception::TEAM_NOT_FOUND);
|
||||
}
|
||||
|
||||
$team = $dbForProject->updateDocument('teams', $team->getId(), $team
|
||||
$team
|
||||
->setAttribute('name', $name)
|
||||
->setAttribute('search', implode(' ', [$teamId, $name])));
|
||||
->setAttribute('search', implode(' ', [$teamId, $name]));
|
||||
|
||||
$team = $dbForProject->withRequestTimestamp($requestTimestamp, function () use ($dbForProject, $team) {
|
||||
return $dbForProject->updateDocument('teams', $team->getId(), $team);
|
||||
});
|
||||
|
||||
$events->setParam('teamId', $team->getId());
|
||||
|
||||
|
|
@ -532,6 +539,7 @@ App::get('/v1/teams/:teamId/memberships')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MEMBERSHIP_LIST)
|
||||
->label('sdk.offline.model', '/teams/{teamId}/memberships')
|
||||
->param('teamId', '', new UID(), 'Team ID.')
|
||||
->param('queries', [], new Memberships(), '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(', ', Memberships::ALLOWED_ATTRIBUTES), true)
|
||||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
|
|
@ -613,6 +621,8 @@ App::get('/v1/teams/:teamId/memberships/:membershipId')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MEMBERSHIP)
|
||||
->label('sdk.offline.model', '/teams/{teamId}/memberships')
|
||||
->label('sdk.offline.key', '{membershipId}')
|
||||
->param('teamId', '', new UID(), 'Team ID.')
|
||||
->param('membershipId', '', new UID(), 'Membership ID.')
|
||||
->inject('response')
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ App::init()
|
|||
->addHeader('Server', 'Appwrite')
|
||||
->addHeader('X-Content-Type-Options', 'nosniff')
|
||||
->addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE')
|
||||
->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, Content-Range, Range, Cache-Control, Expires, Pragma')
|
||||
->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma')
|
||||
->addHeader('Access-Control-Expose-Headers', 'X-Fallback-Cookies')
|
||||
->addHeader('Access-Control-Allow-Origin', $refDomain)
|
||||
->addHeader('Access-Control-Allow-Credentials', 'true')
|
||||
|
|
@ -384,7 +384,7 @@ App::options()
|
|||
$response
|
||||
->addHeader('Server', 'Appwrite')
|
||||
->addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE')
|
||||
->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, Content-Range, Range, Cache-Control, Expires, Pragma, X-Fallback-Cookies')
|
||||
->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Fallback-Cookies')
|
||||
->addHeader('Access-Control-Expose-Headers', 'X-Fallback-Cookies')
|
||||
->addHeader('Access-Control-Allow-Origin', $origin)
|
||||
->addHeader('Access-Control-Allow-Credentials', 'true')
|
||||
|
|
@ -485,6 +485,10 @@ App::error()
|
|||
$error->setType(AppwriteException::GENERAL_ROUTE_NOT_FOUND);
|
||||
break;
|
||||
}
|
||||
} elseif ($error instanceof Utopia\Database\Exception\Conflict) {
|
||||
$error = new AppwriteException(AppwriteException::DOCUMENT_UPDATE_CONFLICT, null, null, $error);
|
||||
$code = $error->getCode();
|
||||
$message = $error->getMessage();
|
||||
}
|
||||
|
||||
/** Wrap all exceptions inside Appwrite\Extend\Exception */
|
||||
|
|
|
|||
|
|
@ -135,6 +135,8 @@ App::post('/v1/mock/tests/bar')
|
|||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MOCK)
|
||||
->label('sdk.offline.model', '/mock/tests/bar')
|
||||
->label('sdk.offline.key', '{required}')
|
||||
->label('sdk.mock', true)
|
||||
->param('required', '', new Text(100), 'Sample string param')
|
||||
->param('default', '', new Integer(true), 'Sample numeric param')
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ use Appwrite\Event\Audit;
|
|||
use Appwrite\Event\Database as EventDatabase;
|
||||
use Appwrite\Event\Delete;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Messaging\Adapter\Realtime;
|
||||
use Appwrite\Usage\Stats;
|
||||
|
|
@ -16,7 +15,6 @@ use Utopia\Abuse\Abuse;
|
|||
use Utopia\Abuse\Adapters\TimeLimit;
|
||||
use Utopia\Cache\Adapter\Filesystem;
|
||||
use Utopia\Cache\Cache;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Document;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ App::get('/versions')
|
|||
];
|
||||
|
||||
foreach ($platforms as $platform) {
|
||||
$languages = $platform['languages'] ?? [];
|
||||
$languages = $platform['sdks'] ?? [];
|
||||
|
||||
foreach ($languages as $key => $language) {
|
||||
if (isset($language['dev']) && $language['dev']) {
|
||||
|
|
|
|||
|
|
@ -92,7 +92,6 @@ $http->on('start', function (Server $http) use ($payloadSize, $register) {
|
|||
$collections = Config::getParam('collections', []);
|
||||
|
||||
try {
|
||||
$redis->flushAll();
|
||||
Console::success('[Setup] - Creating database: appwrite...');
|
||||
$dbForConsole->create();
|
||||
} catch (\Exception $e) {
|
||||
|
|
|
|||
16
app/init.php
16
app/init.php
|
|
@ -1061,7 +1061,7 @@ App::setResource('servers', function () {
|
|||
|
||||
$languages = array_map(function ($language) {
|
||||
return strtolower($language['name']);
|
||||
}, $server['languages']);
|
||||
}, $server['sdks']);
|
||||
|
||||
return $languages;
|
||||
});
|
||||
|
|
@ -1155,3 +1155,17 @@ App::setResource('schema', function ($utopia, $dbForProject) {
|
|||
$params,
|
||||
);
|
||||
}, ['utopia', 'dbForProject']);
|
||||
|
||||
App::setResource('requestTimestamp', function ($request) {
|
||||
// Validate x-appwrite-timestamp header
|
||||
$timestampHeader = $request->getHeader('x-appwrite-timestamp');
|
||||
$requestTimestamp = null;
|
||||
if (!empty($timestampHeader)) {
|
||||
try {
|
||||
$requestTimestamp = new \DateTime($timestampHeader);
|
||||
} catch (\Throwable $e) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Invalid X-Appwrite-Timestamp header value');
|
||||
}
|
||||
}
|
||||
return $requestTimestamp;
|
||||
}, ['request']);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@ $cli
|
|||
->task('sdks')
|
||||
->action(function () {
|
||||
$platforms = Config::getParam('platforms');
|
||||
$selected = \strtolower(Console::confirm('Choose SDK ("*" for all):'));
|
||||
$selectedPlatform = Console::confirm('Choose Platform ("' . APP_PLATFORM_CLIENT . '", "' . APP_PLATFORM_SERVER . '", "' . APP_PLATFORM_CONSOLE . '" or "*" for all):');
|
||||
$selectedSDK = \strtolower(Console::confirm('Choose SDK ("*" for all):'));
|
||||
$version = Console::confirm('Choose an Appwrite version');
|
||||
$git = (Console::confirm('Should we use git push? (yes/no)') == 'yes');
|
||||
$production = ($git) ? (Console::confirm('Type "Appwrite" to push code to production git repos') == 'Appwrite') : false;
|
||||
|
|
@ -37,8 +38,12 @@ $cli
|
|||
}
|
||||
|
||||
foreach ($platforms as $key => $platform) {
|
||||
foreach ($platform['languages'] as $language) {
|
||||
if ($selected !== $language['key'] && $selected !== '*') {
|
||||
if ($selectedPlatform !== $key && $selectedPlatform !== '*') {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($platform['sdks'] as $language) {
|
||||
if ($selectedSDK !== $language['key'] && $selectedSDK !== '*') {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -81,8 +86,13 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|||
switch ($language['key']) {
|
||||
case 'web':
|
||||
$config = new Web();
|
||||
$config->setNPMPackage('appwrite');
|
||||
$config->setBowerPackage('appwrite');
|
||||
if ($platform['key'] === APP_PLATFORM_CONSOLE) {
|
||||
$config->setNPMPackage('@appwrite.io/console');
|
||||
$config->setBowerPackage('@appwrite.io/console');
|
||||
} else {
|
||||
$config->setNPMPackage('appwrite');
|
||||
$config->setBowerPackage('appwrite');
|
||||
}
|
||||
break;
|
||||
case 'cli':
|
||||
$config = new CLI();
|
||||
|
|
|
|||
|
|
@ -43,13 +43,13 @@
|
|||
"ext-sockets": "*",
|
||||
"appwrite/php-clamav": "1.1.*",
|
||||
"appwrite/php-runtimes": "0.11.*",
|
||||
"utopia-php/abuse": "0.18.*",
|
||||
"utopia-php/abuse": "0.19.*",
|
||||
"utopia-php/analytics": "0.2.*",
|
||||
"utopia-php/audit": "0.20.*",
|
||||
"utopia-php/audit": "0.21.*",
|
||||
"utopia-php/cache": "0.8.*",
|
||||
"utopia-php/cli": "0.13.*",
|
||||
"utopia-php/config": "0.2.*",
|
||||
"utopia-php/database": "0.30.*",
|
||||
"utopia-php/database": "0.31.*",
|
||||
"utopia-php/preloader": "0.2.*",
|
||||
"utopia-php/domains": "1.1.*",
|
||||
"utopia-php/framework": "0.26.*",
|
||||
|
|
|
|||
74
composer.lock
generated
74
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": "ac80cafdd8c2c6deaec3dfe628084655",
|
||||
"content-hash": "3e00aa37bea907b7dcca7f912402a392",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
|
|
@ -1808,29 +1808,28 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/abuse",
|
||||
"version": "0.18.0",
|
||||
"version": "0.19.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/abuse.git",
|
||||
"reference": "8496401234f73a49f8c4259d3e89ab4a7c1f9ecf"
|
||||
"reference": "419b6e2e0a5dec35ea83a25758df9cd129b6c412"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/8496401234f73a49f8c4259d3e89ab4a7c1f9ecf",
|
||||
"reference": "8496401234f73a49f8c4259d3e89ab4a7c1f9ecf",
|
||||
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/419b6e2e0a5dec35ea83a25758df9cd129b6c412",
|
||||
"reference": "419b6e2e0a5dec35ea83a25758df9cd129b6c412",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
"ext-pdo": "*",
|
||||
"php": ">=8.0",
|
||||
"utopia-php/database": "0.30.*"
|
||||
"utopia-php/database": "0.31.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.2.*",
|
||||
"phpstan/phpstan": "1.9.x-dev",
|
||||
"phpunit/phpunit": "^9.4",
|
||||
"vimeo/psalm": "4.0.1"
|
||||
"phpstan/phpstan": "^1.9",
|
||||
"phpunit/phpunit": "^9.4"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
|
|
@ -1852,9 +1851,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/abuse/issues",
|
||||
"source": "https://github.com/utopia-php/abuse/tree/0.18.0"
|
||||
"source": "https://github.com/utopia-php/abuse/tree/0.19.0"
|
||||
},
|
||||
"time": "2023-02-14T09:56:04+00:00"
|
||||
"time": "2023-02-26T03:28:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/analytics",
|
||||
|
|
@ -1913,22 +1912,22 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/audit",
|
||||
"version": "0.20.0",
|
||||
"version": "0.21.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/audit.git",
|
||||
"reference": "3fce3f4ad3ea9dfcb39b79668abd76331412a5ed"
|
||||
"reference": "7f9783a14718c82570c6effb35a3cb42c30b13a2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/audit/zipball/3fce3f4ad3ea9dfcb39b79668abd76331412a5ed",
|
||||
"reference": "3fce3f4ad3ea9dfcb39b79668abd76331412a5ed",
|
||||
"url": "https://api.github.com/repos/utopia-php/audit/zipball/7f9783a14718c82570c6effb35a3cb42c30b13a2",
|
||||
"reference": "7f9783a14718c82570c6effb35a3cb42c30b13a2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-pdo": "*",
|
||||
"php": ">=8.0",
|
||||
"utopia-php/database": "0.30.*"
|
||||
"utopia-php/database": "0.31.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.2.*",
|
||||
|
|
@ -1956,9 +1955,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/audit/issues",
|
||||
"source": "https://github.com/utopia-php/audit/tree/0.20.0"
|
||||
"source": "https://github.com/utopia-php/audit/tree/0.21.0"
|
||||
},
|
||||
"time": "2023-02-14T09:46:54+00:00"
|
||||
"time": "2023-02-26T03:28:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/cache",
|
||||
|
|
@ -2115,16 +2114,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/database",
|
||||
"version": "0.30.1",
|
||||
"version": "0.31.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/database.git",
|
||||
"reference": "1cea72c1217357bf0747ae4f28ebef57e9dc0e65"
|
||||
"reference": "61f9f4743a317f1d78558a5f981adf74e7fdc931"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/1cea72c1217357bf0747ae4f28ebef57e9dc0e65",
|
||||
"reference": "1cea72c1217357bf0747ae4f28ebef57e9dc0e65",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/61f9f4743a317f1d78558a5f981adf74e7fdc931",
|
||||
"reference": "61f9f4743a317f1d78558a5f981adf74e7fdc931",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2163,9 +2162,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/database/issues",
|
||||
"source": "https://github.com/utopia-php/database/tree/0.30.1"
|
||||
"source": "https://github.com/utopia-php/database/tree/0.31.0"
|
||||
},
|
||||
"time": "2023-02-14T06:25:03+00:00"
|
||||
"time": "2023-02-23T09:49:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/domains",
|
||||
|
|
@ -3742,23 +3741,23 @@
|
|||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"version": "9.2.24",
|
||||
"version": "9.2.25",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||
"reference": "2cf940ebc6355a9d430462811b5aaa308b174bed"
|
||||
"reference": "0e2b40518197a8c0d4b08bc34dfff1c99c508954"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2cf940ebc6355a9d430462811b5aaa308b174bed",
|
||||
"reference": "2cf940ebc6355a9d430462811b5aaa308b174bed",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/0e2b40518197a8c0d4b08bc34dfff1c99c508954",
|
||||
"reference": "0e2b40518197a8c0d4b08bc34dfff1c99c508954",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
"nikic/php-parser": "^4.14",
|
||||
"nikic/php-parser": "^4.15",
|
||||
"php": ">=7.3",
|
||||
"phpunit/php-file-iterator": "^3.0.3",
|
||||
"phpunit/php-text-template": "^2.0.2",
|
||||
|
|
@ -3807,7 +3806,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.24"
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.25"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -3815,7 +3814,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-01-26T08:26:55+00:00"
|
||||
"time": "2023-02-25T05:32:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-file-iterator",
|
||||
|
|
@ -5127,16 +5126,16 @@
|
|||
},
|
||||
{
|
||||
"name": "squizlabs/php_codesniffer",
|
||||
"version": "3.7.1",
|
||||
"version": "3.7.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
|
||||
"reference": "1359e176e9307e906dc3d890bcc9603ff6d90619"
|
||||
"reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619",
|
||||
"reference": "1359e176e9307e906dc3d890bcc9603ff6d90619",
|
||||
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879",
|
||||
"reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -5172,14 +5171,15 @@
|
|||
"homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
|
||||
"keywords": [
|
||||
"phpcs",
|
||||
"standards"
|
||||
"standards",
|
||||
"static analysis"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
|
||||
"source": "https://github.com/squizlabs/PHP_CodeSniffer",
|
||||
"wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
|
||||
},
|
||||
"time": "2022-06-18T07:21:10+00:00"
|
||||
"time": "2023-02-22T23:07:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "swoole/ide-helper",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Account } from "appwrite";
|
||||
import { Client, Account } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Avatars } from "appwrite";
|
||||
import { Client, Avatars } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Avatars } from "appwrite";
|
||||
import { Client, Avatars } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Avatars } from "appwrite";
|
||||
import { Client, Avatars } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Avatars } from "appwrite";
|
||||
import { Client, Avatars } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Avatars } from "appwrite";
|
||||
import { Client, Avatars } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Avatars } from "appwrite";
|
||||
import { Client, Avatars } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Avatars } from "appwrite";
|
||||
import { Client, Avatars } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Databases } from "appwrite";
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, Functions } from "appwrite";
|
||||
import { Client, Functions } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client();
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue