1
0
Fork 0
mirror of synced 2024-06-01 18:39:57 +12:00

Merge branch 'master' of github.com:appwrite/appwrite into functions

This commit is contained in:
Eldad Fux 2020-07-07 00:08:03 +03:00
commit e31cf70171
37 changed files with 350 additions and 428 deletions

View file

@ -30,4 +30,4 @@ install:
script:
- docker ps
- docker exec appwrite bash test
- docker exec appwrite test

View file

@ -11,14 +11,14 @@
- Added support for Brotli compression (@PedroCisnerosSantana, @Rohitub222)
- New UI micro-interactions and CSS fixes (@AnatoleLucet)
- UI performance & accessibility improvments (#406)
- Updated ClamAV conntainer to version 1.0.9
- New Doctor CLI to debug the Appwrite server ([#415](https://github.com/appwrite/appwrite/issues/415))
- All emails are now sent asynchronously for improved performance (@TorstenDittmann)
- Updated grid for OAuth2 providers list in the console
- Upgraded Redis Resque queue library to version 1.3.6
- Added container names to docker-compose.yml (@drandell)
- Upgraded ClamAV container image to version 1.0.9
- Upgraded ClamAV container image to version 1.0.11 ([#412](https://github.com/appwrite/appwrite/issues/412))
- Optimised function execution by using fully-qualified function calls
- Added support for boolean 'true' and 'false' in query strings alongside 1 and 0
## Bug Fixes
@ -34,6 +34,15 @@
- Fixed wrong JSON validation when creating and updating database documnets
- Fixed bug where max file size was limited to max of 10MB
- Fixed bug preventing the deletion of the project logo
- Fixed Bug when trying to overwrite OAuth cookie in the Flutter SDK
- Fixed OAuth redirect when using the self-hosted instance default success URL ([#454](https://github.com/appwrite/appwrite/issues/454))
- Fixed bug denying authentication with Github OAuth provider
- New OAuth adapter for Box.com
- New OAuth adapter for PayPal sandbox
## Breaking Changes
- **Deprecated** `first` and `last` query params for documents list route in the database API
- **Deprecated** Deprectaed Pubjabi Translations ('pn')
## Security

View file

@ -151,6 +151,12 @@ bash ./build.sh X.X.X
Before running the command, make sure you have proper write permissions to the Appwrite docker hub team.
**Build for multicore**
```bash
docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t appwrite/multicore:0.0.0 --push
```
## Tests
To run tests manually, run phpunit from your command line:

View file

@ -31,7 +31,6 @@ return [
'no', // Norwegian
'ph', // Filipino
'pl', // Polish
'pn', // Punjabi
'pt-br', // Portuguese - Brazil
'pt-pt', // Portuguese - Portugal
'ro', // Romanian

View file

@ -1,10 +0,0 @@
<?php
return [
'AF' => 'ਅਫਰੀਕਾ',
'AN' => 'ਅੰਤਾਰਕਟੀਕਾ',
'AS' => 'ਏਸੀਆਈ',
'EU' => 'ਯੂਰੋਪਾ',
'NA' => 'ਨੂਰਡ-ਅਮੇਰਿਕਾ',
'OC' => 'ਓਸੀਆਨੀ',
'SA' => 'ਸੂਡ-ਅਮੇਰਿਕਾ',
];

View file

@ -1,197 +0,0 @@
<?php
return [
'AF' => 'ਅਫਗਾਨਿਸਤਾਨ',
'AO' => 'ਅੰਗੋਲਾ',
'AL' => 'ਅਲਬਾਨੀë',
'AD' => 'ਅੰਡੋਰਾ',
'AE' => 'Verenigde ਅਰਬਿਅਨ ਅਮੀਰਾਤ',
'AR' => 'ਅਰਜਨਟੀਨੀë',
'AM' => 'ਅਰਮੀਨੀë',
'AG' => 'ਐਂਟੀਗੁਆ ਐਨ ਬਾਰਬੁਡਾ',
'AU' => 'ਆਸਟਰੇਲੀਆਈ',
'AT' => 'ਓਓਸਟੇਨਰੀਕ',
'AZ' => 'ਅਜ਼ਰਬਾਈਜਾਨ',
'BI' => 'ਬੁਰੂੰਡੀ',
'BE' => 'ਬੈਲਜੀë',
'BJ' => 'ਬੇਨਿਨ',
'BF' => 'ਬੁਰਕੀਨਾ ਫਾਸੋ',
'BD' => 'ਬੰਗਲਾਦੇਸ਼',
'BG' => 'ਬੁਲਗਾਰੀ',
'BH' => 'ਬਹਿਰੀਨ',
'BS' => 'ਬਾਹਾਮਸ',
'BA' => 'ਬੋਸਨੀਅ ਇਨ ਹਰਜ਼ੈਗੋਵਿਨਾ',
'BY' => 'ਬੇਲਾਰੂਸ',
'BZ' => 'ਬੇਲੀਜ਼',
'BO' => 'ਬੋਲੀਵੀਆ',
'BR' => 'ਬ੍ਰਾਸੀਲੀë',
'BB' => 'ਬਾਰਬਾਡੋਸ',
'BN' => 'ਬਰੂਨੇਈ',
'BT' => 'ਭੋਏਤਨ',
'BW' => 'ਬੋਤਸਵਾਨਾ',
'CF' => 'ਮੱਧ ਅਫ਼ਰੀਕੀ ਗਣਰਾਜ',
'CA' => 'ਕਨਡਾ',
'CH' => 'ਸਵਿਟਜ਼ਰਲੈਂਡ',
'CL' => 'ਚਿਲੀ',
'CN' => 'ਸਜੀਨਾ',
'CI' => 'ਇਵੋੋਰਕਸ',
'CM' => 'ਕਾਮਰੋਇਨ',
'CD' => 'ਡੈਮੋਕਰੇਟੀਜ਼ ਰਿਪਬਲਿਕ ਵੈਨ ਡਾਈ ਕੌਂਗੋ',
'CG' => 'ਰਿਪਬਲਿਕ ਵੈਨ ਡਾਈ ਕੌਂਗੋ',
'CO' => 'ਕੋਲੰਬੀਆ',
'KM' => 'ਕੋਮੋਰੋਜ਼',
'CV' => 'ਕਾਪ ਵਰਡੇ',
'CR' => 'ਕੋਸਟਾਰੀਕਾ',
'CU' => 'ਕੁਬਾ',
'CY' => 'ਸਾਈਪ੍ਰਸ',
'CZ' => 'ਸਿਜ਼ੈਗੀ ਰੀਪਬਲਿਕ',
'DE' => 'ਡਿਟਸਲੈਂਡ',
'DJ' => 'ਜਾਇਬੂਤੀ',
'DM' => 'ਡੋਮਿਨਿਕਾ',
'DK' => 'ਡੀਨੇਮਾਰਕ',
'DO' => 'ਡੋਮੀਨੀਕੇਂਸ ਰਿਪਬਲਿਕ',
'DZ' => 'ਅਲਜੀਰੀਆ',
'EC' => 'ਇਕੂਏਟਰ',
'EG' => 'ਐਗਪੇਟ',
'ER' => 'ਏਰੀਟਰੀਆ',
'ES' => 'ਸਪੰਜੇ',
'EE' => 'ਐਸਟਲੈਂਡ',
'ET' => 'ਈਥੀਓਪੀਅ',
'FI' => 'ਫਿਨਲੈਂਡ',
'FJ' => 'ਫਿਦਜੀ',
'FR' => 'ਫ੍ਰੈਂਕ੍ਰੀਕ',
'FM' => 'ਮਿਕਰੋਨੇਸੀ',
'GA' => 'ਗਾਬੋਅਨ',
'GB' => 'Verenigde Koninkryk',
'GE' => 'ਜਾਰਜੀਆ',
'GH' => 'ਘਾਨਾ',
'GN' => 'ਗਿੰਨੀ',
'GM' => 'ਗਾਮੀ',
'GW' => 'ਗਿੰਨੀ-ਬਿਸਾਉ',
'GQ' => 'ਏਕਵੇਟਰਿਆਲ-ਗਿੰਨੀ',
'GR' => 'ਗ੍ਰੀਕਲੈਂਡ',
'GD' => 'ਗ੍ਰੇਨਾਡਾ',
'GT' => 'ਗੁਆਟੇਮਾਲਾ',
'GY' => 'ਗੁਆਨਾ',
'HN' => 'ਹੌਂਡੂਰਸ',
'HR' => 'ਕ੍ਰੋਸੀë',
'HT' => 'ਹੈਤੀ',
'HU' => 'ਹਾਂਗਰੀ',
'ID' => 'ਇੰਡੋਨੇਸ਼ੀਆਈ',
'IN' => 'ਇੰਡੀë',
'IE' => 'ਆਇਰਲੈਂਡ',
'IR' => 'ਇਰਾਨ',
'IQ' => 'ਇਰਕ',
'IS' => 'Ysland',
'IL' => 'ਇਜ਼ਰਾਈਲ',
'IT' => 'ਇਟਾਲੀë',
'JM' => 'ਜਮਾਏਕਾ',
'JO' => 'ਜਾਰਡਨ',
'JP' => 'ਜਪਾਨ',
'KZ' => 'ਕਜ਼ਾਕਸਤਾਨ',
'KE' => 'ਕੀਨੀਆ',
'KG' => 'ਕਿਰਗਿਸਤਾਨ',
'KH' => 'ਕੰਬੋਡਜਾ',
'KI' => 'ਕਿਰੀਬਾਤੀ',
'KN' => 'ਸੇਂਟ ਕਿਟਸ ਐਨ ਨੇਵਿਸ',
'KR' => 'ਸੂਡ-ਕੋਰੀਆ',
'KW' => 'ਕੁਵੈਤ',
'LA' => 'ਲਾਓਸ',
'LB' => 'ਲਿਬਨਾਨ',
'LR' => 'ਲਿਬੇਰੀë',
'LY' => 'ਲੀਬੀë',
'LC' => 'ਸੇਂਟ ਲੂਸੀਆ',
'LI' => 'ਲਿਚਟੇਨਸਟਾਈਨ',
'LK' => 'ਸ਼ਿਰੀਲੰਕਾ',
'LS' => 'ਲੈਸੋਥੋ',
'LT' => 'ਲੀਟਾ',
'LU' => 'ਲਕਸਮਬਰਗ',
'LV' => 'ਲਾਤਵੀਆ',
'MA' => 'ਮਾਰੋਕੋ',
'MC' => 'ਮੋਨੈਕੋ',
'MD' => 'ਮੋਲਦਾਵੀ',
'MG' => 'ਮੈਡਾਗਾਸਕਰ',
'MV' => 'ਮਾਲਦੀਵ',
'MX' => 'ਮੇਕਸਿਕੋ',
'MH' => 'ਮਾਰਸ਼ਲ-ਆਈਲੈਂਡ',
'MK' => 'ਮੈਸੇਡੋਨੀë',
'ML' => 'ਮਾਲੀ',
'MT' => 'ਮਾਲਟਾ',
'MM' => 'ਮਿਆਂਮਾਰ',
'ME' => 'ਮੌਂਟੇਨੇਗਰੋ',
'MN' => 'ਮੰਗੋਲੀë',
'MZ' => 'ਮੋਸਾਮਬੀਕ',
'MR' => 'ਮੌਰੀਟਨੀë',
'MU' => 'ਮਾਰੀਸ਼ਸ',
'MW' => 'ਮਾਲਾਵੀ',
'MY' => 'ਮਲੇਸੀਆਈ',
'NA' => 'ਨਾਮੀਬੀ',
'NE' => 'ਨਾਈਜਰ',
'NG' => 'ਨਾਈਜੀਰੀë',
'NI' => 'ਨਿਕਾਰਾਗੁਆ',
'NL' => 'ਨੀਡਰਲੈਂਡ',
'NO' => 'ਨੂਰਵੇë',
'NP' => 'ਨੇਪਾਲ',
'NR' => 'ਨੌਰੂ',
'NZ' => 'ਨਿie-ਸੀਲੈਂਡ',
'OM' => 'ਓਮਾਨ',
'PK' => 'ਪਾਕਿਸਤਾਨ',
'PA' => 'ਪਨਾਮਾ',
'PE' => 'ਪੇਰੂ',
'PH' => 'ਫਿਲਪੀਨ',
'PW' => 'ਪਲਾਉ',
'PG' => 'ਪਾਪੀਆ-ਨੀਯੂ-ਗਿੰਨੀ',
'PL' => 'ਪੋਲ',
'KP' => 'ਨੂਰਡ-ਕੋਰੀਆ',
'PT' => 'ਪੁਰਤਗਾਲ',
'PY' => 'ਪੈਰਾਗੁਏ',
'QA' => 'ਕਟਾਰ',
'RO' => 'ਰੋਮੇਨੀਅ',
'RU' => 'ਰਸਲੈਂਡ',
'RW' => 'ਰਵਾਂਡਾ',
'SA' => 'ਸਾਓਦੀ-ਅਰਾਬੀ',
'SD' => 'ਸੋਦਾਨ',
'SN' => 'ਸੇਨੇਗਲ',
'SG' => 'ਸਿੰਗਾਪੁਰ',
'SB' => 'ਸਲੋਮੋ-ਆਈਲੈਂਡ',
'SL' => 'ਸੀਅਰਾ ਲਿਓਨ',
'SV' => 'ਐਲ ਸਾਲਵਾਡੋਰ',
'SM' => 'ਸੈਨ ਮਰੀਨੋ',
'SO' => 'ਸੋਮਾਲੀë',
'RS' => 'ਸਰਵੀë',
'SS' => 'ਸੂਇਡ-ਸੋਦਾਨ',
'ST' => 'ਸਾਓ ਤੋਮੇ ਐਨ ਪ੍ਰਿੰਸੀਪੇ',
'SR' => 'ਸੂਰੀਨਾਮ',
'SK' => 'ਸਲੋਕਯੇ',
'SI' => 'ਹੌਲੀ',
'SE' => 'ਸਵੈਡੇ',
'SZ' => 'ਸਵਾਜ਼ੀਲੈਂਡ',
'SC' => 'ਸੇਸ਼ੇਲ',
'SY' => 'ਸਿਰੀ',
'TD' => 'ਚਾਡ',
'TG' => 'ਹੁਣੇ ਜਾਣਾ',
'TH' => 'ਥਾਈਲੈਂਡ',
'TJ' => 'ਤਦਜਿਕਿਸਤਾਨ',
'TM' => 'ਤੁਰਕਮੇਨਿਸਤਾਨ',
'TL' => 'ਓਸ-ਤਿਮੋਰ',
'TO' => 'ਟੋਂਗਾ',
'TT' => 'ਤ੍ਰਿਨੀਦਾਦ ਅਤੇ ਟੋਬੈਗੋ',
'TN' => 'ਟਿisਨੀਸੀਅ',
'TR' => 'ਤੁਰਕੀ',
'TV' => 'ਤੁਵਾਲੁ',
'TZ' => 'ਤਨਜ਼ਾਨੀë',
'UG' => 'ਯੂਗਾਂਡਾ',
'UA' => 'ਓਕ੍ਰਾੱਨ',
'UY' => 'ਉਰੂਗਵੇ',
'US' => 'ਵੇਰੇਨਿਗਡੇ ਸਟੇਟ',
'UZ' => 'ਓਸਬੀਕਕਿਸਤਾਨ',
'VA' => 'ਵਾਟਿਕਾਂਸਟੈਡ',
'VC' => 'ਸਿਨਟ ਵਿਨਸੈਂਟ ਏਨ ਡਾਈ ਗ੍ਰੇਨਾਡਾਈਨਜ਼',
'VE' => 'ਵੈਨਜ਼ੂਏਲਾ',
'VN' => 'ਵਿਯਤਨਮ',
'VU' => 'ਵੈਨੂਆਟੂ',
'WS' => 'ਸਮੋਆ',
'YE' => 'ਜੀਮਨ',
'ZA' => 'ਸੂਡ-ਅਫਰੀਕਾ',
'ZM' => 'ਜ਼ੈਂਬੀਆ',
'ZW' => 'ਜ਼ਿੰਬਾਬਵੇ',
];

View file

@ -1,17 +0,0 @@
<?php
return [
'settings.inspire' => '"I love Typing&coding in punjabi :)."', // This is the line printed in the homepage and console 'view-source'
'settings.locale' => 'pn',
'settings.direction' => 'ltr',
// Service - Users
'account.emails.team' => '%s ਟੀਮ(Priyanka)',
'account.emails.verification.title' => 'ਖਾਤਾ ਪੁਸ਼ਟੀਕਰਣ',
'account.emails.verification.body' => 'app/config/locales/templates/pn.email.auth.confirm.tpl',
'account.emails.recovery.title' => 'ਪਾਸਵਰਡ ਰੀਸੈੱਟ',
'account.emails.recovery.body' => 'app/config/locales/templates/pn.email.auth.recovery.tpl',
'account.emails.invitation.title' => '% S ਟੀਮ% s ਤੇ ਸੱਦਾ',
'account.emails.invitation.body' => 'app/config/locales/templates/pn.email.auth.invitation.tpl',
'locale.country.unknown' => 'India',
'countries' => include 'pn.countries.php',
'continents' => include 'pn.continents.php',
];

View file

@ -1,15 +0,0 @@
<p>
ਹੈਲੋ {{name}},
</p>
<p>
ਆਪਣੇ ਈਮੇਲ ਪਤੇ ਦੀ ਪੁਸ਼ਟੀ ਕਰਨ ਲਈ ਇਸ ਲਿੰਕ ਦਾ ਪਾਲਣ ਕਰੋ:
</p>
{{cta}}
<p>
ਜੇ ਤੁਸੀਂ ਇਸ ਪਤੇ ਨੂੰ ਪ੍ਰਮਾਣਿਤ ਕਰਨ ਲਈ ਨਹੀਂ ਕਿਹਾ, ਤਾਂ ਤੁਸੀਂ ਇਸ ਸੁਨੇਹੇ ਨੂੰ ਨਜ਼ਰ ਅੰਦਾਜ਼ ਕਰ ਸਕਦੇ ਹੋ.
</p>
<p>
ਧੰਨਵਾਦ,
<br />
{{project}} ਟੀਮ
</p>

View file

@ -1,18 +0,0 @@
<p>
ਸਤ ਸ੍ਰੀ ਅਕਾਲ,
</p>
<p>
ਇਹ ਮੇਲ ਤੁਹਾਨੂੰ ਇਸ ਲਈ ਭੇਜਿਆ ਗਿਆ ਸੀ ਕਿਉਂਕਿ <b> {{owner}} </ b> ਤੁਹਾਨੂੰ <b> {{team} at </b> {{project}} ' .
</p>
<p>
<b> {{team}} </ b> ਟੀਮ ਵਿੱਚ ਸ਼ਾਮਲ ਹੋਣ ਲਈ ਇਸ ਲਿੰਕ ਦਾ ਪਾਲਣ ਕਰੋ:
</p>
{{cta}}
<p>
ਜੇ ਤੁਸੀਂ ਦਿਲਚਸਪੀ ਨਹੀਂ ਰੱਖਦੇ, ਤਾਂ ਤੁਸੀਂ ਇਸ ਸੰਦੇਸ਼ ਨੂੰ ਨਜ਼ਰ ਅੰਦਾਜ਼ ਕਰ ਸਕਦੇ ਹੋ.
</p>
<p>
ਧੰਨਵਾਦ,
<br />
{{project}} ਟੀਮ
</p>

View file

@ -1,15 +0,0 @@
<p>
ਸਤ ਸ੍ਰੀ ਅਕਾਲ {{name}},
</p>
<p>
ਆਪਣੇ {{project}} ਪਾਸਵਰਡ ਨੂੰ ਰੀਸੈਟ ਕਰਨ ਲਈ ਇਸ ਲਿੰਕ ਦਾ ਪਾਲਣ ਕਰੋ.
</p>
{{cta}}
<p>
ਜੇ ਤੁਸੀਂ ਆਪਣਾ ਪਾਸਵਰਡ ਰੀਸੈਟ ਕਰਨ ਲਈ ਨਹੀਂ ਕਿਹਾ, ਤਾਂ ਤੁਸੀਂ ਇਸ ਸੁਨੇਹੇ ਨੂੰ ਨਜ਼ਰ ਅੰਦਾਜ਼ ਕਰ ਸਕਦੇ ਹੋ.
</p>
<p>
ਧੰਨਵਾਦ,
<br />
{{project}} ਟੀਮ
</p>

View file

@ -2,6 +2,7 @@
return [ // Ordered by ABC.
'amazon' => [
'name' => 'Amazon',
'developers' => 'https://developer.amazon.com/apps-and-games/services-and-apis',
'icon' => 'icon-amazon',
'enabled' => true,
@ -10,6 +11,7 @@ return [ // Ordered by ABC.
'mock' => false,
],
'apple' => [
'name' => 'Apple',
'developers' => 'https://developer.apple.com/',
'icon' => 'icon-apple',
'enabled' => true,
@ -18,6 +20,7 @@ return [ // Ordered by ABC.
'mock' => false,
],
'bitbucket' => [
'name' => 'BitBucket',
'developers' => 'https://developer.atlassian.com/bitbucket',
'icon' => 'icon-bitbucket',
'enabled' => true,
@ -26,6 +29,7 @@ return [ // Ordered by ABC.
'mock' => false,
],
'bitly' => [
'name' => 'Bitly',
'developers' => 'https://dev.bitly.com/v4_documentation.html',
'icon' => 'icon-bitly',
'enabled' => true,
@ -33,7 +37,17 @@ return [ // Ordered by ABC.
'beta' => false,
'mock' => false
],
'box' => [
'name' => 'Box',
'developers' => 'https://developer.box.com/reference/',
'icon' => 'icon-box',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => false
],
'discord' => [
'name' => 'Discord',
'developers' => 'https://discordapp.com/developers/docs/topics/oauth2',
'icon' => 'icon-discord',
'enabled' => true,
@ -42,6 +56,7 @@ return [ // Ordered by ABC.
'mock' => false,
],
'dropbox' => [
'name' => 'Dropbox',
'developers' => 'https://www.dropbox.com/developers/documentation',
'icon' => 'icon-dropbox',
'enabled' => true,
@ -50,6 +65,7 @@ return [ // Ordered by ABC.
'mock' => false,
],
'facebook' => [
'name' => 'Facebook',
'developers' => 'https://developers.facebook.com/',
'icon' => 'icon-facebook',
'enabled' => true,
@ -58,6 +74,7 @@ return [ // Ordered by ABC.
'mock' => false,
],
'github' => [
'name' => 'GitHub',
'developers' => 'https://developer.github.com/',
'icon' => 'icon-github-circled',
'enabled' => true,
@ -66,6 +83,7 @@ return [ // Ordered by ABC.
'mock' => false,
],
'gitlab' => [
'name' => 'GitLab',
'developers' => 'https://docs.gitlab.com/ee/api/',
'icon' => 'icon-gitlab',
'enabled' => true,
@ -74,6 +92,7 @@ return [ // Ordered by ABC.
'mock' => false,
],
'google' => [
'name' => 'Google',
'developers' => 'https://support.google.com/googleapi/answer/6158849',
'icon' => 'icon-google',
'enabled' => true,
@ -82,6 +101,7 @@ return [ // Ordered by ABC.
'mock' => false,
],
'linkedin' => [
'name' => 'LinkedIn',
'developers' => 'https://developer.linkedin.com/',
'icon' => 'icon-linkedin',
'enabled' => true,
@ -90,6 +110,7 @@ return [ // Ordered by ABC.
'mock' => false,
],
'microsoft' => [
'name' => 'Microsoft',
'developers' => 'https://developer.microsoft.com/en-us/',
'icon' => 'icon-windows',
'enabled' => true,
@ -98,6 +119,16 @@ return [ // Ordered by ABC.
'mock' => false,
],
'paypal' => [
'name' => 'PayPal',
'developers' => 'https://developer.paypal.com/docs/api/overview/',
'icon' => 'icon-paypal',
'enabled' => true,
'form' => false,
'beta' => false,
'mock' => false
],
'paypalSandbox' => [
'name' => 'PayPal (Sandbox)',
'developers' => 'https://developer.paypal.com/docs/api/overview/',
'icon' => 'icon-paypal',
'enabled' => true,
@ -106,6 +137,7 @@ return [ // Ordered by ABC.
'mock' => false
],
'salesforce' => [
'name' => 'Salesforce',
'developers' => 'https://developer.salesforce.com/docs/',
'icon' => 'icon-salesforce',
'enabled' => true,
@ -114,6 +146,7 @@ return [ // Ordered by ABC.
'mock' => false,
],
'slack' => [
'name' => 'Slack',
'developers' => 'https://api.slack.com/',
'icon' => 'icon-slack',
'enabled' => true,
@ -122,6 +155,7 @@ return [ // Ordered by ABC.
'mock' => false,
],
'spotify' => [
'name' => 'Spotify',
'developers' => 'https://developer.spotify.com/documentation/general/guides/authorization-guide/',
'icon' => 'icon-spotify',
'enabled' => true,
@ -130,6 +164,7 @@ return [ // Ordered by ABC.
'mock' => false,
],
'twitch' => [
'name' => 'Twitch',
'developers' => 'https://dev.twitch.tv/docs/authentication',
'icon' => 'icon-twitch',
'enabled' => true,
@ -138,6 +173,7 @@ return [ // Ordered by ABC.
'mock' => false,
],
'vk' => [
'name' => 'VK',
'developers' => 'https://vk.com/dev',
'icon' => 'icon-vk',
'enabled' => true,
@ -146,6 +182,7 @@ return [ // Ordered by ABC.
'mock' => false,
],
'yahoo' => [
'name' => 'Yahoo',
'developers' => 'https://developer.yahoo.com/oauth2/guide/flows_authcode/',
'icon' => 'icon-yahoo',
'enabled' => true,
@ -154,6 +191,7 @@ return [ // Ordered by ABC.
'mock' => false,
],
'yandex' => [
'name' => 'Yandex',
'developers' => 'https://tech.yandex.com/oauth/',
'icon' => 'icon-yandex',
'enabled' => true,
@ -162,6 +200,7 @@ return [ // Ordered by ABC.
'mock' => false,
],
// 'instagram' => [
// 'name' => 'Instagram',
// 'developers' => 'https://www.instagram.com/developer/',
// 'icon' => 'icon-instagram',
// 'enabled' => false,
@ -169,6 +208,7 @@ return [ // Ordered by ABC.
// 'mock' => false,
// ],
// 'twitter' => [
// 'name' => 'twitter',
// 'developers' => 'https://developer.twitter.com/',
// 'icon' => 'icon-twitter',
// 'enabled' => false,
@ -177,6 +217,7 @@ return [ // Ordered by ABC.
// ],
// Keep Last
'mock' => [
'name' => 'Mock',
'developers' => 'https://appwrite.io',
'icon' => 'icon-appwrite',
'enabled' => true,

View file

@ -29,8 +29,8 @@ use DeviceDetector\DeviceDetector;
use GeoIp2\Database\Reader;
use Utopia\Validator\ArrayList;
$oauthDefaultSuccess = $request->getServer('_APP_HOME').'/auth/oauth2/success';
$oauthDefaultFailure = $request->getServer('_APP_HOME').'/auth/oauth2/failure';
$oauthDefaultSuccess = '/auth/oauth2/success';
$oauthDefaultFailure = '/auth/oauth2/failure';
$oauth2Keys = [];
@ -78,9 +78,8 @@ $utopia->post('/v1/account')
}
}
$profile = $projectDB->getCollection([ // Get user by email address
$profile = $projectDB->getCollectionFirst([ // Get user by email address
'limit' => 1,
'first' => true,
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_USERS,
'email='.$email,
@ -162,9 +161,8 @@ $utopia->post('/v1/account/sessions')
->action(
function ($email, $password) use ($response, $request, $projectDB, $audit, $webhook) {
$protocol = Config::getParam('protocol');
$profile = $projectDB->getCollection([ // Get user by email address
$profile = $projectDB->getCollectionFirst([ // Get user by email address
'limit' => 1,
'first' => true,
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_USERS,
'email='.$email,
@ -417,9 +415,8 @@ $utopia->get('/v1/account/sessions/oauth2/:provider/redirect')
$projectDB->deleteDocument($current); //throw new Exception('User already logged in', 401);
}
$user = (empty($user->getId())) ? $projectDB->getCollection([ // Get user by provider id
$user = (empty($user->getId())) ? $projectDB->getCollectionFirst([ // Get user by provider id
'limit' => 1,
'first' => true,
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_USERS,
'oauth2'.\ucfirst($provider).'='.$oauth2ID,
@ -430,9 +427,8 @@ $utopia->get('/v1/account/sessions/oauth2/:provider/redirect')
$name = $oauth2->getUserName($accessToken);
$email = $oauth2->getUserEmail($accessToken);
$user = $projectDB->getCollection([ // Get user by provider email address
$user = $projectDB->getCollectionFirst([ // Get user by provider email address
'limit' => 1,
'first' => true,
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_USERS,
'email='.$email,
@ -508,8 +504,9 @@ $utopia->get('/v1/account/sessions/oauth2/:provider/redirect')
->addHeader('X-Fallback-Cookies', \json_encode([Auth::$cookieName => Auth::encodeSession($user->getId(), $secret)]))
;
}
if ($state['success'] === $oauthDefaultSuccess) { // Add keys for non-web platforms
// Add keys for non-web platforms - TODO - add verification phase to aviod session sniffing
if (parse_url($state['success'], PHP_URL_PATH) === $oauthDefaultSuccess) {
$state['success'] = URLParser::parse($state['success']);
$query = URLParser::parseQuery($state['success']['query']);
$query['project'] = $project->getId();
@ -807,9 +804,8 @@ $utopia->patch('/v1/account/email')
throw new Exception('Invalid credentials', 401);
}
$profile = $projectDB->getCollection([ // Get user by email address
$profile = $projectDB->getCollectionFirst([ // Get user by email address
'limit' => 1,
'first' => true,
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_USERS,
'email='.$email,
@ -1071,9 +1067,8 @@ $utopia->post('/v1/account/recovery')
->param('url', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the recovery email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.')
->action(
function ($email, $url) use ($request, $response, $projectDB, $mail, $audit, $project) {
$profile = $projectDB->getCollection([ // Get user by email address
$profile = $projectDB->getCollectionFirst([ // Get user by email address
'limit' => 1,
'first' => true,
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_USERS,
'email='.$email,
@ -1177,9 +1172,8 @@ $utopia->put('/v1/account/recovery')
throw new Exception('Passwords must match', 400);
}
$profile = $projectDB->getCollection([ // Get user by email address
$profile = $projectDB->getCollectionFirst([ // Get user by email address
'limit' => 1,
'first' => true,
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_USERS,
'$id='.$userId,
@ -1329,9 +1323,8 @@ $utopia->put('/v1/account/verification')
->param('secret', '', function () { return new Text(256); }, 'Valid verification token.')
->action(
function ($userId, $secret) use ($response, $user, $projectDB, $audit) {
$profile = $projectDB->getCollection([ // Get user by email address
$profile = $projectDB->getCollectionFirst([ // Get user by email address
'limit' => 1,
'first' => true,
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_USERS,
'$id='.$userId,

View file

@ -3,6 +3,7 @@
global $utopia, $request, $response;
use Utopia\Exception;
use Utopia\Validator\Boolean;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
use Utopia\Validator\Range;
@ -364,7 +365,7 @@ $utopia->get('/v1/avatars/qr')
->param('text', '', function () { return new Text(512); }, 'Plain text to be converted to QR code image.')
->param('size', 400, function () { return new Range(0, 1000); }, 'QR code size. Pass an integer between 0 to 1000. Defaults to 400.', true)
->param('margin', 1, function () { return new Range(0, 10); }, 'Margin from edge. Pass an integer between 0 to 10. Defaults to 1.', true)
->param('download', 0, function () { return new Range(0, 1); }, 'Return resulting image with \'Content-Disposition: attachment \' headers for the browser to start downloading it. Pass 0 for no header, or 1 for otherwise. Default value is set to 0.', true)
->param('download', false, function () { return new Boolean(true); }, 'Return resulting image with \'Content-Disposition: attachment \' headers for the browser to start downloading it. Pass 0 for no header, or 1 for otherwise. Default value is set to 0.', true)
->label('scope', 'avatars.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'avatars')
@ -373,6 +374,8 @@ $utopia->get('/v1/avatars/qr')
->label('sdk.description', '/docs/references/avatars/get-qr.md')
->action(
function ($text, $size, $margin, $download) use ($response) {
$download = ($download === '1' || $download === 'true' || $download === 1 || $download === true);
$renderer = new ImageRenderer(
new RendererStyle($size, $margin),
new ImagickImageBackEnd('png', 100)

View file

@ -5,14 +5,15 @@ global $utopia, $register, $request, $response, $webhook, $audit, $projectDB;
use Utopia\App;
use Utopia\Exception;
use Utopia\Response;
use Utopia\Validator\Boolean;
use Utopia\Validator\Range;
use Utopia\Validator\WhiteList;
use Utopia\Validator\Text;
use Utopia\Validator\ArrayList;
use Utopia\Validator\JSON;
use Utopia\Locale\Locale;
use Utopia\Audit\Audit;
use Utopia\Audit\Adapters\MySQL as AuditAdapter;
// use Utopia\Locale\Locale;
// use Utopia\Audit\Audit;
// use Utopia\Audit\Adapters\MySQL as AuditAdapter;
use Appwrite\Database\Database;
use Appwrite\Database\Document;
use Appwrite\Database\Validator\UID;
@ -22,8 +23,9 @@ use Appwrite\Database\Validator\Collection;
use Appwrite\Database\Validator\Authorization;
use Appwrite\Database\Exception\Authorization as AuthorizationException;
use Appwrite\Database\Exception\Structure as StructureException;
use DeviceDetector\DeviceDetector;
use GeoIp2\Database\Reader;
// use DeviceDetector\DeviceDetector;
// use GeoIp2\Database\Reader;
$utopia->post('/v1/database/collections')
->desc('Create Collection')
@ -481,10 +483,8 @@ $utopia->get('/v1/database/collections/:collectionId/documents')
->param('orderType', 'ASC', function () { return new WhiteList(array('DESC', 'ASC')); }, 'Order direction. Possible values are DESC for descending order, or ASC for ascending order.', true)
->param('orderCast', 'string', function () { return new WhiteList(array('int', 'string', 'date', 'time', 'datetime')); }, 'Order field type casting. Possible values are int, string, date, time or datetime. The database will attempt to cast the order field to the value you pass here. The default value is a string.', true)
->param('search', '', function () { return new Text(256); }, 'Search query. Enter any free text search. The database will try to find a match against all document attributes and children.', true)
->param('first', 0, function () { return new Range(0, 1); }, 'Return only the first document. Pass 1 for true or 0 for false. The default value is 0.', true)
->param('last', 0, function () { return new Range(0, 1); }, 'Return only the last document. Pass 1 for true or 0 for false. The default value is 0.', true)
->action(
function ($collectionId, $filters, $offset, $limit, $orderField, $orderType, $orderCast, $search, $first, $last) use ($response, $projectDB, $utopia) {
function ($collectionId, $filters, $offset, $limit, $orderField, $orderType, $orderCast, $search) use ($response, $projectDB, $utopia) {
$collection = $projectDB->getDocument($collectionId, false);
if (\is_null($collection->getId()) || Database::SYSTEM_COLLECTION_COLLECTIONS != $collection->getCollection()) {
@ -498,38 +498,32 @@ $utopia->get('/v1/database/collections/:collectionId/documents')
'orderType' => $orderType,
'orderCast' => $orderCast,
'search' => $search,
'first' => (bool) $first,
'last' => (bool) $last,
'filters' => \array_merge($filters, [
'$collection='.$collectionId,
]),
]);
if ($first || $last) {
$response->json((!empty($list) ? $list->getArrayCopy() : []));
} else {
if ($utopia->isDevelopment()) {
$collection
->setAttribute('debug', $projectDB->getDebug())
->setAttribute('limit', $limit)
->setAttribute('offset', $offset)
->setAttribute('orderField', $orderField)
->setAttribute('orderType', $orderType)
->setAttribute('orderCast', $orderCast)
->setAttribute('filters', $filters)
;
}
if ($utopia->isDevelopment()) {
$collection
->setAttribute('sum', $projectDB->getSum())
->setAttribute('documents', $list)
->setAttribute('debug', $projectDB->getDebug())
->setAttribute('limit', $limit)
->setAttribute('offset', $offset)
->setAttribute('orderField', $orderField)
->setAttribute('orderType', $orderType)
->setAttribute('orderCast', $orderCast)
->setAttribute('filters', $filters)
;
/*
* View
*/
$response->json($collection->getArrayCopy(/*['$id', '$collection', 'name', 'documents']*/[], ['rules']));
}
$collection
->setAttribute('sum', $projectDB->getSum())
->setAttribute('documents', $list)
;
/*
* View
*/
$response->json($collection->getArrayCopy(/*['$id', '$collection', 'name', 'documents']*/[], ['rules']));
}
);

View file

@ -5,10 +5,10 @@ global $utopia, $request, $response, $register, $user, $consoleDB, $projectDB, $
use Utopia\Exception;
use Utopia\Response;
use Utopia\Validator\ArrayList;
use Utopia\Validator\Boolean;
use Utopia\Validator\Domain as DomainValidator;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
use Utopia\Validator\Range;
use Utopia\Validator\URL;
use Utopia\Config\Config;
use Utopia\Domains\Domain;
@ -454,7 +454,7 @@ $utopia->post('/v1/projects/:projectId/webhooks')
->param('name', null, function () { return new Text(256); }, 'Webhook name.')
->param('events', null, function () { return new ArrayList(new Text(256)); }, 'Webhook events list.')
->param('url', null, function () { return new Text(2000); }, 'Webhook URL.')
->param('security', null, function () { return new Range(0, 1); }, 'Certificate verification, 0 for disabled or 1 for enabled.')
->param('security', false, function () { return new Boolean(true); }, 'Certificate verification, false for disabled or true for enabled.')
->param('httpUser', '', function () { return new Text(256); }, 'Webhook HTTP user.', true)
->param('httpPass', '', function () { return new Text(256); }, 'Webhook HTTP password.', true)
->action(
@ -465,6 +465,7 @@ $utopia->post('/v1/projects/:projectId/webhooks')
throw new Exception('Project not found', 404);
}
$security = ($security === '1' || $security === 'true' || $security === 1 || $security === true);
$key = $request->getServer('_APP_OPENSSL_KEY_V1');
$iv = OpenSSL::randomPseudoBytes(OpenSSL::cipherIVLength(OpenSSL::CIPHER_AES_128_GCM));
$tag = null;
@ -587,8 +588,7 @@ $utopia->put('/v1/projects/:projectId/webhooks/:webhookId')
->param('name', null, function () { return new Text(256); }, 'Webhook name.')
->param('events', null, function () { return new ArrayList(new Text(256)); }, 'Webhook events list.')
->param('url', null, function () { return new Text(2000); }, 'Webhook URL.')
->param('security', null, function () { return new Range(0, 1); }, 'Certificate verification, 0 for disabled or 1 for enabled.')
->param('httpUser', '', function () { return new Text(256); }, 'Webhook HTTP user.', true)
->param('security', false, function () { return new Boolean(true); }, 'Certificate verification, false for disabled or true for enabled.') ->param('httpUser', '', function () { return new Text(256); }, 'Webhook HTTP user.', true)
->param('httpPass', '', function () { return new Text(256); }, 'Webhook HTTP password.', true)
->action(
function ($projectId, $webhookId, $name, $events, $url, $security, $httpUser, $httpPass) use ($request, $response, $consoleDB) {
@ -598,6 +598,7 @@ $utopia->put('/v1/projects/:projectId/webhooks/:webhookId')
throw new Exception('Project not found', 404);
}
$security = ($security === '1' || $security === 'true' || $security === 1 || $security === true);
$key = $request->getServer('_APP_OPENSSL_KEY_V1');
$iv = OpenSSL::randomPseudoBytes(OpenSSL::cipherIVLength(OpenSSL::CIPHER_AES_128_GCM));
$tag = null;
@ -835,8 +836,7 @@ $utopia->post('/v1/projects/:projectId/tasks')
->param('name', null, function () { return new Text(256); }, 'Task name.')
->param('status', null, function () { return new WhiteList(['play', 'pause']); }, 'Task status.')
->param('schedule', null, function () { return new Cron(); }, 'Task schedule CRON syntax.')
->param('security', null, function () { return new Range(0, 1); }, 'Certificate verification, 0 for disabled or 1 for enabled.')
->param('httpMethod', '', function () { return new WhiteList(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT']); }, 'Task HTTP method.')
->param('security', false, function () { return new Boolean(true); }, 'Certificate verification, false for disabled or true for enabled.') ->param('httpMethod', '', function () { return new WhiteList(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT']); }, 'Task HTTP method.')
->param('httpUrl', '', function () { return new URL(); }, 'Task HTTP URL')
->param('httpHeaders', null, function () { return new ArrayList(new Text(256)); }, 'Task HTTP headers list.', true)
->param('httpUser', '', function () { return new Text(256); }, 'Task HTTP user.', true)
@ -852,6 +852,7 @@ $utopia->post('/v1/projects/:projectId/tasks')
$cron = CronExpression::factory($schedule);
$next = ($status == 'play') ? $cron->getNextRunDate()->format('U') : null;
$security = ($security === '1' || $security === 'true' || $security === 1 || $security === true);
$key = $request->getServer('_APP_OPENSSL_KEY_V1');
$iv = OpenSSL::randomPseudoBytes(OpenSSL::cipherIVLength(OpenSSL::CIPHER_AES_128_GCM));
$tag = null;
@ -985,7 +986,7 @@ $utopia->put('/v1/projects/:projectId/tasks/:taskId')
->param('name', null, function () { return new Text(256); }, 'Task name.')
->param('status', null, function () { return new WhiteList(['play', 'pause']); }, 'Task status.')
->param('schedule', null, function () { return new Cron(); }, 'Task schedule CRON syntax.')
->param('security', null, function () { return new Range(0, 1); }, 'Certificate verification, 0 for disabled or 1 for enabled.')
->param('security', false, function () { return new Boolean(true); }, 'Certificate verification, false for disabled or true for enabled.')
->param('httpMethod', '', function () { return new WhiteList(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT']); }, 'Task HTTP method.')
->param('httpUrl', '', function () { return new URL(); }, 'Task HTTP URL.')
->param('httpHeaders', null, function () { return new ArrayList(new Text(256)); }, 'Task HTTP headers list.', true)
@ -1008,6 +1009,7 @@ $utopia->put('/v1/projects/:projectId/tasks/:taskId')
$cron = CronExpression::factory($schedule);
$next = ($status == 'play') ? $cron->getNextRunDate()->format('U') : null;
$security = ($security === '1' || $security === 'true' || $security === 1 || $security === true);
$key = $request->getServer('_APP_OPENSSL_KEY_V1');
$iv = OpenSSL::randomPseudoBytes(OpenSSL::cipherIVLength(OpenSSL::CIPHER_AES_128_GCM));
$tag = null;

View file

@ -236,9 +236,8 @@ $utopia->post('/v1/teams/:teamId/memberships')
],
]);
$invitee = $projectDB->getCollection([ // Get user by email address
$invitee = $projectDB->getCollectionFirst([ // Get user by email address
'limit' => 1,
'first' => true,
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_USERS,
'email='.$email,
@ -484,9 +483,8 @@ $utopia->patch('/v1/teams/:teamId/memberships/:inviteId/status')
}
if (empty($user->getId())) {
$user = $projectDB->getCollection([ // Get user
$user = $projectDB->getCollectionFirst([ // Get user
'limit' => 1,
'first' => true,
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_USERS,
'$id='.$userId,

View file

@ -34,9 +34,8 @@ $utopia->post('/v1/users')
->param('name', '', function () { return new Text(100); }, 'User name.', true)
->action(
function ($email, $password, $name) use ($response, $projectDB) {
$profile = $projectDB->getCollection([ // Get user by email address
$profile = $projectDB->getCollectionFirst([ // Get user by email address
'limit' => 1,
'first' => true,
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_USERS,
'email='.$email,

View file

@ -457,6 +457,10 @@ $utopia->get('/open-api-2.json')
$node['type'] = 'string';
$node['x-example'] = '['.\strtoupper(fromCamelCase($node['name'])).']';
break;
case 'Utopia\Validator\Boolean':
$node['type'] = 'boolean';
$node['x-example'] = false;
break;
case 'Appwrite\Database\Validator\UID':
$node['type'] = 'string';
$node['x-example'] = '['.\strtoupper(fromCamelCase($node['name'])).']';

View file

@ -204,7 +204,6 @@ Locale::setLanguage('nl', include __DIR__.'/config/locales/nl.php');
Locale::setLanguage('no', include __DIR__.'/config/locales/no.php');
Locale::setLanguage('ph', include __DIR__.'/config/locales/ph.php');
Locale::setLanguage('pl', include __DIR__.'/config/locales/pl.php');
Locale::setLanguage('pn', include __DIR__.'/config/locales/pn.php');
Locale::setLanguage('pt-br', include __DIR__.'/config/locales/pt-br.php');
Locale::setLanguage('pt-pt', include __DIR__.'/config/locales/pt-pt.php');
Locale::setLanguage('ro', include __DIR__.'/config/locales/ro.php');

View file

@ -309,13 +309,14 @@ $providers = $this->getParam('providers', []);
if (isset($data['enabled']) && !$data['enabled']) { continue; }
if (isset($data['mock']) && $data['mock']) { continue; }
$form = (isset($data['form'])) ? $data['form'] : false;
$name = (isset($data['name'])) ? $data['name'] : 'Unknown';
$beta = (isset($data['beta'])) ? $data['beta'] : false;
?>
<li class="<?php echo (isset($data['enabled']) && !$data['enabled']) ? 'dev-feature' : ''; ?>">
<div data-ui-modal class="modal close" data-button-alias="none" data-open-event="provider-update-<?php echo $provider; ?>">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h1><?php echo $this->escape(ucfirst($provider)); ?> OAuth2 Settings</h1>
<h1><?php echo $this->escape($name); ?> OAuth2 Settings</h1>
<form
data-analytics-event="submit"
@ -379,7 +380,7 @@ $providers = $this->getParam('providers', []);
<img src="/images/oauth2/<?php echo $this->escape(strtolower($provider)); ?>.png?buster=<?php echo APP_CACHE_BUSTER; ?>" alt="<?php echo $this->escape(ucfirst($provider)); ?> Logo" class="pull-start provider margin-end" />
<span class="text-size-small">
<?php echo ucfirst($provider); ?> <?php if($beta): ?>(beta)<?php endif; ?>
<?php echo $this->escape($name); ?> <?php if($beta): ?>(beta)<?php endif; ?>
</span>
<p class="margin-bottom-no text-one-liner text-size-small">

View file

@ -78,7 +78,7 @@ class CertificatesV1
}
}
$certificate = $consoleDB->getCollection([
$certificate = $consoleDB->getCollectionFirst([
'limit' => 1,
'offset' => 0,
'orderField' => 'id',
@ -88,7 +88,6 @@ class CertificatesV1
'$collection='.Database::SYSTEM_COLLECTION_CERTIFICATES,
'domain='.$domain->get(),
],
'first' => true,
]);
// $condition = ($certificate

25
composer.lock generated
View file

@ -1942,16 +1942,16 @@
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
"reference": "a491d65139e2411c75704e871dd02bdddf5a4bdc"
"reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/a491d65139e2411c75704e871dd02bdddf5a4bdc",
"reference": "a491d65139e2411c75704e871dd02bdddf5a4bdc",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/969b211f9a51aa1f6c01d1d2aef56d3bd91598e5",
"reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5",
"shasum": ""
},
"require": {
"php": "^7.1"
"php": "^7.1 || ^8.0"
},
"replace": {
"myclabs/deep-copy": "self.version"
@ -1982,7 +1982,7 @@
"object",
"object graph"
],
"time": "2020-03-12T21:49:07+00:00"
"time": "2020-06-29T13:22:24+00:00"
},
{
"name": "phar-io/manifest",
@ -2141,24 +2141,23 @@
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
"reference": "790426f28bfcbfc1a6f1d59ee8c986edfa45395c"
"reference": "664187301bfbc87e686df212094e6817805c3ab8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/790426f28bfcbfc1a6f1d59ee8c986edfa45395c",
"reference": "790426f28bfcbfc1a6f1d59ee8c986edfa45395c",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/664187301bfbc87e686df212094e6817805c3ab8",
"reference": "664187301bfbc87e686df212094e6817805c3ab8",
"shasum": ""
},
"require": {
"ext-filter": "^7.1",
"php": "^7.2",
"ext-filter": "*",
"php": "^7.2 || ^8.0",
"phpdocumentor/reflection-common": "^2.0",
"phpdocumentor/type-resolver": "^1.0",
"webmozart/assert": "^1"
},
"require-dev": {
"doctrine/instantiator": "^1",
"mockery/mockery": "^1"
"mockery/mockery": "1.3.*"
},
"type": "library",
"extra": {
@ -2186,7 +2185,7 @@
}
],
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
"time": "2020-06-19T18:58:43+00:00"
"time": "2020-06-27T17:33:53+00:00"
},
{
"name": "phpdocumentor/type-resolver",

View file

@ -2,7 +2,7 @@ version: '3'
services:
traefik:
image: traefik:v2.1.4
image: traefik:2.2
container_name: appwrite_traefik
command:
- --log.level=DEBUG
@ -51,7 +51,7 @@ services:
- ./phpunit.xml:/usr/share/nginx/html/phpunit.xml
- ./tests:/usr/share/nginx/html/tests
- ./app:/usr/share/nginx/html/app
# - ./vendor:/usr/share/nginx/html/vendor
# - ./vendor:/usr/share/nginx/html/vendor
- ./docs:/usr/share/nginx/html/docs
- ./public:/usr/share/nginx/html/public
- ./src:/usr/share/nginx/html/src
@ -134,7 +134,7 @@ services:
- appwrite-redis:/data:rw
clamav:
image: appwrite/clamav:1.0.9
image: appwrite/clamav:1.0.12
container_name: appwrite_clamav
restart: unless-stopped
networks:

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -20,26 +20,26 @@
pre.className = "line-numbers";
code.className = "prism language-" + lang;
copy.className = "icon-docs copy";
copy.textContent = "Click Here to Copy";
copy.title = "Copy to Clipboard";
copy.addEventListener("click", function() {
element.disabled = false;
window.getSelection().removeAllRanges();
element.focus();
element.select();
let range = document.createRange();
document.execCommand("Copy");
range.selectNode(code);
if (document.selection) {
document.selection.empty();
} else if (window.getSelection) {
window.getSelection().removeAllRanges();
window.getSelection().addRange(range);
try {
document.execCommand("copy");
alerts.add({ text: "Copied to clipboard", class: "" }, 3000);
} catch (err) {
alerts.add({ text: "Failed to copy text ", class: "error" }, 3000);
}
element.disabled = true;
alerts.add({ text: "Copied to clipboard", class: "" }, 3000);
window.getSelection().removeAllRanges();
});
let check = function() {

View file

@ -606,7 +606,7 @@
.community {
a {
padding: 5px 10px;
padding: 0 10px;
display: inline-block;
}
}

View file

@ -138,7 +138,7 @@ abstract class OAuth2
\curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
\curl_setopt($ch, CURLOPT_HEADER, 0);
\curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
\curl_setopt($ch, CURLOPT_USERAGENT, '');
\curl_setopt($ch, CURLOPT_USERAGENT, 'Appwrite OAuth2');
if (!empty($payload)) {
\curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);

View file

@ -0,0 +1,152 @@
<?php
namespace Appwrite\Auth\OAuth2;
use Appwrite\Auth\OAuth2;
// Reference Material
// https://developer.box.com/reference/
class Box extends OAuth2
{
private $endpoint = 'https://account.box.com/api/oauth2/';
private $resourceEndpoint = 'https://api.box.com/2.0/';
/**
* @var array
*/
protected $user = [];
protected $scopes = [
'manage_app_users',
];
/**
* @return string
*/
public function getName(): string
{
return 'box';
}
/**
* @return string
*/
public function getLoginURL(): string
{
$url = $this->endpoint . 'authorize?'.
\http_build_query([
'response_type' => 'code',
'client_id' => $this->appID,
'scope' => \implode(',', $this->getScopes()),
'redirect_uri' => $this->callback,
'state' => \json_encode($this->state),
]);
return $url;
}
/**
* @param string $code
*
* @return string
*/
public function getAccessToken(string $code): string
{
$header = "Content-Type: application/x-www-form-urlencoded";
$accessToken = $this->request(
'POST',
$this->endpoint . 'token',
[$header],
\http_build_query([
"client_id" => $this->appID,
"client_secret" => $this->appSecret,
"code" => $code,
"grant_type" => "authorization_code",
"scope" => \implode(',', $this->getScopes()),
"redirect_uri" => $this->callback
])
);
$accessToken = \json_decode($accessToken, true);
if (array_key_exists('access_token', $accessToken)) {
return $accessToken['access_token'];
}
return '';
}
/**
* @param string $accessToken
*
* @return string
*/
public function getUserID(string $accessToken): string
{
$user = $this->getUser($accessToken);
if (isset($user['id'])) {
return $user['id'];
}
return '';
}
/**
* @param string $accessToken
*
* @return string
*/
public function getUserEmail(string $accessToken): string
{
$user = $this->getUser($accessToken);
if (isset($user['login'])) {
return $user['login'];
}
return '';
}
/**
* @param string $accessToken
*
* @return string
*/
public function getUserName(string $accessToken): string
{
$user = $this->getUser($accessToken);
if (isset($user['name'])) {
return $user['name'];
}
return '';
}
/**
* @param string $accessToken
*
* @return array
*/
protected function getUser(string $accessToken): array
{
$header = [
'Authorization: Bearer '.\urlencode($accessToken),
];
if (empty($this->user)) {
$user = $this->request(
'GET',
$this->resourceEndpoint . 'me',
$header
);
$this->user = \json_decode($user, true);
}
return $this->user;
}
}

View file

@ -15,7 +15,7 @@ class Github extends OAuth2
* @var array
*/
protected $scopes = [
'user:email'
'user:email',
];
/**
@ -125,7 +125,7 @@ class Github extends OAuth2
* @return array
*/
protected function getUser(string $accessToken)
{
{
if (empty($this->user)) {
$this->user = \json_decode($this->request('GET', 'https://api.github.com/user', ['Authorization: token '.\urlencode($accessToken)]), true);
}

View file

@ -22,7 +22,7 @@ class Paypal extends OAuth2
'live' => 'https://api.paypal.com/v1/',
];
private $environment = 'live';
protected $environment = 'live';
/**
* @var array

View file

@ -0,0 +1,19 @@
<?php
namespace Appwrite\Auth\OAuth2;
use Appwrite\Auth\OAuth2\Paypal;
class PaypalSandbox extends Paypal
{
protected environment = 'sandbox';
/**
* @return string
*/
public function getName(): string
{
return 'paypalSandbox';
}
}

View file

@ -151,8 +151,6 @@ class Database
'orderField' => '$id',
'orderType' => 'ASC',
'orderCast' => 'int',
'first' => false,
'last' => false,
'filters' => [],
], $options);
@ -162,17 +160,31 @@ class Database
$node = new Document($node);
}
if ($options['first']) {
$results = \reset($results);
}
if ($options['last']) {
$results = \end($results);
}
return $results;
}
/**
* @param array $options
*
* @return Document
*/
public function getCollectionFirst(array $options)
{
$results = $this->getCollection($options);
return \reset($results);
}
/**
* @param array $options
*
* @return Document
*/
public function getCollectionLast(array $options)
{
$results = $this->getCollection($options);
return \end($results);
}
/**
* @param int $id
* @param bool $mock is mocked data allowed?

View file

@ -317,41 +317,6 @@ trait DatabaseBase
return [];
}
/**
* @depends testCreateDocument
*/
public function testListDocumentsFirstAndLast(array $data):array
{
$documents = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/documents', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'limit' => 1,
'orderField' => 'releaseYear',
'orderType' => 'ASC',
'orderCast' => 'int',
'first' => true,
]);
$this->assertEquals(1944, $documents['body']['releaseYear']);
$documents = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/documents', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'limit' => 2,
'offset' => 1,
'orderField' => 'releaseYear',
'orderType' => 'ASC',
'orderCast' => 'int',
'last' => true,
]);
$this->assertEquals(2019, $documents['body']['releaseYear']);
return [];
}
/**
* @depends testCreateDocument
*/

View file

@ -227,7 +227,7 @@ trait LocaleBase
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-locale' => $lang,
]);
foreach ($response['body'] as $i => $code) {
$this->assertArrayHasKey($i, $defaultCountries, $i . ' country should be removed from ' . $lang);
}