Compare commits

...
370 Commits
Author SHA1 Message Date
Torsten DittmannandGitHub e9dd71d075 Merge pull request #1479 from TorstenDittmann/release-0-9-4
prepare: release 0.9.4
2021-08-10 13:28:36 +02:00
Torsten Dittmann 7af9bdbe3a chore(changes): 0.9.4 changelog 2021-08-10 11:07:53 +02:00
Torsten Dittmann 0ad7d35bb0 chore(changes): 0.9.4 changelog 2021-08-10 11:03:28 +02:00
Damodar LohaniandTorsten Dittmann c52672bc9a hot fix api issue 2021-08-10 10:30:46 +02:00
Torsten Dittmann d8d1414962 prepare 0.9.4 version 2021-08-10 10:30:39 +02:00
Torsten DittmannandGitHub 8ce48c1f47 Merge pull request #1435 from TorstenDittmann/release-0-9-3
feat(release): prepare 0.9.3
2021-07-27 16:17:25 +02:00
Torsten Dittmann d3daa2be32 feat(release): prepare 0.9.3 2021-07-27 14:43:08 +02:00
Eldad A. FuxandGitHub 957588a60e Merge pull request #1434 from PineappleIOnic/fix-JWT-Abuse-Key-Fix
Fix Abuse Keys
2021-07-27 14:59:06 +03:00
Bradley Schofield 7974a6ba5e Update account.php 2021-07-27 12:21:26 +01:00
Bradley Schofield e0761e1737 Fix create email verification abuse-key 2021-07-27 12:15:59 +01:00
Bradley Schofield d729d54de0 Fix Create JWT abuse key 2021-07-27 12:07:39 +01:00
Eldad A. FuxandGitHub 7fb7f1073f Merge pull request #1418 from TorstenDittmann/feat-prepare-0-9-2
feat(0.9.2): release
2021-07-22 19:09:33 +03:00
Torsten DittmannandGitHub 5815caf01e chore(changelog): update changelog 2021-07-22 17:45:15 +02:00
Eldad A. FuxandGitHub 82d22d10fc Merge pull request #1419 from PineappleIOnic/fix-early-command-execution
FIX Commands executing before the tar has finished extracting
2021-07-22 18:33:11 +03:00
Eldad A. FuxandGitHub 060e50f644 Merge pull request #1421 from appwrite/fix-jwt-for-functions
Fixed JWT + Functions bug
2021-07-22 18:32:21 +03:00
Eldad Fux d0e4e5cb29 Fixed bug 2021-07-22 17:49:52 +03:00
Bradley Schofield 70d4c4d7be Update functions.php 2021-07-22 11:46:05 +01:00
Bradley Schofield ca3d677596 Make untarring the code file a blocking task 2021-07-22 11:08:08 +01:00
Torsten Dittmann d235ed7190 chore(changelog): add 0.9.2 2021-07-22 11:04:17 +02:00
Torsten Dittmann 4e1bc7aa1d feat(0.9.2): release 2021-07-22 11:02:07 +02:00
Eldad A. FuxandGitHub f388c44e20 Merge pull request #1408 from appwrite/fix-jwt-validate-attribute
fix(jwt): correct session validation
2021-07-19 21:23:04 +03:00
Torsten DittmannandGitHub c2f1389a56 fix(jwt): correct session validation 2021-07-19 17:09:39 +02:00
Eldad A. FuxandGitHub 14cd81e4a8 Merge pull request #1404 from lohanidamodar/doc-create-membership
update create membership doc
2021-07-19 13:19:12 +03:00
Damodar Lohani cf3ffcdf32 update create membership doc 2021-07-18 16:19:50 +05:45
Eldad A. FuxandGitHub 564324ff1c Merge pull request #1398 from TorstenDittmann/fix-install-shell-args
fix(install): escape shell args
2021-07-16 06:32:11 +03:00
Torsten Dittmann 6e69b0a82b fix(install): escape shell args 2021-07-15 18:12:18 +02:00
Eldad A. FuxandGitHub 3fbdf88080 Merge pull request #1378 from appwrite/feat-dev-debugger
feat-dev-debugger
2021-07-13 10:51:36 +03:00
Torsten DittmannandGitHub 3d22d30868 Merge pull request #1388 from appwrite/feat-changelog-0.9.1
update changelog for 0.9.1
2021-07-12 20:14:04 +02:00
Torsten DittmannandGitHub 582f4e91f6 Update CHANGES.md 2021-07-12 20:03:29 +02:00
Torsten DittmannandGitHub 0c1c254019 Merge pull request #1387 from TorstenDittmann/feat-release-0.9.1
feat(release): 0.9.1
2021-07-12 19:45:01 +02:00
Torsten DittmannandGitHub e9a37e9a53 Merge pull request #1385 from TorstenDittmann/fix-broken-pdo-connection
fix(http): reset pdo connection if broken
2021-07-12 18:39:57 +02:00
Torsten Dittmann 71941d8712 feat(release): 0.9.1 2021-07-12 18:21:12 +02:00
Torsten Dittmann cff517a2ab adapt to review 2021-07-12 18:15:21 +02:00
Eldad A. FuxandGitHub b2308e48e3 Merge pull request #1384 from TorstenDittmann/fix-app-resource
fix(app): remove app resource and replace with utopia
2021-07-12 18:42:43 +03:00
Torsten Dittmann 76af58c646 fix(pdo): throw on general to parent 2021-07-12 17:27:26 +02:00
Torsten Dittmann df24011d8b fix(http): reset pdo connection if broken 2021-07-12 12:04:00 +02:00
Torsten Dittmann 18d4a0def0 fix(app): remove app resource and replace with utopia 2021-07-12 11:51:58 +02:00
Damodar Lohani 9814ca2fa9 update with DEBUG build args 2021-07-11 18:10:39 +05:45
Eldad A. FuxandGitHub f713c35170 Merge pull request #1375 from Meldiron/feat-fix-log
Added " to wrap environment name in a log
2021-07-11 15:24:36 +03:00
Damodar Lohani 74b24dfe69 properly setup debugger for everyone and contribution guide 2021-07-11 17:20:03 +05:45
Damodar Lohani 5073c264b7 modified entrypoint to support debugger 2021-07-11 15:49:31 +05:45
Matej Baco 24f85cdc78 Added " to wrap environment name 2021-07-10 20:07:03 +02:00
Damodar Lohani e8754111b9 install and enable yasd if testing is true 2021-07-10 21:06:46 +05:45
Eldad A. FuxandGitHub c7978bddfa Update README.md 2021-07-10 07:33:32 +03:00
Eldad A. FuxandGitHub bb95ec536b Update README.md 2021-07-09 07:44:45 +03:00
Eldad A. FuxandGitHub ce9ee59156 Update README.md 2021-07-09 07:39:58 +03:00
Eldad A. FuxandGitHub 53a24217dc Update CONTRIBUTING.md 2021-07-08 17:50:02 +03:00
Eldad A. FuxandGitHub cd6aa89bcc Merge pull request #1370 from appwrite/feat-update-maven-links
feat(platforms): update maven links
2021-07-07 17:48:51 +03:00
Christy Jacob ce8a1dc8c2 feat(platforms): update maven links 2021-07-07 20:17:24 +05:30
Christy JacobandGitHub 41e181916c Merge pull request #1364 from appwrite/feat-update-readme
feat(docs): update version in readme
2021-07-07 19:55:19 +05:30
Eldad A. FuxandGitHub 426dad9767 Merge pull request #1367 from appwrite/feat-kotlin-java-docs
Fixed kotlin sdk java docs
2021-07-07 15:22:03 +03:00
Eldad A. FuxandGitHub ecd1026b9b Merge pull request #1368 from appwrite/fix-filtertypes-without-rules
fix(database): default value for empty rules
2021-07-07 15:12:43 +03:00
Torsten DittmannandGitHub f158980963 fix(database): default value for empty rules 2021-07-07 13:46:44 +02:00
Jake Barnby 190d9607b0 Fixed kotlin sdk java docs 2021-07-07 23:12:01 +12:00
Torsten DittmannandGitHub 7a828cacc3 Merge pull request #1366 from PineappleIOnic/fix-sdk-getting-started-mistype
Fix Mistype in SDK Getting Started files
2021-07-07 12:31:17 +02:00
Bradley Schofield 8f71b9618c Fix Mistype 2021-07-07 11:25:49 +01:00
Christy Jacob 46b109b25a feat(docs): update version in readme 2021-07-07 15:04:41 +05:30
Christy JacobandGitHub 0752aa2d3b Merge pull request #1362 from appwrite/0.9.x
Appwrite 0.9 🚀
2021-07-07 15:02:02 +05:30
Christy JacobandGitHub cbee8748bd Merge pull request #1363 from appwrite/feat-add-changelog
feat(sdks): added flutter and dart changelog
2021-07-07 15:01:42 +05:30
dc4a25d663 Apply suggestions from code review
Co-authored-by: Jake Barnby <jakeb994@gmail.com>
2021-07-07 14:58:29 +05:30
Christy Jacob 8892421b68 feat(sdks): added flutter and dart changelog 2021-07-07 14:47:35 +05:30
Eldad Fux bac529a270 Increased cache buster 2021-07-06 21:26:25 +03:00
Eldad Fux a42597c848 Tiny change for sdk exmaple dir path 2021-07-06 21:20:23 +03:00
Eldad A. FuxandGitHub bafea4e9cc Merge pull request #1360 from appwrite/feat-generate-java-docs
feat(sdks): generate java docs
2021-07-06 21:16:22 +03:00
Eldad Fux febd244df3 Tiny change for sdk exmaple dir path 2021-07-06 20:38:06 +03:00
Christy Jacob 822a52522d feat(sdks): generate java docs 2021-07-06 23:07:40 +05:30
Eldad A. FuxandGitHub 2286bd2fb3 Merge pull request #1357 from appwrite/feat-kotlin-java-docs
Feat kotlin java docs
2021-07-06 20:10:33 +03:00
Eldad A. FuxandGitHub ccf3f41eb6 Update composer.json 2021-07-06 19:32:53 +03:00
Eldad A. FuxandGitHub 1186c6a36f Merge pull request #1298 from PineappleIOnic/feat-1297-add-expire-date-to-urls
Feat Add Expire Parameter to Email Verification and Password Reset URL's
2021-07-06 19:19:08 +03:00
Eldad A. FuxandGitHub f48e59d6dc Merge pull request #1356 from appwrite/TorstenDittmann-patch-1
fix(changelog): 0.9.x
2021-07-06 19:18:39 +03:00
Bradley Schofield e7b0dd9c4a Fix Tests 2021-07-06 15:39:45 +01:00
Bradley Schofield 4e2b05b87c Update account.php 2021-07-06 13:18:55 +01:00
Jake Barnby defd553bd9 Add java + kotlin doc sources for android + kotlin SDK's 2021-07-07 00:06:14 +12:00
Jake Barnby 5149a83159 Allow docs per language per SDK 2021-07-07 00:05:45 +12:00
Torsten DittmannandGitHub cc614cf38b update changelog 2021-07-06 13:14:51 +02:00
Eldad A. FuxandGitHub 0d4c5ab01e Merge pull request #1349 from TorstenDittmann/fix-database-int-casting
fix(database): properly cast to int
2021-07-06 13:43:46 +03:00
Eldad A. FuxandGitHub 299cb6f720 Merge pull request #1354 from appwrite/feat-flutter-readme-update
desktop platforms support on readme
2021-07-06 13:23:49 +03:00
da12d426cb Apply suggestions from code review
Co-authored-by: Eldad A. Fux <eldad.fux@gmail.com>
2021-07-06 16:08:18 +05:45
Damodar Lohani 9f003542bd update and re-arrange 2021-07-06 14:59:05 +05:45
Bradley Schofield 1a8ace0fb0 Update account.php 2021-07-06 09:14:12 +01:00
Damodar Lohani 2f28bc112f link to build.gradle instead of app id 2021-07-06 13:38:20 +05:45
Damodar Lohani 1629d8d19a links to playground 2021-07-06 13:35:47 +05:45
Damodar Lohani 0acaa76db7 desktop platforms support on readme 2021-07-06 13:26:03 +05:45
Torsten Dittmann 04f529d7db cast in php and skip quoting 2021-07-06 09:01:12 +02:00
Eldad Fux bf9f2455b4 Updated kotlin colors 2021-07-06 09:18:15 +03:00
Eldad Fux a57bd74a47 Updated android colors 2021-07-06 09:15:28 +03:00
Torsten Dittmann e5c65cce1a remove debug logs 2021-07-05 11:36:40 +02:00
Torsten Dittmann d9986cb205 fix(database): properly cast to int 2021-07-05 11:33:47 +02:00
Eldad A. FuxandGitHub 756922a747 Merge pull request #1347 from appwrite/feat-changelog-0.9
fix(changelog): 0.9
2021-07-05 11:44:08 +03:00
Eldad A. FuxandGitHub 3480fefb89 Merge pull request #1348 from TorstenDittmann/feat-db-version-reference
feat(projects): add version number
2021-07-05 11:43:37 +03:00
Eldad A. FuxandGitHub ae8583f3a2 Merge pull request #1322 from appwrite/fix-functions-worker
Fix functions worker
2021-07-05 11:10:35 +03:00
Torsten Dittmann 6c8e1a3190 feat(projects): add version number 2021-07-05 09:12:59 +02:00
Torsten DittmannandGitHub 506997483c Update CHANGES.md 2021-07-05 08:51:56 +02:00
Eldad A. FuxandGitHub 23f8c9a451 Merge pull request #1346 from appwrite/feat-update-kotlin-readme
Feat update kotlin readme
2021-07-05 09:28:07 +03:00
Christy Jacob 3251d29303 feat: added kotlin readme warning 2021-07-05 11:33:06 +05:30
Eldad Fux 92f0cc3cb7 Merge branch 'master' of github.com:appwrite/appwrite 2021-07-05 08:55:13 +03:00
Eldad Fux 999a6b664f Updated logo 2021-07-05 08:55:07 +03:00
Eldad A. FuxandGitHub 71bf43a355 Merge pull request #1343 from lohanidamodar/feat-upgrade-runtimes
feat-upgrade-runtimes
2021-07-04 18:40:46 +03:00
Damodar Lohani 02c5eba4e4 Merge branch '0.9.x' into feat-upgrade-runtimes 2021-07-04 11:11:36 +05:45
Damodar Lohani 48272e8e50 remove denot and .net 2021-07-04 11:09:56 +05:45
Eldad Fux a0645641bc Fixed missing links 2021-07-03 22:16:41 +03:00
Eldad Fux c8054bf209 Updated change log 2021-07-03 15:11:37 +03:00
Eldad Fux 57bc8c75e0 Merge branch 'master' of github.com:appwrite/appwrite into 0.9.x 2021-07-03 09:21:07 +03:00
Eldad A. FuxandGitHub f013d07df3 Merge pull request #1301 from PineappleIOnic/feat-fix-unique-keys-not-updating
Fix Unique Keys not being updated when changing a user's email address
2021-07-03 09:18:39 +03:00
Eldad A. FuxandGitHub 737ba69da0 Merge pull request #1342 from TorstenDittmann/feat-improved-migration
feat(migration): add version chooser
2021-07-03 09:00:35 +03:00
Eldad A. FuxandGitHub 56a272561c Merge pull request #1345 from appwrite/feat-update-specs
feat: update specs and regenerate docs
2021-07-03 08:58:22 +03:00
Christy Jacob 6e346e5384 feat: remove source directory deletion 2021-07-02 17:59:23 +05:30
Eldad A. FuxandGitHub 85e84253f0 Merge pull request #1344 from lohanidamodar/fix-gravity-cache
fix-gravity-cache
2021-07-02 15:19:09 +03:00
Christy Jacob 0cdd1daf0b feat: added kotlin getting started 2021-07-02 17:47:35 +05:30
Christy Jacob d543a5fbe9 feat: correct spelling mistake 2021-07-02 17:39:19 +05:30
Christy Jacob e8870dcb3e feat: update android versions 2021-07-02 17:20:54 +05:30
Christy Jacob 766f19d2a4 feat: update specs and regenerate docs 2021-07-02 17:17:02 +05:30
Torsten Dittmann cec23ecd7e remove leftover imports 2021-07-02 13:32:57 +02:00
Damodar Lohani d37afb58c4 adding java 16.0 as default runtime 2021-07-02 16:40:21 +05:45
Damodar Lohani 949b2a21c3 add gravity to cache key 2021-07-02 16:31:46 +05:45
Damodar Lohani 743d73dca0 make newer node runtime default 2021-07-02 16:26:53 +05:45
Bradley SchofieldandGitHub 1c0454daa9 Merge branch '0.9.x' into feat-1297-add-expire-date-to-urls 2021-07-02 11:40:58 +01:00
Damodar Lohani 5583d946e7 runtime upgrade 2021-07-02 16:25:48 +05:45
Bradley Schofield da9860c7c4 Revert "Merge branch 'master' into feat-1297-add-expire-date-to-urls"
This reverts commit 9472867c66, reversing
changes made to 7e8d76b66d.
2021-07-02 11:39:41 +01:00
Bradley Schofield 9472867c66 Merge branch 'master' into feat-1297-add-expire-date-to-urls 2021-07-02 11:37:29 +01:00
Torsten Dittmann 8966d3d673 add tests 2021-07-02 11:33:10 +02:00
Torsten Dittmann b4dd30dfba fix whitespace 2021-07-02 11:10:46 +02:00
Torsten Dittmann 7a86109dd9 move versions list to migration class 2021-07-02 11:09:02 +02:00
Torsten Dittmann a6e331390a feat(migration): add version chooser 2021-07-02 11:03:01 +02:00
Eldad A. FuxandGitHub 8212bc89e6 Merge pull request #1341 from appwrite/feat-generate-docs
Feat generate docs
2021-07-01 20:41:25 +03:00
Christy Jacob 61d1807a26 feat: review comments 2021-07-01 23:09:47 +05:30
Christy Jacob cab47c78dc Merge branch '0.9.x' of github.com:appwrite/appwrite into feat-generate-docs 2021-07-01 22:30:12 +05:30
Eldad A. FuxandGitHub 149462383d Merge pull request #1340 from appwrite/feat-add-response-filters
feat: add V08 response filter and update web sdk
2021-07-01 19:59:21 +03:00
Christy Jacob f4b8bc1c84 feat: update docs for 0.9.x 2021-07-01 22:21:07 +05:30
Christy Jacob 2c9ce4aa52 feat: updated README and security file 2021-07-01 22:17:22 +05:30
Eldad A. FuxandGitHub 75ce42ea6e Merge pull request #1339 from TorstenDittmann/feat-migration-0.9
feat(migration): 0.9.x
2021-07-01 17:56:09 +03:00
Christy Jacob 5581fb23a0 Merge branch '0.9.x' of github.com:appwrite/appwrite into feat-add-response-filters 2021-07-01 19:41:33 +05:30
Eldad A. FuxandGitHub 92707e92e5 Merge pull request #1337 from appwrite/feat-add-kotlin-platform
Feat add kotlin platform
2021-07-01 17:09:15 +03:00
Christy Jacob d820a2f9f2 feat: updated sdk generator tag 2021-07-01 19:34:25 +05:30
Christy Jacob 998c966614 feat: add missing line 2021-07-01 19:18:11 +05:30
Christy Jacob fa5ac4d3dc feat: add V08 response filter and update web sdk 2021-07-01 19:06:04 +05:30
Torsten Dittmann 787059e88d feat(migration): 0.9.x 2021-07-01 15:35:54 +02:00
Christy Jacob aac3ca45a0 feat: update version number 2021-07-01 12:37:26 +05:30
Christy Jacob 4e3ca74570 Merge branch '0.9.x' of github.com:appwrite/appwrite into feat-add-kotlin-platform 2021-06-30 20:46:20 +05:30
Christy Jacob 31acdec0aa feat: added kotlin platform to SDK task 2021-06-30 20:46:07 +05:30
Eldad A. FuxandGitHub e413a4e4f0 Merge pull request #1333 from appwrite/fix-updated-execution-model-description
Updated description on Execution Model
2021-06-30 17:03:22 +03:00
Eldad A. FuxandGitHub acade77bdc Merge pull request #1335 from TorstenDittmann/fix-npm-package-lock-june-2021
deps(npm): fix lock files
2021-06-30 13:16:00 +03:00
Torsten Dittmann 0186d8c6f8 deps(npm): fix lock files 2021-06-30 11:42:26 +02:00
Eldad Fux c8d8b1b867 Fixed typos 2021-06-30 09:29:39 +03:00
Eldad A. FuxandGitHub 46e1174778 Merge pull request #1332 from TorstenDittmann/deps-imagick-3.5.0
deps(php): imagick to 3.5.0
2021-06-30 09:24:26 +03:00
Eldad Fux afd7678781 Updated description 2021-06-30 09:23:43 +03:00
Torsten Dittmann 6767e14382 fix(php): libgomp dependency 2021-06-29 16:59:32 +02:00
Torsten Dittmann 77a5663bdb deps(php): imagick to 3.5.0 2021-06-29 15:47:38 +02:00
Eldad A. FuxandGitHub 5eeceeba20 Merge pull request #1330 from TorstenDittmann/feat-improved-connection-pools
feat(db): improved connection pools
2021-06-29 11:05:59 +03:00
Eldad A. FuxandGitHub 71c79804e6 Merge pull request #1323 from lohanidamodar/doc-account-oauth2-session
Update OAuth2 session doc
2021-06-29 10:33:06 +03:00
Eldad A. FuxandGitHub 329d86f041 Merge pull request #1331 from appwrite/fix-mock-endpoint-validator
feat: revert integer validator to numeric
2021-06-28 18:51:25 +03:00
Christy Jacob ebc08be20c feat: revert integer validator to numeric 2021-06-28 20:54:37 +05:30
Torsten Dittmann dd47f195a0 deps(composer): updated abuse library to 0.5.0 2021-06-28 12:20:22 +02:00
Torsten Dittmann 49fa26b18c fix model for connections 2021-06-28 09:56:03 +02:00
Torsten Dittmann 91250ea52b fix(users): db connection 2021-06-28 09:55:56 +02:00
64b2fc8056 Update docs/references/account/create-session-oauth2.md
Co-authored-by: Eldad A. Fux <eldad.fux@gmail.com>
2021-06-28 13:18:44 +05:45
Torsten Dittmann 44ba052fcb feat(db): improved connection pools 2021-06-28 09:19:33 +02:00
Eldad Fux 862f6721e8 Merge branch 'master' of github.com:appwrite/appwrite into 0.9.x 2021-06-26 22:06:23 +03:00
Eldad A. FuxandGitHub f374d66464 Merge pull request #1319 from lohanidamodar/fix-gravity-param
Update image library and gravity param
2021-06-26 18:02:06 +03:00
Damodar Lohani 66a6c40433 update image library 2021-06-25 12:36:03 +05:45
598a187a28 Update docs/references/account/create-session-oauth2.md
Co-authored-by: Bradley Schofield <ionicisere@gmail.com>
2021-06-25 12:32:43 +05:45
Damodar Lohani 378be8363a using getGravityTypes method to get list of supported gravity 2021-06-24 12:15:52 +05:45
Damodar Lohani 5c3223d8fe update oAuth2 session doc 2021-06-24 11:52:08 +05:45
Christy Jacob fdd389a17a feat: remove var_dump() 2021-06-24 01:55:27 +05:30
Christy Jacob 31b5b985e3 Merge branch '0.9.x' of github.com:appwrite/appwrite into fix-functions-worker 2021-06-24 01:52:55 +05:30
Christy Jacob d5a7b58c48 feat: pass empty string instead of null in functions worker 2021-06-24 01:52:43 +05:30
Eldad A. FuxandGitHub 91b2a139a5 Merge pull request #1294 from PineappleIOnic/feat-get-session-by-id-endpoint
Add session by ID API Endpoint
2021-06-23 18:45:08 +03:00
Eldad A. FuxandGitHub d756f36f3d Merge pull request #1321 from appwrite/feat-new-console-sdk
feat: updated console sdk
2021-06-23 18:38:13 +03:00
Bradley Schofield 0b1b21a5b0 Update Tests 2021-06-23 16:06:52 +01:00
Bradley Schofield 84f88628f5 Implement Suggestions 2021-06-23 15:02:24 +01:00
Christy Jacob f74f653ac1 feat: remove example docs 2021-06-23 17:52:20 +05:30
Christy Jacob 09dd0ae1c9 feat: remove example docs 2021-06-23 17:50:08 +05:30
Christy Jacob 7c76234656 feat: remove runtimes env var 2021-06-23 17:48:30 +05:30
Christy Jacob 8359a4e797 feat: restore sdks.php 2021-06-23 17:47:55 +05:30
Christy Jacob fca3894115 feat: remove generated sdks 2021-06-23 17:47:33 +05:30
Christy Jacob 6711398ab2 feat: updated console sdk 2021-06-23 17:45:27 +05:30
Damodar Lohani 497d391412 update image library and gravity param 2021-06-23 13:59:35 +05:45
Eldad Fux 9e6e345a3f Updated changelog 2021-06-23 10:56:35 +03:00
Eldad A. FuxandGitHub 46b05afcf1 Merge pull request #1317 from appwrite/dependabot/composer/phpmailer/phpmailer-6.5.0
build(deps): bump phpmailer/phpmailer from 6.4.1 to 6.5.0
2021-06-23 10:55:16 +03:00
Eldad A. FuxandGitHub a2c4dac366 Merge pull request #1314 from PineappleIOnic/fix-runtime-parameter
Renamed `env` param on `/v1/functions` to `runtime`
2021-06-23 10:12:24 +03:00
Eldad Fux 29dfc4cf46 Merge branch '0.9.x' of github.com:appwrite/appwrite into 0.9.x 2021-06-23 09:01:52 +03:00
Eldad Fux 4822d3cc5c Updated runtime logos 2021-06-23 09:01:47 +03:00
Bradley Schofield aa1e713b75 Fix tests 2021-06-22 16:56:05 +01:00
dependabot[bot]andGitHub 607c64734d build(deps): bump phpmailer/phpmailer from 6.4.1 to 6.5.0
Bumps [phpmailer/phpmailer](https://github.com/PHPMailer/PHPMailer) from 6.4.1 to 6.5.0.
- [Release notes](https://github.com/PHPMailer/PHPMailer/releases)
- [Changelog](https://github.com/PHPMailer/PHPMailer/blob/master/changelog.md)
- [Commits](https://github.com/PHPMailer/PHPMailer/compare/v6.4.1...v6.5.0)

---
updated-dependencies:
- dependency-name: phpmailer/phpmailer
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-22 15:18:52 +00:00
Eldad A. FuxandGitHub 6773816909 Merge pull request #1310 from appwrite/fix-removed-duplicated-cli-command
Removed duplicated cli command
2021-06-22 14:51:34 +03:00
86afebd726 Update CHANGES.md
Co-authored-by: Eldad A. Fux <eldad.fux@gmail.com>
2021-06-22 11:18:36 +01:00
22bc391047 Update app/controllers/api/functions.php
Co-authored-by: Eldad A. Fux <eldad.fux@gmail.com>
2021-06-22 11:18:26 +01:00
Eldad A. FuxandGitHub 56f062fccc Merge pull request #1315 from lohanidamodar/feat-new-functions-runtime
feat-new-functions-runtime
2021-06-22 13:07:36 +03:00
Damodar Lohani 9598868c50 update php-runtime version 2021-06-22 14:38:20 +05:45
Eldad A. FuxandGitHub ecadb1bede Merge pull request #1308 from Meldiron/feat-functions-speedup
Execute functions up to 5 seconds faster
2021-06-21 18:45:10 +03:00
Bradley Schofield c92a820c6d Renamed env param on /v1/functions to runtime 2021-06-21 15:42:39 +01:00
Bradley Schofield 1cf66b5934 Update account.php 2021-06-21 09:13:18 +01:00
Eldad A. FuxandGitHub 080c26e359 Merge pull request #1302 from TorstenDittmann/docs-fix-anonymous-session
docs(acocunt): fix converting anon account
2021-06-20 16:36:38 +03:00
Eldad Fux 4a0b9e5e89 Removed duplicated cli command 2021-06-20 16:16:01 +03:00
Eldad A. FuxandGitHub 32b890a553 Merge pull request #1135 from fishmandev/fix-NA--submit-a-pull-request-section-to-config-variables
Use the correct 'End Of Line' symbol for selected platform.
2021-06-20 16:00:30 +03:00
Eldad A. FuxandGitHub e529be5d55 Merge branch 'master' into fix-NA--submit-a-pull-request-section-to-config-variables 2021-06-20 16:00:19 +03:00
Matej Baco b7e9efb3d7 Updated interval of an usage worker 2021-06-20 00:01:01 +02:00
Matej Baco a1d4e35375 Updated INTERVALS of php-resque 2021-06-19 23:46:20 +02:00
Eldad Fux 0221ef2caa Added new lang colors 2021-06-19 16:30:30 +03:00
Torsten Dittmann af493324d0 docs(acocunt): fix converting anon account 2021-06-18 13:32:32 +02:00
Bradley Schofield 7e8d76b66d Add more tests 2021-06-18 10:28:54 +01:00
Eldad Fux 9ab76690b6 Merge branch '0.9.x' of github.com:appwrite/appwrite into 0.9.x 2021-06-18 07:13:48 +03:00
Eldad Fux 0a762f722e Updated chanelog 2021-06-18 07:13:43 +03:00
Bradley Schofield a56463e56e Fix Unique Keys not being update when changing a user's email address 2021-06-17 16:46:29 +01:00
Bradley SchofieldandGitHub 891a46d883 Merge branch '0.9.x' into feat-1297-add-expire-date-to-urls 2021-06-17 14:20:24 +01:00
Bradley Schofield 06cf8ab253 Add tests and changelogs 2021-06-17 14:17:35 +01:00
Bradley Schofield c5a08350a2 Add expire param to Account Recovery and Email Verification 2021-06-17 13:44:06 +01:00
Bradley SchofieldandGitHub 3f386d485e Merge branch '0.9.x' into feat-get-session-by-id-endpoint 2021-06-17 11:07:33 +01:00
Bradley Schofield aa41382b26 Update CHANGES.md 2021-06-17 11:05:57 +01:00
Bradley Schofield 88bb46ec95 Update account.php 2021-06-17 10:41:04 +01:00
Bradley Schofield 978668cbb9 Implement changes on other endpoints 2021-06-17 10:33:57 +01:00
Bradley Schofield 40e9fa9b36 Add Christy's Suggestions 2021-06-17 10:08:01 +01:00
Bradley Schofield fa918f9523 Add Eldad's Suggestions 2021-06-16 14:48:30 +01:00
Bradley Schofield 320cc97ad8 Replace getCollectionFirst with getDocument
Should be faster due to redis caching
2021-06-16 12:48:33 +01:00
Bradley Schofield cdb8fb8286 Implement suggestions 2021-06-16 11:48:12 +01:00
Bradley Schofield e3273bc49f Add Tests 2021-06-16 11:41:15 +01:00
Bradley Schofield d4c39b7b73 Add session by ID API Endpoint 2021-06-16 11:14:08 +01:00
Eldad A. FuxandGitHub 0d2a4f0cbf Merge pull request #1288 from appwrite/fix-functions-conflicts
Updated sort method before containers cleanup
2021-06-15 10:24:47 +03:00
Eldad A. FuxandGitHub b115672e0f Merge pull request #1137 from appwrite/feat-move-deletion-to-worker
feat(teams): move membership deletion task to deletes worker
2021-06-14 23:15:41 +03:00
Eldad Fux 579a24cf73 Updated sort method before cleanup 2021-06-14 22:18:43 +03:00
Christy Jacob 8322749c2c Merge branch 'master' of github.com:appwrite/appwrite into feat-move-deletion-to-worker 2021-06-14 20:56:40 +05:30
Eldad A. FuxandGitHub d469e3a7b6 Merge pull request #1278 from TorstenDittmann/feat-db-pools
feat(server): database connection pools
2021-06-14 17:22:15 +03:00
Torsten Dittmann fe2909b389 Revert "Revert "Merge branch 'master' of https://github.com/appwrite/appwrite into feat-db-pools""
This reverts commit c3f2f82bc1.
2021-06-14 13:55:55 +02:00
Torsten Dittmann 6eb8ce9170 revert changes 2021-06-14 13:46:38 +02:00
Eldad Fux a5cb8414f6 Merge branch 'master' of github.com:appwrite/appwrite into 0.9.x 2021-06-14 14:17:32 +03:00
Torsten Dittmann d3ae58a2ff Merge branch 'master' of https://github.com/appwrite/appwrite into feat-db-pools 2021-06-14 12:49:55 +02:00
Eldad A. FuxandGitHub 9346b5647b Merge pull request #1285 from appwrite/fix-tests-ignore-swagger-validation
fix(tests): skip swagger spec validation
2021-06-14 13:34:00 +03:00
Torsten DittmannandGitHub 95b6e166db fix(tests): skip swagger spec validation 2021-06-14 10:38:26 +02:00
Torsten Dittmann 2c06e15f23 Merge branch '0.9.x' of https://github.com/appwrite/appwrite into feat-db-pools 2021-06-14 09:10:55 +02:00
Eldad Fux a340c4d670 Merge branch 'master' of github.com:appwrite/appwrite into 0.9.x 2021-06-14 10:09:55 +03:00
Torsten Dittmann c3f2f82bc1 Revert "Merge branch 'master' of https://github.com/appwrite/appwrite into feat-db-pools"
This reverts commit eaee419fb1, reversing
changes made to 15e7297b5a.
2021-06-14 09:09:48 +02:00
Torsten Dittmann fc9a833b33 Merge branch '0.9.x' of https://github.com/appwrite/appwrite into feat-db-pools 2021-06-14 09:08:23 +02:00
Torsten Dittmann eaee419fb1 Merge branch 'master' of https://github.com/appwrite/appwrite into feat-db-pools 2021-06-14 09:08:14 +02:00
Torsten Dittmann 15e7297b5a remove unused dependencies 2021-06-14 09:07:52 +02:00
Christy Jacob a93496bc8c Merge branch '0.9.x' of github.com:appwrite/appwrite into feat-move-deletion-to-worker 2021-06-14 11:05:08 +05:30
Christy Jacob 86b1cc1678 feat: merge commit 2021-06-14 10:58:49 +05:30
Christy Jacob 412d7c8735 feat: removed log 2021-06-14 10:45:41 +05:30
Christy Jacob 09a90a5631 feat: fix deletes workker bug 2021-06-14 10:41:48 +05:30
Eldad Fux 785db645eb Added back missing icons 2021-06-12 14:16:52 +03:00
Eldad Fux 967afad696 Fixed extra space on modal window 2021-06-12 13:57:32 +03:00
Eldad A. FuxandGitHub aa1f73fb10 Merge pull request #1276 from TorstenDittmann/refactor-workers
refactor(workers): create abstract worker class
2021-06-12 12:54:52 +03:00
Torsten Dittmann 665d57106e feat(server): database connection pools 2021-06-11 18:09:46 +02:00
Torsten Dittmann d96635ec23 fix(worker): remove unnecessary imports 2021-06-11 16:39:44 +02:00
Torsten Dittmann 3f199e1232 refactor(workers): create abstract worker class 2021-06-11 16:20:18 +02:00
Eldad A. FuxandGitHub 4df8f8aaba Merge pull request #1260 from lohanidamodar/feat-image-crop-gravity
feat-image-crop-gravity
2021-06-11 16:51:25 +03:00
Damodar Lohani 4ea0d627f4 remove int conversion 2021-06-11 18:11:04 +05:45
Eldad A. FuxandGitHub c74a77422b Merge pull request #1272 from lohanidamodar/fix-remove-runtime-exception
fix warning
2021-06-11 14:20:37 +03:00
Eldad A. FuxandGitHub 51d4729737 Merge pull request #1273 from appwrite/feat-add-android-origin
Feat add android origin
2021-06-11 14:20:06 +03:00
Eldad Fux 35e236262c Merge branch '0.9.x' of github.com:appwrite/appwrite into feat-add-android-origin 2021-06-11 12:39:31 +03:00
Eldad Fux e42eab3671 Merge branch 'master' of github.com:appwrite/appwrite into 0.9.x 2021-06-11 12:28:24 +03:00
Christy Jacob f19f186864 Merge branch 'master' of github.com:appwrite/appwrite into feat-add-android-origin 2021-06-11 12:49:28 +05:30
Christy Jacob 9c77618578 feat: restored composer 2021-06-11 12:46:12 +05:30
Christy Jacob 402277da50 feat: removed docs 2021-06-11 12:45:40 +05:30
Christy Jacob 43d9c416a3 feat: added iOS platform to origin validator 2021-06-11 12:44:30 +05:30
Damodar Lohani 58a1b12c27 Merge branch 'master' into feat-image-crop-gravity 2021-06-11 12:20:55 +05:45
Damodar Lohani 282edd5049 Merge branch 'master' into fix-remove-runtime-exception 2021-06-11 12:20:12 +05:45
Eldad A. FuxandGitHub a433181e17 Merge pull request #1274 from TorstenDittmann/fix-imagick-version
fix(dockerfile): imagick version specific commit
2021-06-11 01:14:34 +03:00
Christy Jacob c981ff39c0 feat: added error models to response model 2021-06-10 17:04:14 +05:30
Torsten Dittmann d471a5e1bd fix(dockerfile): imagick version specific commit 2021-06-10 13:14:22 +02:00
Christy Jacob c3d4897d36 feat: changed terminology 2021-06-10 15:13:32 +05:30
Christy Jacob da1ecfaffe feat: added android origin check 2021-06-10 15:05:16 +05:30
Damodar Lohani 775fee6254 Merge branch 'master' into feat-image-crop-gravity 2021-06-10 15:16:31 +05:45
Damodar Lohani 1f1b68f0ca update dependency 2021-06-10 15:16:03 +05:45
Damodar Lohani f26b8f05f5 use exception instead 2021-06-10 14:11:16 +05:45
Damodar Lohani 4563faedcb fix warning 2021-06-10 12:05:46 +05:45
Eldad A. FuxandGitHub d825dd804e Merge pull request #1270 from appwrite/feat-add-android-platform-config
Update Getting started Guides
2021-06-09 18:34:36 +03:00
Christy Jacob bdb4e98123 feat: added namespace 2021-06-09 21:00:56 +05:30
Christy Jacob 0492ccadd5 feat: update getting started guides 2021-06-09 20:56:08 +05:30
Eldad A. FuxandGitHub fdf5c2c248 Merge pull request #1269 from appwrite/feat-add-android-platform-config
feat: add android platform config
2021-06-09 16:33:59 +03:00
Christy Jacob 3425fe351a feat: fixed some issues with the guide 2021-06-09 18:59:31 +05:30
Christy Jacob 0cbbcd3829 feat: update package link 2021-06-09 18:31:35 +05:30
Christy Jacob 25888151fb feat: add android platform config 2021-06-09 18:15:42 +05:30
Eldad A. FuxandGitHub 11edc63a71 Merge pull request #1267 from appwrite/feat-android-support
Feat android support
2021-06-09 14:36:12 +03:00
Eldad Fux 32e6f058d4 Removed reference for old compose file 2021-06-09 14:01:56 +03:00
Damodar Lohani e1133b665d fix whitelist issue 2021-06-09 14:22:20 +05:45
Damodar Lohani 3c29e0da95 update image library 2021-06-09 13:06:49 +05:45
Damodar Lohani 4fb54ac87b fix crop gravity param type 2021-06-09 12:26:39 +05:45
Damodar Lohani 4b9be0f741 composer update 2021-06-08 12:25:09 +05:45
Damodar Lohani a077ec0f55 Merge branch 'master' into feat-image-crop-gravity 2021-06-08 12:24:43 +05:45
Eldad A. FuxandGitHub a8728a2f0d Merge pull request #1234 from TorstenDittmann/feat-specs-unused-models
feat(specs): include only used models param
2021-06-08 00:01:14 +03:00
Eldad A. FuxandGitHub 2238097b3a Merge pull request #1202 from TorstenDittmann/feat-influx-env-variables
feat(system): add env to configure telegraf
2021-06-08 00:00:43 +03:00
Eldad A. FuxandGitHub 0039ec4300 Merge pull request #1241 from lohanidamodar/fix-project-data-type
fix type
2021-06-07 23:58:27 +03:00
Eldad A. FuxandGitHub 8ee8de978a Merge pull request #1243 from appwrite/fix-1240-ignore-email-case
fix: ignore email case when creating account
2021-06-07 23:57:30 +03:00
Eldad A. FuxandGitHub a4d460faf6 Merge pull request #1256 from TorstenDittmann/feat-dbip-2021-06
feat(dbip): update to 2021-06
2021-06-07 23:55:25 +03:00
Eldad A. FuxandGitHub 7c00f89103 Merge pull request #1258 from TorstenDittmann/feat-sdk-generator-0.10.11
deps(composer): sdk-generator@0.10.11
2021-06-07 18:47:07 +03:00
Torsten Dittmann e1ea4c516d deps(scomposer): sdk-generator@0.10.11 2021-06-07 16:43:06 +02:00
Torsten Dittmann d1be341800 remove leftover 2021-06-07 12:18:11 +02:00
Torsten Dittmann c9b8d62834 remove leftover 2021-06-07 12:13:10 +02:00
Torsten Dittmann ffd53053a7 feat(dbip): update to 2021-06 2021-06-07 12:09:31 +02:00
Damodar Lohani 5201e48815 adding image crop gravity support 2021-06-07 12:02:46 +05:45
Eldad Fux a953892cd3 Update docs 2021-06-06 20:54:50 +03:00
Eldad A. FuxandGitHub 7a0b0b6dd0 Merge pull request #1254 from appwrite/fix-escape-html-tags
Fix escape html tags
2021-06-05 15:21:43 +03:00
Eldad Fux 742ad18bbf Updated OG logo 2021-06-05 14:34:06 +03:00
Eldad Fux 5e5a40df63 Escaped vars 2021-06-05 14:30:32 +03:00
Eldad Fux d84d4dc0fd Updated cache buster 2021-06-05 14:30:24 +03:00
Eldad Fux 2378ec8521 Merge branch 'master' of github.com:appwrite/appwrite 2021-06-05 14:23:58 +03:00
Torsten DittmannandGitHub 114578f102 remove leftover 2021-06-04 10:23:29 +02:00
Eldad A. FuxandGitHub 94b46e3c06 Merge pull request #1242 from TorstenDittmann/release-sdks-june-2021
feat(sdks): update to sdk-generator@0.10.9
2021-06-04 08:50:24 +03:00
Eldad A. FuxandGitHub 816f76f4e7 Update README.md 2021-06-03 22:57:34 +03:00
Eldad A. FuxandGitHub 541ba1d288 Update README.md 2021-06-03 22:57:10 +03:00
Christy Jacob ef36e9ef49 feat: review comments 2021-06-04 00:35:11 +05:30
Torsten Dittmann 53e9c84bab chore(changelog): add telegraf env changes 2021-06-03 15:36:11 +02:00
Christy Jacob b954e148b5 feat: review comments 2021-06-03 19:01:00 +05:30
Christy Jacob 26c46a2278 fix: ignore email case when creating account 2021-06-03 18:33:51 +05:30
Torsten DittmannandGitHub 8825d95a4e Merge branch '0.9.x' into feat-influx-env-variables 2021-06-03 14:59:41 +02:00
Christy Jacob ec4d4d56a1 fix: ignore email case when creating account 2021-06-03 18:28:40 +05:30
Torsten Dittmann 3c03b5f997 fix(install): update to new telegraf version 2021-06-03 14:57:17 +02:00
Torsten Dittmann c71920e56f update appwrite/telegraf to 1.2.0 2021-06-03 14:31:58 +02:00
Torsten Dittmann 926d0e328d feat(sdks): new flutter and dart version 2021-06-03 14:25:51 +02:00
Torsten Dittmann 45c3bc9424 revert(spec): option to include all models 2021-06-03 11:58:59 +02:00
Torsten Dittmann c3a48fec71 feat(sdks): update to sdk-generator@0.10.9 2021-06-03 11:33:10 +02:00
Damodar Lohani 95730e74e8 fix type 2021-06-03 12:39:41 +05:45
Eldad A. FuxandGitHub 02e5d23669 Merge pull request #1093 from lohanidamodar/feat-more-platforms
feat-android-platform
2021-06-02 20:18:38 +03:00
Eldad A. FuxandGitHub 950936cc3a Merge branch 'feat-android-support' into feat-more-platforms 2021-06-02 20:18:14 +03:00
Eldad A. FuxandGitHub 81e52e8de3 Merge pull request #1233 from lohanidamodar/feat-android-sdk-readme
feat-android-sdk-readme
2021-06-02 20:16:36 +03:00
Eldad Fux 86b68352b1 Merge branch 'master' of github.com:appwrite/appwrite into 0.9.x 2021-06-02 20:11:36 +03:00
Eldad A. FuxandGitHub e3d444a0cd Merge pull request #1122 from lohanidamodar/feat-flutter-platforms
feat-flutter-desktop-platforms
2021-06-02 09:40:29 +03:00
Eldad A. FuxandGitHub 1bec151f89 Merge pull request #1217 from appwrite/fix-1190-team-membership
Fix 1190 team membership
2021-06-02 09:31:14 +03:00
Eldad A. FuxandGitHub 4e6f2a8f02 Merge pull request #1235 from TorstenDittmann/feat-mock-download
feat(mock): download endpoint
2021-06-02 06:06:50 +03:00
Torsten Dittmann bae59365b9 feat(mock): download endpoint 2021-06-01 19:24:08 +02:00
Eldad A. FuxandGitHub f5ac40e576 Merge pull request #1220 from appwrite/fix-user-empty-name
Fix user empty name
2021-06-01 18:17:01 +03:00
Torsten Dittmann c8f8650b78 Merge branch 'master' of https://github.com/appwrite/appwrite into feat-specs-unused-models 2021-06-01 14:17:11 +02:00
Torsten Dittmann 4771b6ca78 feat(specs): include unused models param 2021-06-01 14:13:44 +02:00
Damodar Lohani 104f5e5685 add platform and oauth details 2021-06-01 16:17:45 +05:45
Damodar Lohani 7dd342b664 correction 2021-06-01 16:13:19 +05:45
Damodar Lohani c2651d56af improvements 2021-06-01 16:11:51 +05:45
Damodar Lohani 75d3c39763 android changelog and getting started 2021-06-01 16:02:50 +05:45
Damodar Lohani 8f5ace8b0a Merge branch 'master' into feat-flutter-platforms 2021-06-01 11:46:00 +05:45
Eldad A. FuxandGitHub d33c6921b8 Merge pull request #1221 from appwrite/feat-upgrade-telegraf-version
Feat upgrade telegraf version
2021-05-31 14:35:59 +03:00
Eldad A. FuxandGitHub 02a8cc8362 Merge pull request #1223 from lohanidamodar/feat-update-verification
Update Email verification
2021-05-31 14:35:07 +03:00
Eldad A. FuxandGitHub 36793d0ed6 Merge pull request #1225 from appwrite/feat-update-mail-template
Feat update mail template
2021-05-31 14:34:40 +03:00
Damodar Lohani 0409dd5c32 added test for verification update 2021-05-31 11:35:52 +05:45
Damodar Lohani 20e4745786 fixed param name 2021-05-31 11:35:43 +05:45
Christy Jacob 404e1ace91 fix(teams): added unit test 2021-05-31 10:26:06 +05:30
Eldad Fux da3d4546ad Update mail style 2021-05-30 23:38:40 +03:00
Eldad Fux 38ded65db1 Fixed spanish encoding 2021-05-30 23:37:32 +03:00
Eldad Fux 46b8031782 Fixed button alignment on RTL langs 2021-05-30 23:37:16 +03:00
Eldad Fux 78ab52da2b Fixed hebrew translation 2021-05-30 23:36:47 +03:00
Damodar Lohani 5b173ce54b update icon 2021-05-30 17:20:17 +05:45
Damodar Lohani 641e777449 Merge branch 'master' into feat-flutter-platforms 2021-05-30 17:20:10 +05:45
Damodar Lohani 239fce8cc1 interchanging platforms 2021-05-30 17:14:14 +05:45
Damodar Lohani deeeba7477 reference 2021-05-30 12:50:54 +05:45
Damodar Lohani 3ef0b6e7cb endpoint to update user email verification 2021-05-30 12:48:51 +05:45
Eldad Fux 62a80fe50a Updated changelog 2021-05-29 18:04:29 +03:00
Eldad Fux b9cf475fa5 Upgraded telegraf version 2021-05-29 18:03:27 +03:00
Eldad Fux c8ec58720e Changed the placeholder to Unknown 2021-05-29 12:10:27 +03:00
Eldad Fux 6aa6ae0878 Updated changelog 2021-05-29 11:51:30 +03:00
Eldad Fux 668882391a Updated LS 2021-05-29 11:48:34 +03:00
Eldad Fux 5f551785b8 Fixed user empty name on console 2021-05-29 11:43:04 +03:00
Christy Jacob b7efefa40f fix(teams): added comment 2021-05-29 13:02:26 +05:30
Christy Jacob a6db680641 fix(teams): removed unused import 2021-05-29 02:29:15 +05:30
Christy Jacob a7a744afb1 fix(teams): removed var_dump 2021-05-29 02:28:38 +05:30
Christy Jacob 744d8b9b48 fix(teams): removed var_dump 2021-05-29 02:27:47 +05:30
Christy Jacob b0e74b6d7b fix(teams): incorrect membership count in teams 2021-05-29 02:25:22 +05:30
Christy Jacob 3b98feef11 Merge branch 'master' of https://github.com/appwrite/appwrite into fix-1190-team-membership 2021-05-29 01:52:04 +05:30
Christy Jacob 5a469ab362 fix(memberships): logic for decremmenting membership count 2021-05-29 01:51:56 +05:30
Torsten Dittmann 46c6531f73 feat(system): add env to configure telegraf 2021-05-27 15:13:40 +02:00
Christy Jacob cfd6aed48e Merge branch '0.8.x' of https://github.com/appwrite/appwrite into feat-move-deletion-to-worker 2021-05-14 01:01:46 +05:30
Christy Jacob c9075278e1 feat: some test code 2021-05-13 19:12:52 +05:30
Christy Jacob 08f606d29b feat: remove unused import 2021-05-11 23:31:00 +05:30
Christy Jacob 0bd542077f feat: uncomment 2021-05-11 23:30:04 +05:30
Christy Jacob 5e6cc855c9 feat: remove logs 2021-05-11 23:29:20 +05:30
Christy Jacob 6836e3c91d feat: move membership deletion to deletes worker 2021-05-11 23:25:38 +05:30
Dmitriy Fishman 0256c9f59a Use the correct 'End Of Line' symbol for selected platform. 2021-05-11 14:35:58 +03:00
Damodar Lohani d09dfc6bdd fix dialog tabs overflowing 2021-05-06 13:33:54 +05:45
Damodar Lohani 309f915070 flutter desktop platforms 2021-05-06 11:19:34 +05:45
Damodar Lohani 1f32979094 move android above coming soon platforms 2021-04-18 06:05:55 +05:45
Damodar Lohani 75d48974f5 fix incorrect name and icon 2021-04-16 14:41:25 +05:45
Damodar Lohani b7470da9d7 adding android platform 2021-04-16 13:15:35 +05:45
Damodar Lohani 5560281141 enabling android platform 2021-04-16 12:41:35 +05:45
1511 changed files with 31952 additions and 5471 deletions
+3 -1
View File
@@ -5,4 +5,6 @@
/.idea/
.DS_Store
.php_cs.cache
debug/
debug/
app/sdks
dev/yasd_init.php
+1 -1
View File
@@ -15,7 +15,7 @@ then
exit 1
fi
if test $(find "./app/db/DBIP/dbip-country-lite-2021-02.mmdb" -mmin +259200)
if test $(find "./app/db/DBIP/dbip-country-lite-2021-06.mmdb" -mmin +259200)
then
printf "${RED}GEO country DB has not been updated for more than 6 months. Go to https://db-ip.com/db/download/ip-to-country-lite to download a newer version${NC}\n"
fi
+74 -9
View File
@@ -1,23 +1,86 @@
# NOT PUBLISHED YET
# Version 0.9.4
## Features
## Security
- Added file created date to file info on the console
- Added file size to file info on the console
- Refactored Devices page in Console:
- Renamed *Devices* to *Sessions*
- Add Provider Icon to each Session
- Add Anonymous Account Placeholder
- Fixed security vulnerability that exposes project ID's from other admin users (#1453)
# Version 0.9.3
## Bugs
- Fixed bug when removing a project member on the Appwrite console (#1214)
- Fixed Abuse Limit keys for JWT and E-Mail confirmation (#1434)
# Version 0.9.2
## Bugs
- Fixed JWT session validation (#1408)
- Fixed passing valid JWT session to Cloud Functions (#1421)
- Fixed race condition when uploading and extracting bigger Cloud Functions (#1419)
# Version 0.9.1
## Bugs
- Fixed PDO Connection timeout (#1385)
- Removed unnecessary `app` resource and replace with `utopia` (#1384)
- Fixed missing quote in Functions Worker logs (#1375)
# Version 0.9.0
## Features
- Added support for Android
- Added a new Cloud Functions runtime for
- Java 16.0
- Java 11.0
- Node 16.0
- Dart 2.13
- Added a new gravity option when croping storage images using the file preview endpoint (#1260)
- Upgraded GEOIP DB file to Jun 2021 release (#1256)
- Added file created date to file info on the console (#1183)
- Added file size to file info on the console (#1183)
- Added internal support for connection pools for improved performance (#1278)
- Added new abstraction for workers executable files (#1276)
- Added a new API in the Users API to allow you to force update your user verification status (#1223)
- Using a fixed commit to avoid breaking changes for imagemagick extenstion (#1274)
- Updated the design of all the email templates (#1225)
- Refactored Devices page in Console: (#1167)
- Renamed *Devices* to *Sessions*
- Add Provider Icon to each Session
- Add Anonymous Account Placeholder
- Upgraded phpmailer version to 6.5.0 (#1317)
- Upgraded telegraf docker image version to v1.2.0
- Added new environment variables to the `telegraf` service: (#1202)
- _APP_INFLUXDB_HOST
- _APP_INFLUXDB_PORT
- Added `expires` parameter to Account Recovery and Email Validation URL's
- Added new endpoint to get a session based on it's ID (#1294)
- Added added a new version param to the migration script (#1342)
- Improved Queue Interval for all workers from 5 seconds to 1 (#1308 Thanks to @Meldiron)
## Breaking Changes (Read before upgrading!)
- Renamed `env` param on `/v1/functions` to `runtime` (#1314)
- Renamed `deleteUser` method in all SDKs to `delete` (#1216)
## Bugs
- Fixed bug causing runtimes conflict and hanging executions when max Functions containers limit passed (#1288)
- Fixed 404 error when removing a project member on the Appwrite console (#1214)
- Fixed Swoole buffer output size to allow downloading files bigger than allowed size (#1189)
- Fixed ClamAV status when anti virus is not running (#1188)
- Fixed deleteSession which was removing cookieFallback from the localstorage on any logout instead of current session (#1206)
- Fixed Nepal flag (#1173)
- Fixed a bug in the Twitch OAuth adapter (#1209)
- Fixed missing session object when OAuth session creation event is triggered (#1208)
- Fixed bug where we didn't ignore the email case, converted all emails to lowercase internally (#1243)
- Fixed a console bug where you can't click a user with no name, added a placehoder for anonyomous users (#1220)
- Fixed unique keys not being updated when changing a user's email address (#1301)
- Fixed a bug where decimal integers where wrongly used with database filters (#1349)
## Security
- Fixed potential XSS injection on the console
# Version 0.8.0
@@ -56,6 +119,8 @@
- Fixed incorrect audit worker event names (#1143)
- Increased limit of memberships fetched in `createTeamMembership` to 2000 (#1143)
- Fixed exception thrown when SSL certificate is already stored in the database (#1151)
- Fixed user delete button in the Appwrite console (#1216)
- Fixed missing placeholder for user name when empty (#1220)
## Breaking Changes (Read before upgrading!)
+28 -4
View File
@@ -123,6 +123,10 @@ Learn more at our [Technology Stack](## Technology Stack) section.
Appwrite's current structure is a combination of both [Monolithic](https://en.wikipedia.org/wiki/Monolithic_application) and [Microservice](https://en.wikipedia.org/wiki/Microservices) architectures, but our final goal, as we grow, is to be using only microservices.
---
![Appwrite](docs/specs/overview.drawio.svg)
---
### File Structure
```bash
@@ -174,10 +178,6 @@ Appwrite's current structure is a combination of both [Monolithic](https://en.wi
└── unit
```
---
![Appwrite](docs/specs/overview.drawio.svg)
---
### The Monolithic Part
Appwrite's main API container is designed as a monolithic app. This is a decision we made to allow us to develop the project faster while still being a very small team.
@@ -282,6 +282,30 @@ docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7
The Runtimes for all supported cloud functions (multicore builds) can be found at the [appwrite/php-runtimes](https://github.com/appwrite/php-runtimes) repository.
## Debug
Appwrite uses [yasd](https://github.com/swoole/yasd) debugger, which can be made available during build of Appwrite. You can connect to the debugger using VS Code [PHP Debug](https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug) extension or if you are in PHP Storm you don't need any plugin. Below are the settings required for remote debugger connection.
First, you need to create an init file. Duplicate **dev/yasd_init.php.stub** file and name it **dev/yasd_init.php** and there change the IP address to your development machine's IP. Without the proper IP address debugger wont connect. And you also need to set **DEBUG** build arg in **appwrite** service in **docker-compose.yml** file.
### VS Code Launch Configuration
```json
{
"name": "Listen for Xdebug",
"type": "php",
"request": "launch",
"port": 9005,
"pathMappings": {
"/usr/src/code": "${workspaceRoot}"
},
}
```
### PHPStorm Setup
In settings, go to **Languages & Frameworks** > **PHP** > **Debug**, there under **Xdebug** set the debug port to **9005** and enable **can accept external connections** checkbox.
## Tests
To run all tests manually, use the Appwrite Docker CLI from your terminal:
+30 -4
View File
@@ -14,9 +14,12 @@ RUN composer update --ignore-platform-reqs --optimize-autoloader \
FROM php:8.0-cli-alpine as step1
ARG DEBUG=false
ENV DEBUG=$DEBUG
ENV PHP_REDIS_VERSION=5.3.4 \
PHP_SWOOLE_VERSION=v4.6.6 \
PHP_IMAGICK_VERSION=master \
PHP_SWOOLE_VERSION=v4.6.7 \
PHP_IMAGICK_VERSION=3.5.0 \
PHP_YAML_VERSION=2.2.1 \
PHP_MAXMINDDB_VERSION=v1.10.1
@@ -53,7 +56,7 @@ RUN \
make && make install && \
cd .. && \
## Imagick Extension
git clone --depth 1 --branch $PHP_IMAGICK_VERSION https://github.com/Imagick/imagick && \
git clone --depth 1 --branch $PHP_IMAGICK_VERSION https://github.com/imagick/imagick && \
cd imagick && \
phpize && \
./configure && \
@@ -75,11 +78,25 @@ RUN \
make && make install && \
cd ../..
## Swoole Debugger setup
RUN if [ "$DEBUG" == "true" ]; then \
cd /tmp && \
apk add boost-dev && \
git clone --depth 1 https://github.com/swoole/yasd && \
cd yasd && \
phpize && \
./configure && \
make && make install && \
cd ..;\
fi
FROM php:8.0-cli-alpine as final
LABEL maintainer="team@appwrite.io"
ARG VERSION=dev
ARG DEBUG=false
ENV DEBUG=$DEBUG
ENV _APP_SERVER=swoole \
_APP_ENV=production \
@@ -150,18 +167,25 @@ RUN \
brotli-dev \
yaml-dev \
imagemagick \
imagemagick-dev \
libmaxminddb-dev \
certbot \
docker-cli \
docker-compose \
libgomp \
&& docker-php-ext-install sockets opcache pdo_mysql \
&& apk del .deps \
&& rm -rf /var/cache/apk/*
RUN \
if [ "$DEBUG" == "true" ]; then \
apk add boost boost-dev; \
fi
WORKDIR /usr/src/code
COPY --from=step0 /usr/local/src/vendor /usr/src/code/vendor
COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/swoole.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/swoole.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/yasd.so* /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/redis.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/imagick.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/yaml.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
@@ -216,7 +240,9 @@ RUN echo extension=redis.so >> /usr/local/etc/php/conf.d/redis.ini
RUN echo extension=imagick.so >> /usr/local/etc/php/conf.d/imagick.ini
RUN echo extension=yaml.so >> /usr/local/etc/php/conf.d/yaml.ini
RUN echo extension=maxminddb.so >> /usr/local/etc/php/conf.d/maxminddb.ini
RUN if [ "$DEBUG" == "true" ]; then printf "zend_extension=yasd \nyasd.debug_mode=remote \nyasd.init_file=/usr/local/dev/yasd_init.php \nyasd.remote_port=9005 \nyasd.log_level=-1" >> /usr/local/etc/php/conf.d/yasd.ini; fi
RUN if [ "$DEBUG" == "true" ]; then echo "opcache.enable=0" >> /usr/local/etc/php/conf.d/appwrite.ini; fi
RUN echo "opcache.preload_user=www-data" >> /usr/local/etc/php/conf.d/appwrite.ini
RUN echo "opcache.preload=/usr/src/code/app/preload.php" >> /usr/local/etc/php/conf.d/appwrite.ini
RUN echo "opcache.enable_cli=1" >> /usr/local/etc/php/conf.d/appwrite.ini
+10 -8
View File
@@ -1,6 +1,6 @@
<br />
<p align="center">
<a href="https://appwrite.io" target="_blank"><img width="260" height="39" src="https://appwrite.io/images/github-logo.png" alt="Appwrite Logo"></a>
<a href="https://appwrite.io" target="_blank"><img width="260" height="39" src="https://appwrite.io/images/appwrite.svg" alt="Appwrite Logo"></a>
<br />
<br />
<b>A complete backend solution for your [Flutter / Vue / Angular / React / iOS / Android / *ANY OTHER*] app</b>
@@ -10,12 +10,12 @@
<!--[![Hacktoberfest](https://badgen.net/badge/hacktoberfest/friendly/pink)](CONTRIBUTING.md)-->
[![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord)
[![Swag Store](https://img.shields.io/badge/swag%20store-f02e65?style=flat-square)](https://store.appwrite.io)
[![Docker Pulls](https://img.shields.io/docker/pulls/appwrite/appwrite?color=f02e65&style=flat-square)](https://hub.docker.com/r/appwrite/appwrite)
[![Build Status](https://img.shields.io/travis/com/appwrite/appwrite?style=flat-square)](https://travis-ci.com/appwrite/appwrite)
[![Twitter Account](https://img.shields.io/twitter/follow/appwrite_io?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite_io)
[![Follow Appwrite on StackShare](https://img.shields.io/badge/follow%20on-stackshare-blue?style=flat-square)](https://stackshare.io/appwrite)
[**Appwrite 0.8 has been released! Learn what's new!**](https://dev.to/appwrite/announcing-appwrite-0-8-an-open-source-self-hosted-baas-kda)
[**Appwrite 0.9 has been released! Learn what's new!**](https://dev.to/appwrite/announcing-appwrite-0-9-the-open-source-firebase-alternative-53ho)
Appwrite is an end-to-end backend server for Web, Mobile, Native, or Backend apps packaged as a set of Docker<nobr> microservices. Appwrite abstracts the complexity and repetitiveness required to build a modern backend API from scratch and allows you to build secure apps faster.
@@ -56,7 +56,7 @@ docker run -it --rm \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
--entrypoint="install" \
appwrite/appwrite:0.8.0
appwrite/appwrite:0.9.4
```
### Windows
@@ -68,7 +68,7 @@ docker run -it --rm ^
--volume //var/run/docker.sock:/var/run/docker.sock ^
--volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^
--entrypoint="install" ^
appwrite/appwrite:0.8.0
appwrite/appwrite:0.9.4
```
#### PowerShell
@@ -78,7 +78,7 @@ docker run -it --rm ,
--volume /var/run/docker.sock:/var/run/docker.sock ,
--volume ${pwd}/appwrite:/usr/src/code/appwrite:rw ,
--entrypoint="install" ,
appwrite/appwrite:0.8.0
appwrite/appwrite:0.9.4
```
Once the Docker installation completes, go to http://localhost to access the Appwrite console from your browser. Please note that on non-linux native hosts, the server might take a few minutes to start after installation completes.
@@ -121,14 +121,16 @@ Below is a list of currently supported platforms and languages. If you wish to h
#### Client
* ✅ &nbsp; [Web](https://github.com/appwrite/sdk-for-web) (Maintained by the Appwrite Team)
* ✅ &nbsp; [Flutter](https://github.com/appwrite/sdk-for-flutter) (Maintained by the Appwrite Team)
* ✅ &nbsp; [Android](https://github.com/appwrite/sdk-for-android) (Maintained by the Appwrite Team)
#### Server
* ✅ &nbsp; [NodeJS](https://github.com/appwrite/sdk-for-node) (Maintained by the Appwrite Team)
* ✅ &nbsp; [PHP](https://github.com/appwrite/sdk-for-php) (Maintained by the Appwrite Team)
* ✅ &nbsp; [Dart](https://github.com/appwrite/sdk-for-dart) **Beta** (Maintained by the Appwrite Team)
* ✅ &nbsp; [Deno](https://github.com/appwrite/sdk-for-deno) - **Beta** (Maintained by the Appwrite Team)
* ✅ &nbsp; [Ruby](https://github.com/appwrite/sdk-for-ruby) - **Beta** (Maintained by the Appwrite Team)
* ✅ &nbsp; [Python](https://github.com/appwrite/sdk-for-python) - **Beta** (Maintained by the Appwrite Team)
* ✅ &nbsp; [Ruby](https://github.com/appwrite/sdk-for-ruby) (Maintained by the Appwrite Team)
* ✅ &nbsp; [Python](https://github.com/appwrite/sdk-for-python) (Maintained by the Appwrite Team)
* ✅ &nbsp; [Kotlin](https://github.com/appwrite/sdk-for-kotlin) - **Beta** (Maintained by the Appwrite Team)
* ✅ &nbsp; [.NET](https://github.com/appwrite/sdk-for-dotnet) - **Experimental** (Maintained by the Appwrite Team)
Looking for more SDKs? - Help us by contributing a pull request to our [SDK Generator](https://github.com/appwrite/sdk-generator)!
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
require_once __DIR__.'/init.php';
require_once __DIR__.'/workers.php';
use Utopia\App;
use Utopia\CLI\CLI;
+10 -2
View File
@@ -779,6 +779,14 @@ $collections = [
'default' => 0,
'required' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Version',
'key' => 'version',
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
'default' => '',
'required' => true,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Webhooks',
@@ -1481,8 +1489,8 @@ $collections = [
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Env',
'key' => 'env',
'label' => 'Runtime',
'key' => 'runtime',
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
'default' => '',
'required' => false,
+17 -45
View File
@@ -56,13 +56,13 @@
.main {
background: {{bg-content}};
border-radius: 3px;
border-radius: 10px;
width: 100%;
}
.wrapper {
box-sizing: border-box;
padding: 20px;
padding: 30px 30px 15px 30px;
}
.content-block {
@@ -97,16 +97,15 @@
.btn table td {
background-color: {{bg-content}};
border-radius: 5px;
border-radius: 20px;
text-align: center;
}
.btn a {
background-color: {{bg-content}};
border: solid 1px {{bg-cta}};
border-radius: 5px;
border-radius: 20px;
box-sizing: border-box;
color: #3498db;
color: #577590;
cursor: pointer;
display: inline-block;
font-size: 14px;
@@ -123,45 +122,17 @@
.btn-primary a {
background-color: {{bg-cta}};
border-color: {{bg-cta}};
color: {{text-cta}};
}
@media only screen and (max-width: 620px) {
table[class=body] h1 {
font-size: 28px !important;
margin-bottom: 10px !important;
.container {
padding: 0;
width: 100%;
}
table[class=body] p {
font-size: 16px !important;
}
table[class=body] .wrapper {
padding: 10px !important;
}
table[class=body] .content {
padding: 0 !important;
}
table[class=body] .container {
padding: 0 !important;
width: 100% !important;
}
table[class=body] .main {
border-left-width: 0 !important;
border-radius: 0 !important;
border-right-width: 0 !important;
}
table[class=body] .btn table {
width: 100% !important;
}
table[class=body] .btn a {
width: 100% !important;
.btn-primary a {
font-size: 13px;
}
}
@@ -198,12 +169,11 @@
}
.btn-primary table td:hover {
background-color: {{bg-cta-hover}} !important;
opacity: 0.7 !important;
}
.btn-primary a:hover {
background-color: {{bg-cta-hover}} !important;
border-color: {{bg-cta-hover}} !important;
opacity: 0.7 !important;
}
}
</style>
@@ -220,15 +190,17 @@
<td class="wrapper">
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
{{content}}
</td>
<td>{{content}}</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<!-- <div style="text-align: center; line-height: 25px; margin: 15px 0; font-size: 12px; color: #40404c;">
<a href="https://appwrite.io" style="text-decoration: none; color: #40404c;">Powered by <img src="https://appwrite.io/images/appwrite-footer-light.svg" height="15" style="margin: -3px 0" /></a>
</div> -->
</td>
<td>&nbsp;</td>
</tr>
+4 -6
View File
@@ -1,7 +1,7 @@
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="btn btn-primary">
<tbody>
<tr>
<td align="left">
<td>
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
@@ -18,9 +18,7 @@
</tbody>
</table>
<p>
<small>
<a href="{{redirect}}" target="_blank">
{{redirect}}
</a>
</small>
<a href="{{redirect}}" target="_blank">
{{redirect}}
</a>
</p>
@@ -1,4 +1,4 @@
<p>
<p>
Hola {{name}},
</p>
<p>
@@ -12,4 +12,4 @@
Gracias,
<br />
Equipo {{project}}
</p>
</p>
@@ -1,5 +1,5 @@
<p>
Hola,
Hola {{name}},
</p>
<p>
Te hemos enviado este correo porque <b>{{owner}}</b> quiere invitarte a formar parte del equipo <b>{{team}}</b> en {{project}}.
@@ -2,7 +2,7 @@
שלום {{name}},
</p>
<p>
נא ללחוץ על הקישור שלהלן כדי לאמת את החשבון שלך.
אנא לחץ\י על הקישור שלהלן כדי לאמת את החשבון שלך.
</p>
{{cta}}
<p>
@@ -5,7 +5,7 @@
הודעת דוא״ל זו נשלחה אליך כי <b>{{owner}}</b> ביקש להזמינך להצטרף לצוות <b>{{team}}</b> ב־{{project}}.
</p>
<p>
כדי להצטרף לצוות <b>{{team}}</b>, נא ללחוץ על הקישור:
כדי להצטרף לצוות <b>{{team}}</b>, אנא לחץ\י על הקישור:
</p>
{{cta}}
<p>
@@ -2,7 +2,7 @@
שלום {{name}},
</p>
<p>
נא ללחוץ על הקישור שלהלן כדי לאפס את הסיסמה שלך ב־{{project}}.
אנא לחץ\י על הקישור שלהלן כדי לאפס את הסיסמה שלך ב־{{project}}.
</p>
{{cta}}
<p>
+46 -20
View File
@@ -15,7 +15,7 @@ return [
[
'key' => 'web',
'name' => 'Web',
'version' => '3.0.4',
'version' => '3.2.0',
'url' => 'https://github.com/appwrite/sdk-for-web',
'package' => 'https://www.npmjs.com/package/appwrite',
'enabled' => true,
@@ -62,7 +62,7 @@ return [
[
'key' => 'flutter',
'name' => 'Flutter',
'version' => '0.6.2',
'version' => '0.7.0',
'url' => 'https://github.com/appwrite/sdk-for-flutter',
'package' => 'https://pub.dev/packages/appwrite',
'enabled' => true,
@@ -109,20 +109,25 @@ return [
'gitUserName' => 'appwrite',
],
[
'key' => 'kotlin',
'name' => 'Kotlin',
'url' => '',
'package' => '',
'enabled' => false,
'beta' => false,
'key' => 'android',
'name' => 'Android',
'version' => '0.0.1',
'url' => 'https://github.com/appwrite/sdk-for-android',
'package' => 'https://search.maven.org/artifact/io.appwrite/sdk-for-android',
'enabled' => true,
'beta' => true,
'dev' => false,
'hidden' => false,
'family' => APP_PLATFORM_CLIENT,
'prism' => 'kotlin',
'source' => false,
'gitUrl' => 'git@github.com:appwrite/sdk-for-kotlin.git',
'gitRepoName' => 'sdk-for-kotlin',
'source' => \realpath(__DIR__ . '/../sdks/client-android'),
'gitUrl' => 'git@github.com:appwrite/sdk-for-android.git',
'gitRepoName' => 'sdk-for-android',
'gitUserName' => 'appwrite',
'docDirectories' => [
'Kotlin' => 'kotlin',
'Java' => 'java',
],
],
// [
// 'key' => 'java',
@@ -151,7 +156,7 @@ return [
[
'key' => 'web',
'name' => 'Console',
'version' => '2.0.0',
'version' => '2.1.0',
'url' => 'https://github.com/appwrite/sdk-for-console',
'package' => '',
'enabled' => true,
@@ -178,7 +183,7 @@ return [
[
'key' => 'nodejs',
'name' => 'Node.js',
'version' => '2.2.2',
'version' => '2.4.0',
'url' => 'https://github.com/appwrite/sdk-for-node',
'package' => 'https://www.npmjs.com/package/node-appwrite',
'enabled' => true,
@@ -195,7 +200,7 @@ return [
[
'key' => 'deno',
'name' => 'Deno',
'version' => '0.2.1',
'version' => '0.3.0',
'url' => 'https://github.com/appwrite/sdk-for-deno',
'package' => 'https://deno.land/x/appwrite',
'enabled' => true,
@@ -212,7 +217,7 @@ return [
[
'key' => 'php',
'name' => 'PHP',
'version' => '2.1.1',
'version' => '2.2.0',
'url' => 'https://github.com/appwrite/sdk-for-php',
'package' => 'https://packagist.org/packages/appwrite/appwrite',
'enabled' => true,
@@ -229,7 +234,7 @@ return [
[
'key' => 'python',
'name' => 'Python',
'version' => '0.2.1',
'version' => '0.4.0',
'url' => 'https://github.com/appwrite/sdk-for-python',
'package' => 'https://pypi.org/project/appwrite/',
'enabled' => true,
@@ -246,7 +251,7 @@ return [
[
'key' => 'ruby',
'name' => 'Ruby',
'version' => '2.1.1',
'version' => '2.3.0',
'url' => 'https://github.com/appwrite/sdk-for-ruby',
'package' => 'https://rubygems.org/gems/appwrite',
'enabled' => true,
@@ -263,7 +268,7 @@ return [
[
'key' => 'go',
'name' => 'Go',
'version' => '0.0.7',
'version' => '0.1.0',
'url' => 'https://github.com/appwrite/sdk-for-go',
'package' => '',
'enabled' => false,
@@ -314,7 +319,7 @@ return [
[
'key' => 'dart',
'name' => 'Dart',
'version' => '0.6.1',
'version' => '0.7.0',
'url' => 'https://github.com/appwrite/sdk-for-dart',
'package' => 'https://pub.dev/packages/dart_appwrite',
'enabled' => true,
@@ -331,7 +336,7 @@ return [
[
'key' => 'cli',
'name' => 'Command Line',
'version' => '0.10.1',
'version' => '0.11.0',
'url' => 'https://github.com/appwrite/sdk-for-cli',
'package' => 'https://github.com/appwrite/sdk-for-cli',
'enabled' => true,
@@ -345,6 +350,27 @@ return [
'gitRepoName' => 'sdk-for-cli',
'gitUserName' => 'appwrite',
],
[
'key' => 'kotlin',
'name' => 'Kotlin',
'version' => '0.0.1',
'url' => 'https://github.com/appwrite/sdk-for-kotlin',
'package' => 'https://search.maven.org/artifact/io.appwrite/sdk-for-kotlin',
'enabled' => true,
'beta' => true,
'dev' => false,
'hidden' => false,
'family' => APP_PLATFORM_SERVER,
'prism' => 'kotlin',
'source' => \realpath(__DIR__ . '/../sdks/server-kotlin'),
'gitUrl' => 'git@github.com:appwrite/sdk-for-kotlin.git',
'gitRepoName' => 'sdk-for-kotlin',
'gitUserName' => 'appwrite',
'docDirectories' => [
'Kotlin' => 'kotlin',
'Java' => 'java',
],
],
],
],
];
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
+3 -3
View File
@@ -67,7 +67,7 @@ return [
'introduction' => '',
'default' => 'localhost',
'required' => true,
'question' => 'Enter a DNS A record hostname to serve as a CNAME for your custom domains.\nYou can use the same value as used for the Appwrite hostname.',
'question' => 'Enter a DNS A record hostname to serve as a CNAME for your custom domains.' . PHP_EOL . 'You can use the same value as used for the Appwrite hostname.',
'filter' => ''
],
[
@@ -448,7 +448,7 @@ return [
'name' => '_APP_FUNCTIONS_RUNTIMES',
'description' => "This option allows you to limit the available environments for cloud functions. This option is very useful for low-cost servers to safe disk space.\n\nTo enable/activate this option, pass a list of allowed environments separated by a comma.\n\nCurrently, supported environments are: " . \implode(', ', \array_keys(Config::getParam('runtimes'))),
'introduction' => '0.8.0',
'default' => 'node-15.5,deno-1.8,php-8.0,python-3.9,ruby-3.0,dotnet-5.0',
'default' => 'node-16.0,php-8.0,python-3.9,ruby-3.0,java-16.0',
'required' => false,
'question' => '',
'filter' => ''
@@ -457,7 +457,7 @@ return [
'name' => '_APP_FUNCTIONS_ENVS',
'description' => 'Deprectated with 0.8.0, use \'_APP_FUNCTIONS_RUNTIMES\' instead!',
'introduction' => '0.7.0',
'default' => 'node-14.5,deno-1.8,php-7.4,python-3.9,ruby-3.0,dotnet-5.0',
'default' => 'node-16.0,php-7.4,python-3.9,ruby-3.0,java-16.0',
'required' => false,
'question' => '',
'filter' => ''
+97 -30
View File
@@ -58,15 +58,16 @@ App::post('/v1/account')
/** @var Appwrite\Database\Database $projectDB */
/** @var Appwrite\Event\Event $audits */
$email = \strtolower($email);
if ('console' === $project->getId()) {
$whitlistEmails = $project->getAttribute('authWhitelistEmails');
$whitlistIPs = $project->getAttribute('authWhitelistIPs');
$whitelistEmails = $project->getAttribute('authWhitelistEmails');
$whitelistIPs = $project->getAttribute('authWhitelistIPs');
if (!empty($whitlistEmails) && !\in_array($email, $whitlistEmails)) {
if (!empty($whitelistEmails) && !\in_array($email, $whitelistEmails)) {
throw new Exception('Console registration is restricted to specific emails. Contact your administrator for more information.', 401);
}
if (!empty($whitlistIPs) && !\in_array($request->getIP(), $whitlistIPs)) {
if (!empty($whitelistIPs) && !\in_array($request->getIP(), $whitelistIPs)) {
throw new Exception('Console registration is restricted to specific IPs. Contact your administrator for more information.', 401);
}
}
@@ -174,6 +175,7 @@ App::post('/v1/account/sessions')
/** @var MaxMind\Db\Reader $geodb */
/** @var Appwrite\Event\Event $audits */
$email = \strtolower($email);
$protocol = $request->getProtocol();
$profile = $projectDB->getCollectionFirst([ // Get user by email address
'limit' => 1,
@@ -252,9 +254,13 @@ App::post('/v1/account/sessions')
$countries = $locale->getText('countries');
$countryName = (isset($countries[strtoupper($session->getAttribute('countryCode'))]))
? $countries[strtoupper($session->getAttribute('countryCode'))]
: $locale->getText('locale.country.unknown');
$session
->setAttribute('current', true)
->setAttribute('countryName', (isset($countries[strtoupper($session->getAttribute('countryCode'))])) ? $countries[strtoupper($session->getAttribute('countryCode'))] : $locale->getText('locale.country.unknown'))
->setAttribute('countryName', $countryName)
;
$response->dynamic($session, Response::MODEL_SESSION);
@@ -751,9 +757,13 @@ App::post('/v1/account/sessions/anonymous')
->setStatusCode(Response::STATUS_CODE_CREATED)
;
$countryName = (isset($countries[strtoupper($session->getAttribute('countryCode'))]))
? $countries[strtoupper($session->getAttribute('countryCode'))]
: $locale->getText('locale.country.unknown');
$session
->setAttribute('current', true)
->setAttribute('countryName', (isset($countries[$session->getAttribute('countryCode')])) ? $countries[$session->getAttribute('countryCode')] : $locale->getText('locale.country.unknown'))
->setAttribute('countryName', $countryName)
;
$response->dynamic($session, Response::MODEL_SESSION);
@@ -772,7 +782,7 @@ App::post('/v1/account/jwt')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_JWT)
->label('abuse-limit', 10)
->label('abuse-key', 'url:{url},userId:{param-userId}')
->label('abuse-key', 'url:{url},userId:{userId}')
->inject('response')
->inject('user')
->action(function ($response, $user) {
@@ -876,9 +886,11 @@ App::get('/v1/account/sessions')
foreach ($sessions as $key => $session) {
/** @var Document $session */
$session->setAttribute('countryName', (isset($countries[strtoupper($session->getAttribute('countryCode'))]))
? $countries[strtoupper($session->getAttribute('countryCode'))]
: $locale->getText('locale.country.unknown'));
$countryName = (isset($countries[strtoupper($session->getAttribute('countryCode'))]))
? $countries[strtoupper($session->getAttribute('countryCode'))]
: $locale->getText('locale.country.unknown');
$session->setAttribute('countryName', $countryName);
$session->setAttribute('current', ($current == $session->getId()) ? true : false);
$sessions[$key] = $session;
@@ -902,19 +914,20 @@ App::get('/v1/account/logs')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_LOG_LIST)
->inject('response')
->inject('register')
->inject('project')
->inject('user')
->inject('locale')
->inject('geodb')
->action(function ($response, $register, $project, $user, $locale, $geodb) {
->inject('utopia')
->action(function ($response, $project, $user, $locale, $geodb, $utopia) {
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */
/** @var Appwrite\Database\Document $user */
/** @var Utopia\Locale\Locale $locale */
/** @var MaxMind\Db\Reader $geodb */
/** @var Utopia\App $utopia */
$adapter = new AuditAdapter($register->get('db'));
$adapter = new AuditAdapter($utopia->getResource('db'));
$adapter->setNamespace('app_'.$project->getId());
$audit = new Audit($adapter);
@@ -966,6 +979,47 @@ App::get('/v1/account/logs')
$response->dynamic(new Document(['logs' => $output]), Response::MODEL_LOG_LIST);
});
App::get('/v1/account/sessions/:sessionId')
->desc('Get Session By ID')
->groups(['api', 'account'])
->label('scope', 'account')
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'account')
->label('sdk.method', 'getSession')
->label('sdk.description', '/docs/references/account/get-session.md')
->label('sdk.response.code', Response::STATUS_CODE_OK)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_SESSION)
->param('sessionId', null, new UID(), 'Session unique ID. Use the string \'current\' to get the current device session.')
->inject('response')
->inject('user')
->inject('locale')
->inject('projectDB')
->action(function ($sessionId, $response, $user, $locale, $projectDB) {
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $user */
/** @var Utopia\Locale\Locale $locale */
/** @var Appwrite\Database\Database $projectDB */
$sessionId = ($sessionId === 'current')
? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret)
: $sessionId;
$session = $projectDB->getDocument($sessionId); // get user by session ID
if ($session->isEmpty() || Database::SYSTEM_COLLECTION_SESSIONS != $session->getCollection()) {
throw new Exception('Session not found', 404);
};
$countryName = (isset($countries[strtoupper($session->getAttribute('countryCode'))]))
? $countries[strtoupper($session->getAttribute('countryCode'))]
: $locale->getText('locale.country.unknown');
$session->setAttribute('countryName', $countryName);
$response->dynamic($session, Response::MODEL_SESSION);
});
App::patch('/v1/account/name')
->desc('Update Account Name')
->groups(['api', 'account'])
@@ -1086,6 +1140,7 @@ App::patch('/v1/account/email')
throw new Exception('Invalid credentials', 401);
}
$email = \strtolower($email);
$profile = $projectDB->getCollectionFirst([ // Get user by email address
'limit' => 1,
'filters' => [
@@ -1100,14 +1155,23 @@ App::patch('/v1/account/email')
// TODO after this user needs to confirm mail again
$user = $projectDB->updateDocument(\array_merge(
if (!$isAnonymousUser) {
// Remove previous unique ID.
$projectDB->deleteUniqueKey(\md5($user->getArrayCopy()['$collection'].':'.'email'.'='.$user->getAttribute('email')));
}
$document = (\array_merge(
$user->getArrayCopy(),
($isAnonymousUser ? [ 'password' => Auth::passwordHash($password) ] : []),
[
'email' => $email,
'emailVerification' => false,
]
));
));
$user = $projectDB->updateDocument($document);
$projectDB->addUniqueKey(\md5($document['$collection'].':'.'email'.'='.$email));
if (false === $user) {
throw new Exception('Failed saving user to DB', 500);
@@ -1408,7 +1472,8 @@ App::post('/v1/account/recovery')
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles);
$isAppUser = Auth::isAppUser(Authorization::$roles);
$email = \strtolower($email);
$profile = $projectDB->getCollectionFirst([ // Get user by email address
'limit' => 1,
'filters' => [
@@ -1425,6 +1490,8 @@ App::post('/v1/account/recovery')
throw new Exception('Invalid credentials. User is blocked', 401); // User is in status blocked
}
$expire = \time() + Auth::TOKEN_EXPIRATION_RECOVERY;
$secret = Auth::tokenGenerator();
$recovery = new Document([
'$collection' => Database::SYSTEM_COLLECTION_TOKENS,
@@ -1432,7 +1499,7 @@ App::post('/v1/account/recovery')
'userId' => $profile->getId(),
'type' => Auth::TOKEN_TYPE_RECOVERY,
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
'expire' => \time() + Auth::TOKEN_EXPIRATION_RECOVERY,
'expire' => $expire,
'userAgent' => $request->getUserAgent('UNKNOWN'),
'ip' => $request->getIP(),
]);
@@ -1454,7 +1521,7 @@ App::post('/v1/account/recovery')
}
$url = Template::parseURL($url);
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['userId' => $profile->getId(), 'secret' => $secret]);
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['userId' => $profile->getId(), 'secret' => $secret, 'expire' => $expire]);
$url = Template::unParseURL($url);
$body = new Template(__DIR__.'/../../config/locale/templates/email-base.tpl');
@@ -1462,17 +1529,16 @@ App::post('/v1/account/recovery')
$cta = new Template(__DIR__.'/../../config/locale/templates/email-cta.tpl');
$body
->setParam('{{content}}', $content->render())
->setParam('{{content}}', $content->render(false))
->setParam('{{cta}}', $cta->render())
->setParam('{{title}}', $locale->getText('account.emails.recovery.title'))
->setParam('{{direction}}', $locale->getText('settings.direction'))
->setParam('{{project}}', $project->getAttribute('name', ['[APP-NAME]']))
->setParam('{{name}}', $profile->getAttribute('name'))
->setParam('{{redirect}}', $url)
->setParam('{{bg-body}}', '#f6f6f6')
->setParam('{{bg-body}}', '#f7f7f7')
->setParam('{{bg-content}}', '#ffffff')
->setParam('{{bg-cta}}', '#3498db')
->setParam('{{bg-cta-hover}}', '#34495e')
->setParam('{{bg-cta}}', '#073b4c')
->setParam('{{text-content}}', '#000000')
->setParam('{{text-cta}}', '#ffffff')
;
@@ -1602,7 +1668,7 @@ App::post('/v1/account/verification')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_TOKEN)
->label('abuse-limit', 10)
->label('abuse-key', 'url:{url},email:{param-email}')
->label('abuse-key', 'url:{url},userId:{userId}')
->param('url', '', function ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the verification 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.', false, ['clients']) // TODO add built-in confirm page
->inject('request')
->inject('response')
@@ -1628,6 +1694,8 @@ App::post('/v1/account/verification')
$isAppUser = Auth::isAppUser(Authorization::$roles);
$verificationSecret = Auth::tokenGenerator();
$expire = \time() + Auth::TOKEN_EXPIRATION_CONFIRM;
$verification = new Document([
'$collection' => Database::SYSTEM_COLLECTION_TOKENS,
@@ -1635,7 +1703,7 @@ App::post('/v1/account/verification')
'userId' => $user->getId(),
'type' => Auth::TOKEN_TYPE_VERIFICATION,
'secret' => Auth::hash($verificationSecret), // One way hash encryption to protect DB leak
'expire' => \time() + Auth::TOKEN_EXPIRATION_CONFIRM,
'expire' => $expire,
'userAgent' => $request->getUserAgent('UNKNOWN'),
'ip' => $request->getIP(),
]);
@@ -1655,9 +1723,9 @@ App::post('/v1/account/verification')
if (false === $user) {
throw new Exception('Failed to save user to DB', 500);
}
$url = Template::parseURL($url);
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['userId' => $user->getId(), 'secret' => $verificationSecret]);
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['userId' => $user->getId(), 'secret' => $verificationSecret, 'expire' => $expire]);
$url = Template::unParseURL($url);
$body = new Template(__DIR__.'/../../config/locale/templates/email-base.tpl');
@@ -1665,17 +1733,16 @@ App::post('/v1/account/verification')
$cta = new Template(__DIR__.'/../../config/locale/templates/email-cta.tpl');
$body
->setParam('{{content}}', $content->render())
->setParam('{{content}}', $content->render(false))
->setParam('{{cta}}', $cta->render())
->setParam('{{title}}', $locale->getText('account.emails.verification.title'))
->setParam('{{direction}}', $locale->getText('settings.direction'))
->setParam('{{project}}', $project->getAttribute('name', ['[APP-NAME]']))
->setParam('{{name}}', $user->getAttribute('name'))
->setParam('{{redirect}}', $url)
->setParam('{{bg-body}}', '#f6f6f6')
->setParam('{{bg-body}}', '#f7f7f7')
->setParam('{{bg-content}}', '#ffffff')
->setParam('{{bg-cta}}', '#3498db')
->setParam('{{bg-cta-hover}}', '#34495e')
->setParam('{{bg-cta}}', '#073b4c')
->setParam('{{text-content}}', '#000000')
->setParam('{{text-cta}}', '#ffffff')
;
+8 -2
View File
@@ -436,6 +436,12 @@ App::get('/v1/database/collections/:collectionId/documents')
throw new Exception('Collection not found', 404);
}
$types = [];
foreach ($collection->getAttribute('rules', []) as $rule) {
/** @var Document $rule */
$types[$rule->getAttribute('key')] = $rule->getAttribute('type');
}
$list = $projectDB->getCollection([
'limit' => $limit,
'offset' => $offset,
@@ -446,7 +452,7 @@ App::get('/v1/database/collections/:collectionId/documents')
'filters' => \array_merge($filters, [
'$collection='.$collectionId,
]),
]);
], $types);
// if (App::isDevelopment()) {
// $collection
@@ -624,4 +630,4 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId')
;
$response->noContent();
});
});
+10 -10
View File
@@ -39,14 +39,14 @@ App::post('/v1/functions')
->label('sdk.response.model', Response::MODEL_FUNCTION)
->param('name', '', new Text(128), 'Function name. Max length: 128 chars.')
->param('execute', [], new ArrayList(new Text(64)), 'An array of strings with execution permissions. By default no user is granted with any execute permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
->param('env', '', new WhiteList(array_keys(Config::getParam('runtimes')), true), 'Execution enviornment.')
->param('runtime', '', new WhiteList(array_keys(Config::getParam('runtimes')), true), 'Execution runtime.')
->param('vars', [], new Assoc(), 'Key-value JSON object.', true)
->param('events', [], new ArrayList(new WhiteList(array_keys(Config::getParam('events')), true)), 'Events list.', true)
->param('schedule', '', new Cron(), 'Schedule CRON syntax.', true)
->param('timeout', 15, new Range(1, 900), 'Function maximum execution time in seconds.', true)
->inject('response')
->inject('projectDB')
->action(function ($name, $execute, $env, $vars, $events, $schedule, $timeout, $response, $projectDB) {
->action(function ($name, $execute, $runtime, $vars, $events, $schedule, $timeout, $response, $projectDB) {
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Database $projectDB */
@@ -59,7 +59,7 @@ App::post('/v1/functions')
'dateUpdated' => time(),
'status' => 'disabled',
'name' => $name,
'env' => $env,
'runtime' => $runtime,
'tag' => '',
'vars' => $vars,
'events' => $events,
@@ -748,20 +748,20 @@ App::post('/v1/functions/:functionId/executions')
$jwt = ''; // initialize
if (!empty($user->getId())) { // If userId exists, generate a JWT for function
$tokens = $user->getAttribute('tokens', []);
$session = new Document();
$sessions = $user->getAttribute('sessions', []);
$current = new Document();
foreach ($tokens as $token) { /** @var Appwrite\Database\Document $token */
if ($token->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too
$session = $token;
foreach ($sessions as $session) { /** @var Appwrite\Database\Document $session */
if ($session->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too
$current = $session;
}
}
if(!$session->isEmpty()) {
if(!$current->isEmpty()) {
$jwtObj = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 900, 10); // Instantiate with key, algo, maxAge and leeway.
$jwt = $jwtObj->encode([
'userId' => $user->getId(),
'sessionId' => $session->getId(),
'sessionId' => $current->getId(),
]);
}
}
+9 -11
View File
@@ -6,7 +6,6 @@ use Utopia\Storage\Device\Local;
use Utopia\Storage\Storage;
use Appwrite\ClamAV\Network;
use Appwrite\Event\Event;
use RuntimeException;
App::get('/v1/health')
->desc('Get HTTP')
@@ -43,12 +42,11 @@ App::get('/v1/health/db')
->label('sdk.method', 'getDB')
->label('sdk.description', '/docs/references/health/get-db.md')
->inject('response')
->inject('register')
->action(function ($response, $register) {
->inject('utopia')
->action(function ($response, $utopia) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Registry\Registry $register */
$register->get('db'); /* @var $db PDO */
/** @var Utopia\App $utopia */
$utopia->getResource('db');
$response->json(['status' => 'OK']);
});
@@ -62,11 +60,11 @@ App::get('/v1/health/cache')
->label('sdk.method', 'getCache')
->label('sdk.description', '/docs/references/health/get-cache.md')
->inject('response')
->inject('register')
->action(function ($response, $register) {
->inject('utopia')
->action(function ($response, $utopia) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Registry\Registry $register */
$register->get('cache'); /* @var $cache Predis\Client */
/** @var Utopia\App $utopia */
$utopia->getResource('cache');
$response->json(['status' => 'OK']);
});
@@ -268,7 +266,7 @@ App::get('/v1/health/anti-virus')
'status' => (@$antiVirus->ping()) ? 'online' : 'offline',
'version' => @$antiVirus->version(),
]);
} catch( RuntimeException $e) {
} catch( \Exception $e) {
$response->json([
'status' => 'offline',
'version' => '',
+10 -1
View File
@@ -21,6 +21,14 @@ use Appwrite\Network\Validator\Domain as DomainValidator;
use Appwrite\Utopia\Response;
use Cron\CronExpression;
App::init(function ($project) {
/** @var Utopia\Database\Document $project */
if($project->getId() !== 'console') {
throw new Exception('Access to this API is forbidden.', 401);
}
}, ['project'], 'projects');
App::post('/v1/projects')
->desc('Create Project')
->groups(['api', 'projects'])
@@ -74,6 +82,7 @@ App::post('/v1/projects')
'legalAddress' => $legalAddress,
'legalTaxId' => $legalTaxId,
'teamId' => $team->getId(),
'version' => APP_VERSION_STABLE,
'platforms' => [],
'webhooks' => [],
'keys' => [],
@@ -1268,7 +1277,7 @@ App::post('/v1/projects/:projectId/platforms')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_PLATFORM)
->param('projectId', null, new UID(), 'Project unique ID.')
->param('type', null, new WhiteList(['web', 'flutter-ios', 'flutter-android', 'ios', 'android', 'unity'], true), 'Platform type.')
->param('type', null, new WhiteList(['web', 'flutter-ios', 'flutter-android', 'flutter-linux', 'flutter-macos', 'flutter-windows', 'ios', 'android', 'unity'], true), 'Platform type.')
->param('name', null, new Text(128), 'Platform name. Max length: 128 chars.')
->param('key', '', new Text(256), 'Package name for android or bundle ID for iOS. Max length: 256 chars.', true)
->param('store', '', new Text(256), 'App store or Google Play store ID. Max length: 256 chars.', true)
+5 -5
View File
@@ -22,7 +22,6 @@ use Utopia\Image\Image;
use Appwrite\OpenSSL\OpenSSL;
use Appwrite\Utopia\Response;
use Utopia\Config\Config;
use Utopia\Validator\Numeric;
App::post('/v1/storage/files')
->desc('Create File')
@@ -242,6 +241,7 @@ App::get('/v1/storage/files/:fileId/preview')
->param('fileId', '', new UID(), 'File unique ID')
->param('width', 0, new Range(0, 4000), 'Resize preview image width, Pass an integer between 0 to 4000.', true)
->param('height', 0, new Range(0, 4000), 'Resize preview image height, Pass an integer between 0 to 4000.', true)
->param('gravity', Image::GRAVITY_CENTER, new WhiteList(Image::getGravityTypes()), 'Image crop gravity. Can be one of ' . implode(",", Image::getGravityTypes()), true)
->param('quality', 100, new Range(0, 100), 'Preview image quality. Pass an integer between 0 to 100. Defaults to 100.', true)
->param('borderWidth', 0, new Range(0, 100), 'Preview image border in pixels. Pass an integer between 0 to 100. Defaults to 0.', true)
->param('borderColor', '', new HexColor(), 'Preview image border color. Use a valid HEX color, no # is needed for prefix.', true)
@@ -254,7 +254,7 @@ App::get('/v1/storage/files/:fileId/preview')
->inject('response')
->inject('project')
->inject('projectDB')
->action(function ($fileId, $width, $height, $quality, $borderWidth, $borderColor, $borderRadius, $opacity, $rotation, $background, $output, $request, $response, $project, $projectDB) {
->action(function ($fileId, $width, $height, $gravity, $quality, $borderWidth, $borderColor, $borderRadius, $opacity, $rotation, $background, $output, $request, $response, $project, $projectDB) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */
@@ -279,7 +279,7 @@ App::get('/v1/storage/files/:fileId/preview')
$fileLogos = Config::getParam('storage-logos');
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT'; // 45 days cache
$key = \md5($fileId.$width.$height.$quality.$borderWidth.$borderColor.$borderRadius.$opacity.$rotation.$background.$storage.$output);
$key = \md5($fileId.$width.$height.$gravity.$quality.$borderWidth.$borderColor.$borderRadius.$opacity.$rotation.$background.$storage.$output);
$file = $projectDB->getDocument($fileId);
@@ -299,7 +299,7 @@ App::get('/v1/storage/files/:fileId/preview')
$cipher = null;
$background = (empty($background)) ? 'eceff1' : $background;
$type = \strtolower(\pathinfo($path, PATHINFO_EXTENSION));
$key = \md5($path.$width.$height.$quality.$borderWidth.$borderColor.$borderRadius.$opacity.$rotation.$background.$storage.$output);
$key = \md5($path.$width.$height.$gravity.$quality.$borderWidth.$borderColor.$borderRadius.$opacity.$rotation.$background.$storage.$output);
}
$compressor = new GZIP();
@@ -342,7 +342,7 @@ App::get('/v1/storage/files/:fileId/preview')
$image = new Image($source);
$image->crop((int) $width, (int) $height);
$image->crop((int) $width, (int) $height, $gravity);
if (!empty($opacity) || $opacity==0) {
$image->setOpacity($opacity);
+13 -22
View File
@@ -212,7 +212,8 @@ App::delete('/v1/teams/:teamId')
->inject('response')
->inject('projectDB')
->inject('events')
->action(function ($teamId, $response, $projectDB, $events) {
->inject('deletes')
->action(function ($teamId, $response, $projectDB, $events, $deletes) {
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Database $projectDB */
/** @var Appwrite\Event\Event $events */
@@ -223,25 +224,15 @@ App::delete('/v1/teams/:teamId')
throw new Exception('Team not found', 404);
}
$memberships = $projectDB->getCollection([
'limit' => 2000, // TODO add members limit
'offset' => 0,
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_MEMBERSHIPS,
'teamId='.$teamId,
],
]);
foreach ($memberships as $member) {
if (!$projectDB->deleteDocument($member->getId())) {
throw new Exception('Failed to remove membership for team from DB', 500);
}
}
if (!$projectDB->deleteDocument($teamId)) {
throw new Exception('Failed to remove team from DB', 500);
}
$deletes
->setParam('type', DELETE_TYPE_DOCUMENT)
->setParam('document', $team)
;
$events
->setParam('eventData', $response->output($team, Response::MODEL_TEAM))
;
@@ -285,7 +276,8 @@ App::post('/v1/teams/:teamId/memberships')
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles);
$isAppUser = Auth::isAppUser(Authorization::$roles);
$email = \strtolower($email);
$name = (empty($name)) ? $email : $name;
$team = $projectDB->getDocument($teamId);
@@ -433,7 +425,7 @@ App::post('/v1/teams/:teamId/memberships')
$title = \sprintf($locale->getText('account.emails.invitation.title'), $team->getAttribute('name', '[TEAM-NAME]'), $project->getAttribute('name', ['[APP-NAME]']));
$body
->setParam('{{content}}', $content->render())
->setParam('{{content}}', $content->render(false))
->setParam('{{cta}}', $cta->render())
->setParam('{{title}}', $title)
->setParam('{{direction}}', $locale->getText('settings.direction'))
@@ -441,10 +433,9 @@ App::post('/v1/teams/:teamId/memberships')
->setParam('{{team}}', $team->getAttribute('name', '[TEAM-NAME]'))
->setParam('{{owner}}', $user->getAttribute('name', ''))
->setParam('{{redirect}}', $url)
->setParam('{{bg-body}}', '#f6f6f6')
->setParam('{{bg-body}}', '#f7f7f7')
->setParam('{{bg-content}}', '#ffffff')
->setParam('{{bg-cta}}', '#3498db')
->setParam('{{bg-cta-hover}}', '#34495e')
->setParam('{{bg-cta}}', '#073b4c')
->setParam('{{text-content}}', '#000000')
->setParam('{{text-cta}}', '#ffffff')
;
@@ -784,7 +775,7 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
if ($membership->getAttribute('confirm')) { // Count only confirmed members
$team = $projectDB->updateDocument(\array_merge($team->getArrayCopy(), [
'sum' => $team->getAttribute('sum', 0) - 1,
'sum' => \max($team->getAttribute('sum', 0) - 1, 0), // Ensure that sum >= 0
]));
}
+43 -4
View File
@@ -8,6 +8,7 @@ use Utopia\Validator\WhiteList;
use Appwrite\Network\Validator\Email;
use Utopia\Validator\Text;
use Utopia\Validator\Range;
use Utopia\Validator\Boolean;
use Utopia\Audit\Audit;
use Utopia\Audit\Adapters\MySQL as AuditAdapter;
use Appwrite\Auth\Auth;
@@ -40,6 +41,7 @@ App::post('/v1/users')
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Database $projectDB */
$email = \strtolower($email);
$profile = $projectDB->getCollectionFirst([ // Get user by email address
'limit' => 1,
'filters' => [
@@ -230,18 +232,18 @@ App::get('/v1/users/:userId/logs')
->label('sdk.response.model', Response::MODEL_LOG_LIST)
->param('userId', '', new UID(), 'User unique ID.')
->inject('response')
->inject('register')
->inject('project')
->inject('projectDB')
->inject('locale')
->inject('geodb')
->action(function ($userId, $response, $register, $project, $projectDB, $locale, $geodb) {
->inject('utopia')
->action(function ($userId, $response, $project, $projectDB, $locale, $geodb, $utopia) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Registry\Registry $register */
/** @var Appwrite\Database\Document $project */
/** @var Appwrite\Database\Database $projectDB */
/** @var Utopia\Locale\Locale $locale */
/** @var MaxMind\Db\Reader $geodb */
/** @var Utopia\App $utopia */
$user = $projectDB->getDocument($userId);
@@ -249,7 +251,7 @@ App::get('/v1/users/:userId/logs')
throw new Exception('User not found', 404);
}
$adapter = new AuditAdapter($register->get('db'));
$adapter = new AuditAdapter($utopia->getResource('db'));
$adapter->setNamespace('app_'.$project->getId());
$audit = new Audit($adapter);
@@ -368,6 +370,43 @@ App::patch('/v1/users/:userId/status')
$response->dynamic($user, Response::MODEL_USER);
});
App::patch('/v1/users/:userId/verification')
->desc('Update Email Verification')
->groups(['api', 'users'])
->label('event', 'users.update.verification')
->label('scope', 'users.write')
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'users')
->label('sdk.method', 'updateVerification')
->label('sdk.description', '/docs/references/users/update-user-verification.md')
->label('sdk.response.code', Response::STATUS_CODE_OK)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_USER)
->param('userId', '', new UID(), 'User unique ID.')
->param('emailVerification', false, new Boolean(), 'User Email Verification Status.')
->inject('response')
->inject('projectDB')
->action(function ($userId, $emailVerification, $response, $projectDB) {
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Database $projectDB */
$user = $projectDB->getDocument($userId);
if (empty($user->getId()) || Database::SYSTEM_COLLECTION_USERS != $user->getCollection()) {
throw new Exception('User not found', 404);
}
$user = $projectDB->updateDocument(\array_merge($user->getArrayCopy(), [
'emailVerification' => $emailVerification,
]));
if (false === $user) {
throw new Exception('Failed saving user to DB', 500);
}
$response->dynamic($user, Response::MODEL_USER);
});
App::patch('/v1/users/:userId/prefs')
->desc('Update User Preferences')
->groups(['api', 'users'])
+8
View File
@@ -16,6 +16,7 @@ use Appwrite\Database\Validator\Authorization;
use Appwrite\Network\Validator\Origin;
use Appwrite\Utopia\Response\Filters\V06;
use Appwrite\Utopia\Response\Filters\V07;
use Appwrite\Utopia\Response\Filters\V08;
use Utopia\CLI\Console;
Config::setParam('domainVerification', false);
@@ -140,6 +141,9 @@ App::init(function ($utopia, $request, $response, $console, $project, $consoleDB
case version_compare ($responseFormat , '0.7.2', '<=') :
Response::setFilter(new V07());
break;
case version_compare ($responseFormat , '0.8.0', '<=') :
Response::setFilter(new V08());
break;
default:
Response::setFilter(null);
}
@@ -300,6 +304,10 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) {
/** @var Utopia\View $layout */
/** @var Appwrite\Database\Document $project */
if ($error instanceof PDOException) {
throw $error;
}
$route = $utopia->match($request);
$template = ($route) ? $route->getLabel('error', null) : null;
+28 -1
View File
@@ -6,9 +6,9 @@ use Appwrite\Database\Document;
use Appwrite\Network\Validator\Host;
use Appwrite\Utopia\Response;
use Utopia\App;
use Utopia\Validator\ArrayList;
use Utopia\Validator\Numeric;
use Utopia\Validator\Text;
use Utopia\Validator\ArrayList;
use Utopia\Storage\Validator\File;
App::get('/v1/mock/tests/foo')
@@ -191,6 +191,31 @@ App::delete('/v1/mock/tests/bar')
->action(function ($x, $y, $z) {
});
App::get('/v1/mock/tests/general/download')
->desc('Download File')
->groups(['mock'])
->label('scope', 'public')
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'general')
->label('sdk.method', 'download')
->label('sdk.methodType', 'location')
->label('sdk.description', 'Mock a file download request.')
->label('sdk.response.type', '*/*')
->label('sdk.response.code', Response::STATUS_CODE_OK)
->label('sdk.mock', true)
->inject('response')
->action(function ($response) {
/** @var Utopia\Swoole\Request $request */
$response
->setContentType('text/plain')
->addHeader('Content-Disposition', 'attachment; filename="test.txt"')
->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT') // 45 days cache
->addHeader('X-Peak', \memory_get_peak_usage())
->send("Download test passed.")
;
});
App::post('/v1/mock/tests/general/upload')
->desc('Upload File')
->groups(['mock'])
@@ -246,6 +271,7 @@ App::get('/v1/mock/tests/general/redirect')
->label('sdk.description', 'Mock a redirect request.')
->label('sdk.response.code', Response::STATUS_CODE_MOVED_PERMANENTLY)
->label('sdk.response.type', Response::CONTENT_TYPE_HTML)
->label('sdk.response.model', Response::MODEL_MOCK)
->label('sdk.mock', true)
->inject('response')
->action(function ($response) {
@@ -369,6 +395,7 @@ App::get('/v1/mock/tests/general/502-error')
->label('sdk.description', 'Mock a 502 bad gateway.')
->label('sdk.response.code', Response::STATUS_CODE_BAD_GATEWAY)
->label('sdk.response.type', Response::CONTENT_TYPE_TEXT)
->label('sdk.response.model', Response::MODEL_ANY)
->label('sdk.mock', true)
->inject('response')
->action(function ($response) {
+3 -5
View File
@@ -9,7 +9,7 @@ use Utopia\Abuse\Adapters\TimeLimit;
use Utopia\Storage\Device\Local;
use Utopia\Storage\Storage;
App::init(function ($utopia, $request, $response, $project, $user, $register, $events, $audits, $usage, $deletes) {
App::init(function ($utopia, $request, $response, $project, $user, $register, $events, $audits, $usage, $deletes, $db) {
/** @var Utopia\App $utopia */
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
@@ -34,9 +34,7 @@ App::init(function ($utopia, $request, $response, $project, $user, $register, $e
/*
* Abuse Check
*/
$timeLimit = new TimeLimit($route->getLabel('abuse-key', 'url:{url},ip:{ip}'), $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), function () use ($register) {
return $register->get('db');
});
$timeLimit = new TimeLimit($route->getLabel('abuse-key', 'url:{url},ip:{ip}'), $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), $db);
$timeLimit->setNamespace('app_'.$project->getId());
$timeLimit
->setParam('{userId}', $user->getId())
@@ -111,7 +109,7 @@ App::init(function ($utopia, $request, $response, $project, $user, $register, $e
->setParam('projectId', $project->getId())
;
}, ['utopia', 'request', 'response', 'project', 'user', 'register', 'events', 'audits', 'usage', 'deletes'], 'api');
}, ['utopia', 'request', 'response', 'project', 'user', 'register', 'events', 'audits', 'usage', 'deletes', 'db'], 'api');
App::init(function ($utopia, $request, $response, $project, $user) {
+2 -1
View File
@@ -8,6 +8,7 @@ use Utopia\App;
use Utopia\View;
use Utopia\Config\Config;
use Utopia\Exception;
use Utopia\Validator\Boolean;
use Utopia\Validator\Range;
use Utopia\Validator\WhiteList;
@@ -494,4 +495,4 @@ App::get('/versions')
}
$response->json($versions);
});
});
Binary file not shown.
Binary file not shown.
+29 -13
View File
@@ -3,8 +3,6 @@
require_once __DIR__.'/../vendor/autoload.php';
use Appwrite\Database\Validator\Authorization;
use Utopia\Swoole\Files;
use Utopia\Swoole\Request;
use Appwrite\Utopia\Response;
use Swoole\Process;
use Swoole\Http\Server;
@@ -12,16 +10,8 @@ use Swoole\Http\Request as SwooleRequest;
use Swoole\Http\Response as SwooleResponse;
use Utopia\App;
use Utopia\CLI\Console;
use Utopia\Config\Config;
use Utopia\Domains\Domain;
// xdebug_start_trace('/tmp/trace');
ini_set('memory_limit','512M');
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
ini_set('default_socket_timeout', -1);
error_reporting(E_ALL);
use Utopia\Swoole\Files;
use Utopia\Swoole\Request;
$http = new Server("0.0.0.0", App::getEnv('PORT', 80));
@@ -68,7 +58,7 @@ Files::load(__DIR__ . '/../public');
include __DIR__ . '/controllers/general.php';
$http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swooleResponse) {
$http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swooleResponse) use ($register) {
$request = new Request($swooleRequest);
$response = new Response($swooleResponse);
@@ -86,6 +76,17 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo
}
$app = new App('UTC');
$db = $register->get('dbPool')->get();
$redis = $register->get('redisPool')->get();
App::setResource('db', function () use (&$db) {
return $db;
});
App::setResource('cache', function () use (&$redis) {
return $redis;
});
try {
Authorization::cleanRoles();
@@ -98,12 +99,27 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo
Console::error('[Error] File: '.$th->getFile());
Console::error('[Error] Line: '.$th->getLine());
/**
* Reset Database connection if PDOException was thrown.
*/
if ($th instanceof PDOException) {
$db = null;
}
if(App::isDevelopment()) {
$swooleResponse->end('error: '.$th->getMessage());
}
else {
$swooleResponse->end('500: Server Error');
}
} finally {
/** @var PDOPool $dbPool */
$dbPool = $register->get('dbPool');
$dbPool->put($db);
/** @var RedisPool $redisPool */
$redisPool = $register->get('redisPool');
$redisPool->put($redis);
}
});
+52 -42
View File
@@ -11,6 +11,12 @@ if (\file_exists(__DIR__.'/../vendor/autoload.php')) {
require_once __DIR__.'/../vendor/autoload.php';
}
ini_set('memory_limit','512M');
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
ini_set('default_socket_timeout', -1);
error_reporting(E_ALL);
use Ahc\Jwt\JWT;
use Ahc\Jwt\JWTException;
use Appwrite\Auth\Auth;
@@ -20,7 +26,6 @@ use Appwrite\Database\Adapter\Redis as RedisAdapter;
use Appwrite\Database\Document;
use Appwrite\Database\Validator\Authorization;
use Appwrite\Event\Event;
use Appwrite\Extend\PDO;
use Appwrite\OpenSSL\OpenSSL;
use Utopia\App;
use Utopia\View;
@@ -29,7 +34,10 @@ use Utopia\Locale\Locale;
use Utopia\Registry\Registry;
use MaxMind\Db\Reader;
use PHPMailer\PHPMailer\PHPMailer;
use PDO as PDONative;
use Swoole\Database\PDOConfig;
use Swoole\Database\PDOPool;
use Swoole\Database\RedisConfig;
use Swoole\Database\RedisPool;
const APP_NAME = 'Appwrite';
const APP_DOMAIN = 'appwrite.io';
@@ -39,8 +47,8 @@ const APP_USERAGENT = APP_NAME.'-Server v%s. Please report abuse at %s';
const APP_MODE_DEFAULT = 'default';
const APP_MODE_ADMIN = 'admin';
const APP_PAGING_LIMIT = 12;
const APP_CACHE_BUSTER = 146;
const APP_VERSION_STABLE = '0.8.0';
const APP_CACHE_BUSTER = 150;
const APP_VERSION_STABLE = '0.9.4';
const APP_STORAGE_UPLOADS = '/storage/uploads';
const APP_STORAGE_FUNCTIONS = '/storage/functions';
const APP_STORAGE_CACHE = '/storage/cache';
@@ -145,23 +153,44 @@ Database::addFilter('encrypt',
/*
* Registry
*/
$register->set('db', function () { // Register DB connection
$register->set('dbPool', function () { // Register DB connection
$dbHost = App::getEnv('_APP_DB_HOST', '');
$dbPort = App::getEnv('_APP_DB_PORT', '');
$dbUser = App::getEnv('_APP_DB_USER', '');
$dbPass = App::getEnv('_APP_DB_PASS', '');
$dbScheme = App::getEnv('_APP_DB_SCHEMA', '');
$pdo = new PDO("mysql:host={$dbHost};dbname={$dbScheme};charset=utf8mb4", $dbUser, $dbPass, array(
PDONative::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4',
PDONative::ATTR_TIMEOUT => 3, // Seconds
PDONative::ATTR_PERSISTENT => true
));
// Connection settings
$pdo->setAttribute(PDONative::ATTR_DEFAULT_FETCH_MODE, PDONative::FETCH_ASSOC); // Return arrays
$pdo->setAttribute(PDONative::ATTR_ERRMODE, PDONative::ERRMODE_EXCEPTION); // Handle all errors with exceptions
$pool = new PDOPool((new PDOConfig())
->withHost($dbHost)
->withPort($dbPort)
->withDbName($dbScheme)
->withCharset('utf8mb4')
->withUsername($dbUser)
->withPassword($dbPass)
, 16);
return $pdo;
return $pool;
});
$register->set('redisPool', function () {
$redisHost = App::getEnv('_APP_REDIS_HOST', '');
$redisPort = App::getEnv('_APP_REDIS_PORT', '');
$redisUser = App::getEnv('_APP_REDIS_USER', '');
$redisPass = App::getEnv('_APP_REDIS_PASS', '');
$redisAuth = '';
if ($redisUser && $redisPass) {
$redisAuth = $redisUser.':'.$redisPass;
}
$pool = new RedisPool((new RedisConfig)
->withHost($redisHost)
->withPort($redisPort)
->withAuth($redisAuth)
->withDbIndex(0)
, 16);
return $pool;
});
$register->set('influxdb', function () { // Register DB connection
$host = App::getEnv('_APP_INFLUXDB_HOST', '');
@@ -185,25 +214,6 @@ $register->set('statsd', function () { // Register DB connection
return $statsd;
});
$register->set('cache', function () { // Register cache connection
$redis = new Redis();
$redis->pconnect(App::getEnv('_APP_REDIS_HOST', ''), App::getEnv('_APP_REDIS_PORT', ''));
$user = App::getEnv('_APP_REDIS_USER','');
$pass = App::getEnv('_APP_REDIS_PASS','');
$auth = [];
if(!empty($user)) {
$auth["user"] = $user;
}
if(!empty($pass)) {
$auth["pass"] = $pass;
}
if(!empty($auth)) {
$redis->auth($auth);
}
$redis->setOption(Redis::OPT_READ_TIMEOUT, -1);
return $redis;
});
$register->set('smtp', function () {
$mail = new PHPMailer(true);
@@ -233,7 +243,7 @@ $register->set('smtp', function () {
return $mail;
});
$register->set('geodb', function () {
return new Reader(__DIR__.'/db/DBIP/dbip-country-lite-2021-02.mmdb');
return new Reader(__DIR__.'/db/DBIP/dbip-country-lite-2021-06.mmdb');
});
/*
@@ -387,7 +397,7 @@ App::setResource('user', function($mode, $project, $console, $request, $response
/** @var Appwrite\Database\Document $project */
/** @var Appwrite\Database\Database $consoleDB */
/** @var Appwrite\Database\Database $projectDB */
/** @var bool $mode */
/** @var string $mode */
Authorization::setDefaultStatus(true);
@@ -457,7 +467,7 @@ App::setResource('user', function($mode, $project, $console, $request, $response
$user = $projectDB->getDocument($jwtUserId);
}
if (empty($user->search('$id', $jwtSessionId, $user->getAttribute('tokens')))) { // Match JWT to active token
if (empty($user->search('$id', $jwtSessionId, $user->getAttribute('sessions')))) { // Match JWT to active token
$user = new Document(['$id' => '', '$collection' => Database::SYSTEM_COLLECTION_USERS]);
}
}
@@ -483,23 +493,23 @@ App::setResource('console', function($consoleDB) {
return $consoleDB->getDocument('console');
}, ['consoleDB']);
App::setResource('consoleDB', function($register) {
App::setResource('consoleDB', function($db, $cache) {
$consoleDB = new Database();
$consoleDB->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register));
$consoleDB->setAdapter(new RedisAdapter(new MySQLAdapter($db, $cache), $cache));
$consoleDB->setNamespace('app_console'); // Should be replaced with param if we want to have parent projects
$consoleDB->setMocks(Config::getParam('collections', []));
return $consoleDB;
}, ['register']);
}, ['db', 'cache']);
App::setResource('projectDB', function($register, $project) {
App::setResource('projectDB', function($db, $cache, $project) {
$projectDB = new Database();
$projectDB->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register));
$projectDB->setAdapter(new RedisAdapter(new MySQLAdapter($db, $cache), $cache));
$projectDB->setNamespace('app_'.$project->getId());
$projectDB->setMocks(Config::getParam('collections', []));
return $projectDB;
}, ['register', 'project']);
}, ['db', 'cache', 'project']);
App::setResource('mode', function($request) {
/** @var Utopia\Swoole\Request $request */
+2 -2
View File
@@ -129,7 +129,7 @@ $cli
$httpsPort = Console::confirm('Choose your server HTTPS port: (default: '.$defaultHTTPSPort.')');
$httpsPort = ($httpsPort) ? $httpsPort : $defaultHTTPSPort;
}
$input = [];
foreach($vars as $key => $var) {
@@ -196,7 +196,7 @@ $cli
foreach ($input as $key => $value) {
if($value) {
$env .= $key.'='.$value.' ';
$env .= $key.'='.\escapeshellarg($value).' ';
}
}
+17 -6
View File
@@ -8,22 +8,32 @@ use Appwrite\Database\Database;
use Appwrite\Database\Validator\Authorization;
use Appwrite\Database\Adapter\MySQL as MySQLAdapter;
use Appwrite\Database\Adapter\Redis as RedisAdapter;
use Appwrite\Migration\Version;
use Appwrite\Migration\Migration;
use Utopia\Validator\Text;
$cli
->task('migrate')
->action(function () use ($register) {
Console::success('Starting Data Migration');
->param('version', APP_VERSION_STABLE, new Text(8), 'Version to migrate to.', true)
->action(function ($version) use ($register) {
if (!array_key_exists($version, Migration::$versions)) {
Console::error("Version {$version} not found.");
Console::exit(1);
return;
}
Console::success('Starting Data Migration to version '.$version);
$db = $register->get('db', true);
$cache = $register->get('cache', true);
$consoleDB = new Database();
$consoleDB
->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register))
->setAdapter(new RedisAdapter(new MySQLAdapter($db, $cache), $cache))
->setNamespace('app_console') // Main DB
->setMocks(Config::getParam('collections', []));
$projectDB = new Database();
$projectDB
->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register))
->setAdapter(new RedisAdapter(new MySQLAdapter($db, $cache), $cache))
->setMocks(Config::getParam('collections', []));
$console = $consoleDB->getDocument('console');
@@ -36,7 +46,8 @@ $cli
$projects = [$console];
$count = 0;
$migration = new Version\V07($register->get('db')); //TODO: remove hardcoded version and move to dynamic migration
$class = 'Appwrite\\Migration\\Version\\'.Migration::$versions[$version];
$migration = new $class($register->get('db'));
while ($sum > 0) {
foreach ($projects as $project) {
+23 -15
View File
@@ -15,7 +15,8 @@ use Appwrite\SDK\Language\Deno;
use Appwrite\SDK\Language\DotNet;
use Appwrite\SDK\Language\Flutter;
use Appwrite\SDK\Language\Go;
use Appwrite\SDK\Language\Java;
use Appwrite\SDK\Language\Kotlin;
use Appwrite\SDK\Language\Android;
use Appwrite\SDK\Language\Swift;
$cli
@@ -28,7 +29,7 @@ $cli
$production = ($git) ? (Console::confirm('Type "Appwrite" to push code to production git repos') == 'Appwrite') : false;
$message = ($git) ? Console::confirm('Please enter your commit message:') : '';
if(!in_array($version, ['0.6.x', '0.7.x', '0.8.x'])) {
if(!in_array($version, ['0.6.x', '0.7.x', '0.8.x', '0.9.x'])) {
throw new Exception('Unknown version given');
}
@@ -134,9 +135,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
case 'go':
$config = new Go();
break;
case 'java':
$config = new Java();
break;
case 'swift':
$config = new Swift();
break;
@@ -144,6 +142,13 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
$cover = '';
$config = new DotNet();
break;
case 'android':
$config = new Android();
break;
case 'kotlin':
$config = new Kotlin();
$warning = $warning."\n\n > This is the Kotlin SDK for integrating with Appwrite from your Kotlin server-side code. If you're looking for the Android SDK you should check [appwrite/sdk-for-android](https://github.com/appwrite/sdk-for-android)";
break;
default:
throw new Exception('Language "'.$language['key'].'" not supported');
break;
@@ -155,9 +160,8 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
$sdk
->setName($language['name'])
->setDescription("Appwrite is an open-source backend as a service server that abstract and simplify complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way.
Use the {$language['name']} SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools.
For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)")
->setNamespace('io appwrite')
->setDescription("Appwrite is an open-source backend as a service server that abstract and simplify complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the {$language['name']} SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)")
->setShortDescription('Appwrite is an open-source self-hosted backend server that abstract and simplify complex and repetitive development tasks behind a very simple REST API')
->setLicense($license)
->setLicenseContent($licenseContent)
@@ -180,7 +184,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
->setTwitter(APP_SOCIAL_TWITTER_HANDLE)
->setDiscord(APP_SOCIAL_DISCORD_CHANNEL, APP_SOCIAL_DISCORD)
->setDefaultHeaders([
'X-Appwrite-Response-Format' => '0.8.0',
'X-Appwrite-Response-Format' => '0.9.0',
])
;
@@ -202,7 +206,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
\exec('rm -rf '.$target.' && \
mkdir -p '.$target.' && \
cd '.$target.' && \
git init && \
git init --initial-branch=master && \
git remote add origin '.$gitUrl.' && \
git fetch && \
git pull '.$gitUrl.' && \
@@ -219,11 +223,15 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
Console::success("Remove temp directory '{$target}' for {$language['name']} SDK");
}
\exec('mkdir -p '.$resultExamples.' && cp -r '.$result.'/docs/examples '.$resultExamples);
Console::success("Copied code examples for {$language['name']} SDK to: {$resultExamples}");
\exec('rm -rf '.$result);
Console::success("Removed source code directory '{$result}' for {$language['name']} SDK");
$docDirectories = $language['docDirectories'] ?? [''];
foreach ($docDirectories as $languageTitle => $path) {
$languagePath = strtolower($languageTitle !== 0 ? '/'.$languageTitle : '');
\exec(
'mkdir -p '.$resultExamples.$languagePath.' && \
cp -r '.$result.'/docs/examples'.$languagePath.' '.$resultExamples
);
Console::success("Copied code examples for {$language['name']} SDK to: {$resultExamples}");
}
}
}
+2 -1
View File
@@ -99,7 +99,8 @@
<input type="hidden" id="collection-read" name="read" required data-cast-to="json" value="<?php echo htmlentities(json_encode([])); ?>" />
<input type="hidden" id="collection-write" name="write" required data-cast-to="json" value="<?php echo htmlentities(json_encode([])); ?>" />
<input type="hidden" id="collection-rules" name="rules" required data-cast-to="json" value="{}" />
<hr />
<button type="submit">Create</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
+3 -3
View File
@@ -46,9 +46,9 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled',true);
<div class="box margin-bottom-large">
<div class="text-align-center">
<img src="" data-ls-attrs="src=/images/runtimes/{{project-function.env|envLogo}}" alt="Function Env." class="avatar huge margin-top-negative-xxl" />
<img src="" data-ls-attrs="src=/images/runtimes/{{project-function.runtime|runtimeLogo}}" alt="Function Runtime" class="avatar huge margin-top-negative-xxl" />
<p class="text-fade margin-bottom-small" data-ls-bind="{{project-function.env|envName}} {{project-function.env|envVersion}}">
<p class="text-fade margin-bottom-small" data-ls-bind="{{project-function.runtime|runtimeName}} {{project-function.runtime|runtimeVersion}}">
</p>
<div data-ls-if="{{project-function.tag}} !== ''" class="margin-top">
<button data-ls-ui-trigger="execute-now">Execute Now</button> &nbsp; <a data-ls-attrs="href=/console/functions/function/logs?id={{router.params.id}}&project={{router.params.project}}" class="button reverse" style="vertical-align: top;">View Logs</a>
@@ -612,7 +612,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled',true);
--code='/myrepo/myfunction'" data-forms-code="powershell" data-lang="powershell" data-lang-label="PowerShell"></textarea>
</div>
<p>Learn more about <a href="" target="_blank">creating tags</a>, installing and using the <a href="" target="_blank">Appwrite CLI</a>.</p>
<p>Learn more about <a href="https://appwrite.io/docs/server/functions#functionsCreateTag" target="_blank">creating tags</a>, installing and using the <a href="https://appwrite.io/docs/command-line" target="_blank">Appwrite CLI</a>.</p>
</li>
<li>
<h2 style="display: none">Manual</h2>
+6 -4
View File
@@ -40,14 +40,14 @@ $runtimes = $this->getParam('runtimes', []);
<ul data-ls-loop="project-functions.functions" data-ls-as="function" class="list">
<li class="clear">
<div class="pull-start margin-end avatar-container">
<img src="" data-ls-attrs="src=/images/runtimes/{{function.env|envLogo}}?v=<?php echo APP_CACHE_BUSTER; ?>" alt="Function Env." class="avatar" loading="lazy" width="60" height="60" />
<img src="" data-ls-attrs="src=/images/runtimes/{{function.runtime|runtimeLogo}}?v=<?php echo APP_CACHE_BUSTER; ?>" alt="Function Runtime" class="avatar" loading="lazy" width="60" height="60" />
</div>
<a data-ls-attrs="href=/console/functions/function?id={{function.$id}}&project={{router.params.project}}" class="button pull-end">Settings</a>
<span data-ls-bind="{{function.name}}"></span>
<p class="text-fade margin-bottom-no" data-ls-bind="{{function.env|envName}} {{function.env|envVersion}}"></p>
<p class="text-fade margin-bottom-no" data-ls-bind="{{function.runtime|runtimeName}} {{function.runtime|runtimeVersion}}"></p>
</li>
</ul>
</div>
@@ -109,13 +109,15 @@ $runtimes = $this->getParam('runtimes', []);
<label for="name">Name</label>
<input type="text" id="name" name="name" required autocomplete="off" class="margin-bottom" maxlength="128" />
<label for="env">Runtimes</label>
<select name="env" id="env" required class="margin-bottom-xl">
<label for="runtime">Runtimes</label>
<select name="runtime" id="runtime" required class="margin-bottom-xl">
<?php foreach($runtimes as $key => $runtime): ?>
<option value="<?php echo $this->escape($key); ?>"><?php echo $this->escape($runtime['name']); ?> <?php echo $this->escape($runtime['version']); ?></option>
<?php endforeach; ?>
</select>
<input id="execute" name="execute" value="" hidden/>
<footer>
<button type="submit">Create</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</footer>
+154 -6
View File
@@ -79,6 +79,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled',true);
<div
data-service="projects.getUsage"
data-event="load"
data-scope="console"
data-name="usage"
data-param-project-id="{{router.params.project}}"
data-param-range="30d">
@@ -184,11 +185,23 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled',true);
<img src="" data-ls-attrs="src=/images/clients/{{platform.type}}.png?v=<?php echo APP_CACHE_BUSTER; ?>" alt="Platform Logo" class="avatar" loading="lazy" width="60" height="60" />
<div data-ls-if="{{platform.type}} === 'flutter-ios'" class="corner">
<img src="" data-ls-attrs="src=/images/clients/ios.png?v=<?php echo APP_CACHE_BUSTER; ?>" alt="iOS Logo" class="avatar xs" loading="lazy" width="30" height="30" />
<img src="" data-ls-attrs="src=/images/clients/flutter.png?v=<?php echo APP_CACHE_BUSTER; ?>" alt="iOS Logo" class="avatar xs" loading="lazy" width="30" height="30" />
</div>
<div data-ls-if="{{platform.type}} === 'flutter-android'" class="corner">
<img src="" data-ls-attrs="src=/images/clients/android.png?v=<?php echo APP_CACHE_BUSTER; ?>" alt="Android Logo" class="avatar xs" loading="lazy" width="30" height="30" />
<img src="" data-ls-attrs="src=/images/clients/flutter.png?v=<?php echo APP_CACHE_BUSTER; ?>" alt="Android Logo" class="avatar xs" loading="lazy" width="30" height="30" />
</div>
<div data-ls-if="{{platform.type}} === 'flutter-linux'" class="corner">
<img src="" data-ls-attrs="src=/images/clients/flutter.png?v=<?php echo APP_CACHE_BUSTER; ?>" alt="Linux Logo" class="avatar xs" loading="lazy" width="30" height="30" />
</div>
<div data-ls-if="{{platform.type}} === 'flutter-macos'" class="corner">
<img src="" data-ls-attrs="src=/images/clients/flutter.png?v=<?php echo APP_CACHE_BUSTER; ?>" alt="MacOS Logo" class="avatar xs" loading="lazy" width="30" height="30" />
</div>
<div data-ls-if="{{platform.type}} === 'flutter-windows'" class="corner">
<img src="" data-ls-attrs="src=/images/clients/flutter.png?v=<?php echo APP_CACHE_BUSTER; ?>" alt="Windows Logo" class="avatar xs" loading="lazy" width="30" height="30" />
</div>
</div>
<span class="text-one-liner" data-ls-bind="{{platform.name}}"></span>
@@ -228,11 +241,11 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled',true);
<li>
<div class="link flutter-new"><img src="/images/clients/flutter.png?v=<?php echo APP_CACHE_BUSTER; ?>" alt="Flutter Platform Logo" class="avatar xxs margin-end-small" loading="lazy" /> New Flutter App &nbsp;<span class="text-size-tiny">(beta)</span></div>
</li>
<li class="disabled">
<div class="link ios-new"><img src="/images/clients/ios.png?v=<?php echo APP_CACHE_BUSTER; ?>" alt="iOS Platform Logo" class="avatar xxs margin-end-small" loading="lazy" /> New iOS App <span class="text-fade text-size-small">(soon)</span></div>
<li>
<div class="link android-new"><img src="/images/clients/android.png?v=<?php echo APP_CACHE_BUSTER; ?>" alt="Android Platform Logo" class="avatar xxs margin-end-small" loading="lazy" /> New Android App</div>
</li>
<li class="disabled">
<div class="link android-new"><img src="/images/clients/android.png?v=<?php echo APP_CACHE_BUSTER; ?>" alt="Android Platform Logo" class="avatar xxs margin-end-small" loading="lazy" /> New Android App <span class="text-fade text-size-small">(soon)</span></div>
<div class="link ios-new"><img src="/images/clients/ios.png?v=<?php echo APP_CACHE_BUSTER; ?>" alt="iOS Platform Logo" class="avatar xxs margin-end-small" loading="lazy" /> New iOS App <span class="text-fade text-size-small">(soon)</span></div>
</li>
<li class="disabled">
<div class="link unity-new"><img src="/images/clients/unity.png?v=<?php echo APP_CACHE_BUSTER; ?>" alt="Unity Platform Logo" class="avatar xxs margin-end-small" loading="lazy" /> New Unity Game <span class="text-fade text-size-small">(soon)</span></div>
@@ -317,7 +330,43 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled',true);
</form>
</script>
<div data-ui-modal class="modal box close" data-button-alias=".flutter-new">
<div data-ui-modal class="modal box close" data-button-alias=".android-new">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h1>Register your Android App</h1>
<form
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Create Project Platform (Android)"
data-service="projects.createPlatform"
data-scope="console"
data-event="submit"
data-success="alert,trigger,reset"
data-success-param-alert-text="Registered new platform successfully"
data-success-param-trigger-events="projects.createPlatform"
data-failure="alert"
data-failure-param-alert-text="Failed to register platform"
data-failure-param-alert-classname="error">
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
<input type="hidden" name="type" data-ls-bind="android" />
<label for="name">Name <span class="tooltip large" data-tooltip="Choose any name that will help you distinguish between your different apps."><i class="icon-question"></i></span></label>
<input type="text" class="full-width" name="name" required autocomplete="off" placeholder="My Android App" maxlength="128" />
<label for="key">Package Name <span class="tooltip large" data-tooltip="Your package name is generally the applicationId in your app-level build.gradle file."><i class="icon-question"></i></span></label>
<input type="text" class="full-width" name="key" required autocomplete="off" placeholder="com.company.appname" />
<hr />
<button type="submit">Register</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Back</button>
</form>
</div>
<div data-ui-modal class="modal box close width-large" data-button-alias=".flutter-new">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h1 class="margin-bottom-xl">Register your Flutter App</h1>
@@ -387,6 +436,105 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled',true);
<hr />
<button type="submit">Register</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Back</button>
</form>
</li>
<li>
<h2 style="display: none">&nbsp;&nbsp;Linux&nbsp;&nbsp;</h2>
<form
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Create Project Platform (Flutter / Linux)"
data-service="projects.createPlatform"
data-scope="console"
data-event="submit"
data-success="alert,trigger,reset"
data-success-param-alert-text="Registered new platform successfully"
data-success-param-trigger-events="projects.createPlatform"
data-failure="alert"
data-failure-param-alert-text="Failed to register platform"
data-failure-param-alert-classname="error">
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
<input type="hidden" name="type" data-ls-bind="flutter-linux" />
<label for="name">Name <span class="tooltip large" data-tooltip="Choose any name that will help you distinguish between your different apps."><i class="icon-question"></i></span></label>
<input type="text" class="full-width" name="name" required autocomplete="off" placeholder="My Linux App" maxlength="128" />
<label for="key">Package Name <span class="tooltip large" data-tooltip="Your application name"><i class="icon-question"></i></span></label>
<input type="text" class="full-width" name="key" required autocomplete="off" placeholder="appname" />
<hr />
<button type="submit">Register</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Back</button>
</form>
</li>
<li>
<h2 style="display: none">&nbsp;&nbsp;MacOS&nbsp;&nbsp;</h2>
<form
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Create Project Platform (Flutter / Mac OS)"
data-service="projects.createPlatform"
data-scope="console"
data-event="submit"
data-success="alert,trigger,reset"
data-success-param-alert-text="Registered new platform successfully"
data-success-param-trigger-events="projects.createPlatform"
data-failure="alert"
data-failure-param-alert-text="Failed to register platform"
data-failure-param-alert-classname="error">
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
<input type="hidden" name="type" data-ls-bind="flutter-macos" />
<label for="name">Name <span class="tooltip large" data-tooltip="Choose any name that will help you distinguish between your different apps."><i class="icon-question"></i></span></label>
<input type="text" class="full-width" name="name" required autocomplete="off" placeholder="My Mac OS App" maxlength="128" />
<label for="key">Bundle ID <span class="tooltip large" data-tooltip="You can find your Bundle Identifier in the General tab for your app's primary target in Xcode."><i class="icon-question"></i></span></label>
<input type="text" class="full-width" name="key" required autocomplete="off" placeholder="com.company.appname" />
<hr />
<button type="submit">Register</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Back</button>
</form>
</li>
<li>
<h2 style="display: none">&nbsp;&nbsp;Windows&nbsp;&nbsp;</h2>
<form
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Create Project Platform (Flutter / Windows)"
data-service="projects.createPlatform"
data-scope="console"
data-event="submit"
data-success="alert,trigger,reset"
data-success-param-alert-text="Registered new platform successfully"
data-success-param-trigger-events="projects.createPlatform"
data-failure="alert"
data-failure-param-alert-text="Failed to register platform"
data-failure-param-alert-classname="error">
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
<input type="hidden" name="type" data-ls-bind="flutter-windows" />
<label for="name">Name <span class="tooltip large" data-tooltip="Choose any name that will help you distinguish between your different apps."><i class="icon-question"></i></span></label>
<input type="text" class="full-width" name="name" required autocomplete="off" placeholder="My Windows App" maxlength="128" />
<label for="key">Package Name <span class="tooltip large" data-tooltip="Your application name"><i class="icon-question"></i></span></label>
<input type="text" class="full-width" name="key" required autocomplete="off" placeholder="appname" />
<hr />
<button type="submit">Register</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Back</button>
</form>
</li>
+2 -2
View File
@@ -77,8 +77,8 @@ $auth = $this->getParam('auth', []);
<td data-title="Name: ">
<a data-ls-attrs="href=/console/users/user?id={{user.$id}}&project={{router.params.project}}">
<span data-ls-bind="{{user.name}}"></span>
<span data-ls-if="{{user.name|escape}} === ''">-----</span>
<span data-ls-if="{{user.email}} === ''">Anonymous User</span>
<span data-ls-if="{{user.name|escape}} === '' && {{user.email}} !== ''">Unknown</span>
<span data-ls-if="{{user.name|escape}} === '' && {{user.email}} === ''">Anonymous User</span>
</a>
</td>
<td data-title="Email: ">
+1 -1
View File
@@ -12,7 +12,7 @@
<br />
<span data-ls-bind="{{team.name}}">&nbsp;</span>
<span data-ls-if="{{team.name}} === ''">Unknown</span>
<span data-ls-if="{{team.name|escape}} === ''">Unknown</span>
</h1>
</div>
+7 -7
View File
@@ -12,8 +12,8 @@
<br />
<span data-ls-bind="{{user.name}}">&nbsp;</span>
<span data-ls-if="{{user.name}} === '' && {{user.email}} !== ''">Unknown</span>
<span data-ls-if="{{user.name}} === '' && {{user.email}} === ''">Anonymous User</span>
<span data-ls-if="{{user.name|escape}} === '' && {{user.email}} !== ''">Unknown</span>
<span data-ls-if="{{user.name|escape}} === '' && {{user.email}} === ''">Anonymous User</span>
</h1>
</div>
@@ -97,7 +97,7 @@
<h3 class="text-danger">Danger Zone</h3>
<div class="box danger">
<div class="box danger margin-bottom">
<p>This is the area where you can delete this user.</p>
<p>By deleting this user you will lose all data associated with this user.</p>
@@ -218,7 +218,7 @@
<button class="danger">Logout</button>
</form>
<div class="pull-start margin-end avatar-container">
<img onerror="this.onerror=null;this.src='/images/unknown.svg'" data-ls-attrs="src={{env.API}}/avatars/browsers/{{session.clientCode|lowercase}}?width=60&height=60&project={{env.PROJECT}},title={{session.clientName}},alt={{session.clientName}}" class="avatar" loading="lazy" width="60" height="60" />
<img onerror="this.onerror=null;this.src='/images/unknown.svg'" data-ls-attrs="src={{env.API}}/avatars/browsers/{{session.clientCode|lowercase}}?width=120&height=120&project={{env.PROJECT}},title={{session.clientName}},alt={{session.clientName}}" class="avatar" loading="lazy" width="60" height="60" />
<div data-ls-if="{{session.provider}} !== 'email'" class="corner">
<img data-ls-attrs="src=/images/users/{{session.provider}}.png?buster=<?php echo APP_CACHE_BUSTER; ?>,title={{session.provider}},alt={{session.provider}}" class="avatar xs" loading="lazy" width="30" height="30" />
@@ -228,7 +228,7 @@
<span data-ls-bind="{{session.clientName}}"></span> <span data-ls-bind="{{session.clientVersion}}"></span> on <span data-ls-bind="{{session.deviceModel}}"></span> <span data-ls-bind="{{session.osName}}"></span> <span data-ls-bind="{{session.osVersion}}"></span>
<div class="margin-top-small">
<img onerror="this.onerror=null;this.src='/images/unknown.svg'" data-ls-if="{{session.countryCode}} !== '--'" data-ls-attrs="src={{env.API}}/avatars/flags/{{session.countryCode}}?width=80&height=80&project={{env.PROJECT}}" class="avatar xxs margin-end-small inline" />
<img onerror="this.onerror=null;this.src='/images/unknown.svg'" data-ls-if="{{session.countryCode}} !== '--'" data-ls-attrs="src={{env.API}}/avatars/flags/{{session.countryCode}}?width=120&height=120&project={{env.PROJECT}}" class="avatar xxs margin-end-small inline" />
<small data-ls-bind="{{session.ip}}"></small> / <small data-ls-bind="{{session.countryName}}"></small>
</div>
</li>
@@ -265,11 +265,11 @@
data-param-user-id="{{router.params.id}}"
data-event="load,logs-load">
<div data-ls-if="{{logs.length}} === 0" style="display: none" class="margin-top-xxl margin-bottom-xxl text-align-center">
<div data-ls-if="{{logs.logs.length}} === 0" style="display: none" class="margin-top-xxl margin-bottom-xxl text-align-center">
No logs available.
</div>
<div class="box" data-ls-if="{{logs.length}} !== 0" style="display: none">
<div class="box" data-ls-if="{{logs.logs.length}} !== 0" style="display: none">
<table class="vertical small">
<thead>
<tr>
+5 -2
View File
@@ -342,7 +342,7 @@ services:
- MYSQL_DATABASE=${_APP_DB_SCHEMA}
- MYSQL_USER=${_APP_DB_USER}
- MYSQL_PASSWORD=${_APP_DB_PASS}
command: 'mysqld --innodb-flush-method=fsync'
command: 'mysqld --innodb-flush-method=fsync --wait_timeout=86400'
redis:
image: redis:6.0-alpine3.12
@@ -372,11 +372,14 @@ services:
- appwrite-influxdb:/var/lib/influxdb:rw
telegraf:
image: appwrite/telegraf:1.0.0
image: appwrite/telegraf:1.2.0
container_name: appwrite-telegraf
restart: unless-stopped
networks:
- appwrite
environment:
- _APP_INFLUXDB_HOST
- _APP_INFLUXDB_PORT
networks:
gateway:
+12 -12
View File
@@ -43,7 +43,7 @@ if(!empty($platforms)) {
<link rel="apple-touch-icon" href="/images/apple.png">
<!-- <link rel="preconnect" href="" /> -->
<?php if (!empty($canonical)): ?>
<link rel="canonical" href="<?php echo $canonical; ?>" />
<link rel="canonical" href="<?php echo $this->escape($canonical); ?>" />
<?php endif; ?>
<?php foreach ($this->getParam('prefetch', []) as $prefetch): ?>
<link rel="prefetch" href="<?php echo $this->escape($prefetch); ?>" />
@@ -52,12 +52,12 @@ if(!empty($platforms)) {
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5" />
<meta name="theme-color" content="#24f4d4">
<meta property="og:type" content="website" />
<meta property="og:title" content="<?php echo $this->getParam('title', ''); ?>" />
<meta property="og:description" content="<?php echo $this->getParam('description', ''); ?>" />
<meta property="og:title" content="<?php echo $this->escape($this->getParam('title', '')); ?>" />
<meta property="og:description" content="<?php echo $this->escape($this->getParam('description', '')); ?>" />
<?php if (!empty($canonical)): ?>
<meta property="og:url" content="<?php echo $canonical; ?>" />
<meta property="og:url" content="<?php echo $this->escape($canonical); ?>" />
<?php endif; ?>
<meta property="og:image" content="<?php echo $endpoint; ?>/images/logo.png?v=<?php echo APP_CACHE_BUSTER; ?>" />
<meta property="og:image" content="<?php echo $this->escape($endpoint); ?>/images/logo.png?v=<?php echo APP_CACHE_BUSTER; ?>" />
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
@@ -69,11 +69,11 @@ if(!empty($platforms)) {
var APP_ENV = {
NAME: '<?php echo APP_NAME; ?>',
VERSION: '<?php echo $version; ?>',
CACHEBUSTER: '<?php echo $version; ?>/<?php echo APP_CACHE_BUSTER; ?>',
PROTOCOL: '<?php echo $protocol; ?>',
ENDPOINT: '<?php echo $endpoint; ?>',
DOMAIN: '<?php echo $domain; ?>',
VERSION: '<?php echo $this->escape($version); ?>',
CACHEBUSTER: '<?php echo $this->escape($version); ?>/<?php echo APP_CACHE_BUSTER; ?>',
PROTOCOL: '<?php echo $this->escape($protocol); ?>',
ENDPOINT: '<?php echo $this->escape($endpoint); ?>',
DOMAIN: '<?php echo $this->escape($domain); ?>',
HOME: '<?php echo $this->escape($this->getParam('home')); ?>',
SETUP: '<?php echo $this->escape($this->getParam('setup')); ?>',
API: '/v1',
@@ -93,7 +93,7 @@ if(!empty($platforms)) {
script.type = 'text/javascript';
script.async = true;
script.src = '/dist/scripts/app-all.js?v=<?php echo APP_CACHE_BUSTER; ?>.<?php echo $version; ?>';
script.src = '/dist/scripts/app-all.js?v=<?php echo APP_CACHE_BUSTER; ?>.<?php echo $this->escape($version); ?>';
script.onload = function() {
window.ls.run(window);
};
@@ -142,6 +142,6 @@ if(!empty($platforms)) {
<?php echo $this->exec($this->getParam('footer', [])); ?>
<!-- Version <?php echo $version; ?> -->
<!-- Version <?php echo $this->escape($version); ?> -->
</body>
</html>
+32
View File
@@ -0,0 +1,32 @@
<?php
use Appwrite\Extend\PDO;
use Utopia\App;
/** @var Utopia\Registry\Registry $register */
require_once __DIR__.'/init.php';
$register->set('db', function () {
$dbHost = App::getEnv('_APP_DB_HOST', '');
$dbUser = App::getEnv('_APP_DB_USER', '');
$dbPass = App::getEnv('_APP_DB_PASS', '');
$dbScheme = App::getEnv('_APP_DB_SCHEMA', '');
$pdo = new PDO("mysql:host={$dbHost};dbname={$dbScheme};charset=utf8mb4", $dbUser, $dbPass, array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4',
PDO::ATTR_TIMEOUT => 3, // Seconds
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
));
return $pdo;
});
$register->set('cache', function () { // Register cache connection
$redis = new Redis();
$redis->pconnect(App::getEnv('_APP_REDIS_HOST', ''), App::getEnv('_APP_REDIS_PORT', ''));
$redis->setOption(Redis::OPT_READ_TIMEOUT, -1);
return $redis;
});
+7 -7
View File
@@ -1,24 +1,24 @@
<?php
use Appwrite\Resque\Worker;
use Utopia\Audit\Audit;
use Utopia\Audit\Adapters\MySQL as AuditAdapter;
use Utopia\CLI\Console;
require_once __DIR__.'/../init.php';
require_once __DIR__.'/../workers.php';
Console::title('Audits V1 Worker');
Console::success(APP_NAME.' audits worker v1 has started');
class AuditsV1
class AuditsV1 extends Worker
{
public $args = [];
public function setUp(): void
public function init(): void
{
}
public function perform()
public function run(): void
{
global $register;
@@ -39,8 +39,8 @@ class AuditsV1
$audit->log($userId, $event, $resource, $userAgent, $ip, '', $data);
}
public function tearDown(): void
public function shutdown(): void
{
// ... Remove environment for this job
}
}
}
+15 -13
View File
@@ -1,35 +1,38 @@
<?php
use Utopia\App;
use Utopia\CLI\Console;
use Utopia\Config\Config;
use Utopia\Domains\Domain;
use Appwrite\Database\Database;
use Appwrite\Database\Adapter\MySQL as MySQLAdapter;
use Appwrite\Database\Adapter\Redis as RedisAdapter;
use Appwrite\Database\Validator\Authorization;
use Appwrite\Network\Validator\CNAME;
use Appwrite\Resque\Worker;
use Utopia\App;
use Utopia\CLI\Console;
use Utopia\Config\Config;
use Utopia\Domains\Domain;
require_once __DIR__.'/../init.php';
require_once __DIR__.'/../workers.php';
Console::title('Certificates V1 Worker');
Console::success(APP_NAME.' certificates worker v1 has started');
class CertificatesV1
class CertificatesV1 extends Worker
{
public $args = [];
public function setUp(): void
public function init(): void
{
}
public function perform()
public function run(): void
{
global $register;
$db = $register->get('db');
$cache = $register->get('cache');
$consoleDB = new Database();
$consoleDB->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register));
$consoleDB->setAdapter(new RedisAdapter(new MySQLAdapter($db, $cache), $cache));
$consoleDB->setNamespace('app_console'); // Main DB
$consoleDB->setMocks(Config::getParam('collections', []));
@@ -204,8 +207,7 @@ class CertificatesV1
Authorization::reset();
}
public function tearDown(): void
public function shutdown(): void
{
// ... Remove environment for this job
}
}
}
+42 -20
View File
@@ -5,6 +5,7 @@ use Appwrite\Database\Adapter\MySQL as MySQLAdapter;
use Appwrite\Database\Adapter\Redis as RedisAdapter;
use Appwrite\Database\Document;
use Appwrite\Database\Validator\Authorization;
use Appwrite\Resque\Worker;
use Utopia\Storage\Device\Local;
use Utopia\Abuse\Abuse;
use Utopia\Abuse\Adapters\TimeLimit;
@@ -13,26 +14,24 @@ use Utopia\Config\Config;
use Utopia\Audit\Audit;
use Utopia\Audit\Adapters\MySQL as AuditAdapter;
require_once __DIR__.'/../init.php';
require_once __DIR__.'/../workers.php';
Console::title('Deletes V1 Worker');
Console::success(APP_NAME.' deletes worker v1 has started'."\n");
class DeletesV1
class DeletesV1 extends Worker
{
public $args = [];
protected $consoleDB = null;
public function setUp(): void
public function init(): void
{
}
public function perform()
public function run(): void
{
$projectId = $this->args['projectId'];
$projectId = isset($this->args['projectId']) ? $this->args['projectId'] : '';
$type = $this->args['type'];
switch (strval($type)) {
@@ -52,6 +51,9 @@ class DeletesV1
case Database::SYSTEM_COLLECTION_COLLECTIONS:
$this->deleteDocuments($document, $projectId);
break;
case Database::SYSTEM_COLLECTION_TEAMS:
$this->deleteMemberships($document, $projectId);
break;
default:
Console::error('No lazy delete operation available for document of type: '.$document->getCollection());
break;
@@ -82,9 +84,8 @@ class DeletesV1
}
}
public function tearDown(): void
public function shutdown(): void
{
// ... Remove environment for this job
}
protected function deleteDocuments(Document $document, $projectId)
@@ -97,6 +98,14 @@ class DeletesV1
], $this->getProjectDB($projectId));
}
protected function deleteMemberships(Document $document, $projectId) {
// Delete Memberships
$this->deleteByGroup([
'$collection='.Database::SYSTEM_COLLECTION_MEMBERSHIPS,
'teamId='.$document->getId(),
], $this->getProjectDB($projectId));
}
protected function deleteProject(Document $document)
{
// Delete all DBs
@@ -127,11 +136,22 @@ class DeletesV1
}
}
// Delete Memberships
// Delete Memberships and decrement team membership counts
$this->deleteByGroup([
'$collection='.Database::SYSTEM_COLLECTION_MEMBERSHIPS,
'userId='.$document->getId(),
], $this->getProjectDB($projectId));
], $this->getProjectDB($projectId), function(Document $document) use ($projectId) {
if ($document->getAttribute('confirm')) { // Count only confirmed members
$teamId = $document->getAttribute('teamId');
$team = $this->getProjectDB($projectId)->getDocument($teamId);
if(!$team->isEmpty()) {
$team = $this->getProjectDB($projectId)->updateDocument(\array_merge($team->getArrayCopy(), [
'sum' => \max($team->getAttribute('sum', 0) - 1, 0), // Ensure that sum >= 0
]));
}
}
});
}
protected function deleteExecutionLogs($timestamp)
@@ -156,9 +176,7 @@ class DeletesV1
throw new Exception('Failed to delete audit logs. No timestamp provided');
}
$timeLimit = new TimeLimit("", 0, 1, function () use ($register) {
return $register->get('db');
});
$timeLimit = new TimeLimit("", 0, 1, $register->get('db'));
$this->deleteForProjectIds(function($projectId) use ($timeLimit, $timestamp){
$timeLimit->setNamespace('app_'.$projectId);
@@ -203,7 +221,7 @@ class DeletesV1
Console::success('Delete code tag: '.$document->getAttribute('path', ''));
}
else {
Console::error('Dailed to delete code tag: '.$document->getAttribute('path', ''));
Console::error('Failed to delete code tag: '.$document->getAttribute('path', ''));
}
});
@@ -251,7 +269,6 @@ class DeletesV1
Authorization::disable();
$projects = $this->getConsoleDB()->getCollection([
'limit' => $limit,
'offset' => $count,
'orderType' => 'ASC',
'orderCast' => 'string',
'filters' => [
@@ -294,7 +311,6 @@ class DeletesV1
$results = $database->getCollection([
'limit' => $limit,
'offset' => $count,
'orderField' => '$id',
'orderType' => 'ASC',
'orderCast' => 'string',
@@ -340,9 +356,12 @@ class DeletesV1
{
global $register;
$db = $register->get('db');
$cache = $register->get('cache');
if($this->consoleDB === null) {
$this->consoleDB = new Database();
$this->consoleDB->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register));
$this->consoleDB->setAdapter(new RedisAdapter(new MySQLAdapter($db, $cache), $cache));;
$this->consoleDB->setNamespace('app_console'); // Main DB
$this->consoleDB->setMocks(Config::getParam('collections', []));
}
@@ -356,9 +375,12 @@ class DeletesV1
protected function getProjectDB($projectId): Database
{
global $register;
$db = $register->get('db');
$cache = $register->get('cache');
$projectDB = new Database();
$projectDB->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register));
$projectDB->setAdapter(new RedisAdapter(new MySQLAdapter($db, $cache), $cache));
$projectDB->setNamespace('app_'.$projectId); // Main DB
$projectDB->setMocks(Config::getParam('collections', []));
+31 -29
View File
@@ -6,13 +6,15 @@ use Appwrite\Database\Adapter\MySQL as MySQLAdapter;
use Appwrite\Database\Adapter\Redis as RedisAdapter;
use Appwrite\Database\Validator\Authorization;
use Appwrite\Event\Event;
use Appwrite\Resque\Worker;
use Appwrite\Utopia\Response\Model\Execution;
use Cron\CronExpression;
use Swoole\Runtime;
use Utopia\App;
use Utopia\CLI\Console;
use Utopia\Config\Config;
require_once __DIR__.'/../init.php';
require_once __DIR__.'/../workers.php';
Runtime::enableCoroutine(0);
@@ -70,9 +72,6 @@ Console::success('Finished warmup in '.$warmupTime.' seconds');
$stdout = '';
$stderr = '';
$exitCode = Console::execute('docker ps --all --format "name={{.Names}}&status={{.Status}}&labels={{.Labels}}" --filter label=appwrite-type=function'
, '', $stdout, $stderr, 30);
$executionStart = \microtime(true);
$exitCode = Console::execute('docker ps --all --format "name={{.Names}}&status={{.Status}}&labels={{.Labels}}" --filter label=appwrite-type=function'
@@ -125,20 +124,23 @@ Console::info(count($list)." functions listed in " . ($executionEnd - $execution
//TODO aviod scheduled execution if delay is bigger than X offest
class FunctionsV1
class FunctionsV1 extends Worker
{
public $args = [];
public $allowed = [];
public function setUp(): void
public function init(): void
{
}
public function perform()
public function run(): void
{
global $register;
$db = $register->get('db');
$cache = $register->get('cache');
$projectId = $this->args['projectId'] ?? '';
$functionId = $this->args['functionId'] ?? '';
$webhooks = $this->args['webhooks'] ?? [];
@@ -152,7 +154,7 @@ class FunctionsV1
$jwt = $this->args['jwt'] ?? '';
$database = new Database();
$database->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register));
$database->setAdapter(new RedisAdapter(new MySQLAdapter($db, $cache), $cache));
$database->setNamespace('app_'.$projectId);
$database->setMocks(Config::getParam('collections', []));
@@ -330,12 +332,12 @@ class FunctionsV1
Authorization::reset();
$runtime = (isset($runtimes[$function->getAttribute('env', '')]))
? $runtimes[$function->getAttribute('env', '')]
$runtime = (isset($runtimes[$function->getAttribute('runtime', '')]))
? $runtimes[$function->getAttribute('runtime', '')]
: null;
if(\is_null($runtime)) {
throw new Exception('Environment "'.$function->getAttribute('env', '').' is not supported');
throw new Exception('Runtime "'.$function->getAttribute('runtime', '').'" is not supported');
}
$vars = \array_merge($function->getAttribute('vars', []), [
@@ -355,7 +357,7 @@ class FunctionsV1
\array_walk($vars, function (&$value, $key) {
$key = $this->filterEnvKey($key);
$value = \escapeshellarg((empty($value)) ? 'null' : $value);
$value = \escapeshellarg((empty($value)) ? '' : $value);
$value = "--env {$key}={$value}";
});
@@ -423,15 +425,24 @@ class FunctionsV1
" --workdir /usr/local/src".
" ".\implode(" ", $vars).
" {$runtime['image']}".
" sh -c 'mv /tmp/code.tar.gz /usr/local/src/code.tar.gz && tar -zxf /usr/local/src/code.tar.gz --strip 1 && rm /usr/local/src/code.tar.gz && tail -f /dev/null'"
" tail -f /dev/null"
, '', $stdout, $stderr, 30);
$executionEnd = \microtime(true);
if($exitCode !== 0) {
throw new Exception('Failed to create function environment: '.$stderr);
}
$exitCodeUntar = Console::execute("docker exec ".
$container.
" sh -c 'mv /tmp/code.tar.gz /usr/local/src/code.tar.gz && tar -zxf /usr/local/src/code.tar.gz --strip 1 && rm /usr/local/src/code.tar.gz'"
, '', $stdout, $stderr, 60);
if($exitCodeUntar !== 0) {
throw new Exception('Failed to extract tar: '.$stderr);
}
$executionEnd = \microtime(true);
$list[$container] = [
'name' => $container,
'online' => true,
@@ -479,6 +490,7 @@ class FunctionsV1
throw new Exception('Failed saving execution to DB', 500);
}
$executionModel = new Execution();
$executionUpdate = new Event('v1-webhooks', 'WebhooksV1');
$executionUpdate
@@ -486,17 +498,7 @@ class FunctionsV1
->setParam('userId', $userId)
->setParam('webhooks', $webhooks)
->setParam('event', 'functions.executions.update')
->setParam('eventData', [
'$id' => $execution['$id'],
'functionId' => $execution['functionId'],
'dateCreated' => $execution['dateCreated'],
'trigger' => $execution['trigger'],
'status' => $execution['status'],
'exitCode' => $execution['exitCode'],
'stdout' => $execution['stdout'],
'stderr' => $execution['stderr'],
'time' => $execution['time']
]);
->setParam('eventData', $execution->getArrayCopy(array_keys($executionModel->getRules())));
$executionUpdate->trigger();
@@ -535,7 +537,7 @@ class FunctionsV1
if(\count($list) > $max) {
Console::info('Starting containers cleanup');
\usort($list, function ($item1, $item2) {
\uasort($list, function ($item1, $item2) {
return (int)($item1['appwrite-created'] ?? 0) <=> (int)($item2['appwrite-created'] ?? 0);
});
@@ -579,7 +581,7 @@ class FunctionsV1
return $output;
}
public function tearDown(): void
public function shutdown(): void
{
}
}
}
+7 -8
View File
@@ -1,26 +1,26 @@
<?php
use Appwrite\Resque\Worker;
use Utopia\App;
use Utopia\CLI\Console;
require_once __DIR__.'/../init.php';
require_once __DIR__.'/../workers.php';
Console::title('Mails V1 Worker');
Console::success(APP_NAME.' mails worker v1 has started'."\n");
class MailsV1
class MailsV1 extends Worker
{
/**
* @var array
*/
public $args = [];
public function setUp(): void
public function init(): void
{
}
public function perform()
public function run(): void
{
global $register;
@@ -68,8 +68,7 @@ class MailsV1
}
}
public function tearDown(): void
public function shutdown(): void
{
// ... Remove environment for this job
}
}
}
+17 -15
View File
@@ -1,37 +1,40 @@
<?php
use Utopia\App;
use Utopia\CLI\Console;
use Utopia\Config\Config;
use Appwrite\Database\Database;
use Appwrite\Database\Adapter\MySQL as MySQLAdapter;
use Appwrite\Database\Adapter\Redis as RedisAdapter;
use Appwrite\Database\Validator\Authorization;
use Appwrite\Resque\Worker;
use Cron\CronExpression;
use Utopia\App;
use Utopia\CLI\Console;
use Utopia\Config\Config;
require_once __DIR__.'/../init.php';
require_once __DIR__.'/../workers.php';
Console::title('Tasks V1 Worker');
Console::success(APP_NAME.' tasks worker v1 has started');
class TasksV1
class TasksV1 extends Worker
{
/**
* @var array
*/
public $args = [];
public function setUp(): void
public function init(): void
{
}
public function perform()
public function run(): void
{
global $register;
$db = $register->get('db');
$cache = $register->get('cache');
$consoleDB = new Database();
$consoleDB->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register));
$consoleDB->setAdapter(new RedisAdapter(new MySQLAdapter($db, $cache), $cache));
$consoleDB->setNamespace('app_console'); // Main DB
$consoleDB->setMocks(Config::getParam('collections', []));
@@ -73,11 +76,11 @@ class TasksV1
}
if ($task->getAttribute('updated') !== $updated) { // Task have already been rescheduled by owner
return false;
return;
}
if ($task->getAttribute('status') !== 'play') { // Skip task and don't schedule again
return false;
return;
}
// Reschedule
@@ -202,11 +205,10 @@ class TasksV1
// Send alert if needed (use SMTP as default for now)
return true;
return;
}
public function tearDown(): void
public function shutdown(): void
{
// ... Remove environment for this job
}
}
}
+10 -11
View File
@@ -1,29 +1,30 @@
<?php
use Appwrite\Resque\Worker;
use Utopia\App;
use Utopia\CLI\Console;
require_once __DIR__.'/../init.php';
require_once __DIR__.'/../workers.php';
Console::title('Usage V1 Worker');
Console::success(APP_NAME.' usage worker v1 has started');
class UsageV1
class UsageV1 extends Worker
{
/**
* @var array
*/
public $args = [];
public function setUp(): void
public function init(): void
{
}
public function perform()
public function run(): void
{
global $register;
/** @var \Domnikl\Statsd\Client $statsd */
$statsd = $register->get('statsd', true);
$projectId = $this->args['projectId'] ?? '';
@@ -36,12 +37,12 @@ class UsageV1
$httpMethod = $this->args['httpMethod'] ?? '';
$httpRequest = $this->args['httpRequest'] ?? 0;
$functionId = $this->args['functionId'];
$functionId = $this->args['functionId'] ?? '';
$functionExecution = $this->args['functionExecution'] ?? 0;
$functionExecutionTime = $this->args['functionExecutionTime'] ?? 0;
$functionStatus = $this->args['functionStatus'] ?? '';
$tags = ",project={$projectId},version=".App::getEnv('_APP_VERSION', 'UNKNOWN').'';
$tags = ",project={$projectId},version=".App::getEnv('_APP_VERSION', 'UNKNOWN');
// the global namespace is prepended to every key (optional)
$statsd->setNamespace('appwrite.usage');
@@ -52,7 +53,6 @@ class UsageV1
if($functionExecution >= 1) {
$statsd->increment('executions.all'.$tags.',functionId='.$functionId.',functionStatus='.$functionStatus);
var_dump($tags.',functionId='.$functionId.',functionStatus='.$functionStatus);
$statsd->count('executions.time'.$tags.',functionId='.$functionId, $functionExecutionTime);
}
@@ -65,8 +65,7 @@ class UsageV1
}
}
public function tearDown(): void
public function shutdown(): void
{
// ... Remove environment for this job
}
}
}
+7 -8
View File
@@ -1,23 +1,23 @@
<?php
use Appwrite\Resque\Worker;
use Utopia\App;
use Utopia\CLI\Console;
require_once __DIR__.'/../init.php';
require_once __DIR__.'/../workers.php';
Console::title('Webhooks V1 Worker');
Console::success(APP_NAME.' webhooks worker v1 has started');
class WebhooksV1
class WebhooksV1 extends Worker
{
public $args = [];
public function setUp(): void
public function init(): void
{
}
public function perform()
public function run(): void
{
$errors = [];
@@ -88,8 +88,7 @@ class WebhooksV1
}
}
public function tearDown(): void
public function shutdown(): void
{
// ... Remove environment for this job
}
}
}
+1 -1
View File
@@ -7,4 +7,4 @@ else
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
fi
REDIS_BACKEND=$REDIS_BACKEND RESQUE_PHP='/usr/src/code/vendor/autoload.php' php /usr/src/code/vendor/bin/resque-scheduler
INTERVAL=1 REDIS_BACKEND=$REDIS_BACKEND RESQUE_PHP='/usr/src/code/vendor/autoload.php' php /usr/src/code/vendor/bin/resque-scheduler
+1 -1
View File
@@ -7,4 +7,4 @@ else
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
fi
QUEUE='v1-audits' APP_INCLUDE='/usr/src/code/app/workers/audits.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
INTERVAL=1 QUEUE='v1-audits' APP_INCLUDE='/usr/src/code/app/workers/audits.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
+1 -1
View File
@@ -7,4 +7,4 @@ else
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
fi
QUEUE='v1-certificates' APP_INCLUDE='/usr/src/code/app/workers/certificates.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
INTERVAL=1 QUEUE='v1-certificates' APP_INCLUDE='/usr/src/code/app/workers/certificates.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
+1 -1
View File
@@ -7,4 +7,4 @@ else
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
fi
QUEUE='v1-deletes' APP_INCLUDE='/usr/src/code/app/workers/deletes.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
INTERVAL=1 QUEUE='v1-deletes' APP_INCLUDE='/usr/src/code/app/workers/deletes.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
+1 -1
View File
@@ -7,4 +7,4 @@ else
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
fi
QUEUE='v1-functions' APP_INCLUDE='/usr/src/code/app/workers/functions.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
INTERVAL=0.1 QUEUE='v1-functions' APP_INCLUDE='/usr/src/code/app/workers/functions.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
+1 -1
View File
@@ -7,4 +7,4 @@ else
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
fi
QUEUE='v1-mails' APP_INCLUDE='/usr/src/code/app/workers/mails.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
INTERVAL=1 QUEUE='v1-mails' APP_INCLUDE='/usr/src/code/app/workers/mails.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
+1 -1
View File
@@ -7,4 +7,4 @@ else
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
fi
QUEUE='v1-tasks' APP_INCLUDE='/usr/src/code/app/workers/tasks.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
INTERVAL=0.1 QUEUE='v1-tasks' APP_INCLUDE='/usr/src/code/app/workers/tasks.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
+1 -1
View File
@@ -7,4 +7,4 @@ else
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
fi
QUEUE='v1-usage' APP_INCLUDE='/usr/src/code/app/workers/usage.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
INTERVAL=1 QUEUE='v1-usage' APP_INCLUDE='/usr/src/code/app/workers/usage.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
+1 -1
View File
@@ -7,4 +7,4 @@ else
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
fi
QUEUE='v1-webhooks' APP_INCLUDE='/usr/src/code/app/workers/webhooks.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
INTERVAL=0.1 QUEUE='v1-webhooks' APP_INCLUDE='/usr/src/code/app/workers/webhooks.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
+10 -10
View File
@@ -36,35 +36,35 @@
"ext-sockets": "*",
"appwrite/php-clamav": "1.1.*",
"appwrite/php-runtimes": "0.2.*",
"appwrite/php-runtimes": "0.4.*",
"utopia-php/framework": "0.14.*",
"utopia-php/abuse": "0.4.*",
"utopia-php/abuse": "0.5.*",
"utopia-php/analytics": "0.2.*",
"utopia-php/audit": "0.5.*",
"utopia-php/cache": "0.2.*",
"utopia-php/cli": "0.11.*",
"utopia-php/config": "0.2.*",
"utopia-php/locale": "0.3.*",
"utopia-php/registry": "0.4.*",
"utopia-php/registry": "0.5.*",
"utopia-php/preloader": "0.2.*",
"utopia-php/domains": "1.1.*",
"utopia-php/swoole": "0.2.*",
"utopia-php/storage": "0.5.*",
"utopia-php/image": "0.2.*",
"utopia-php/image": "0.5.*",
"resque/php-resque": "1.3.6",
"matomo/device-detector": "4.2.2",
"matomo/device-detector": "4.2.3",
"dragonmantank/cron-expression": "3.1.0",
"influxdb/influxdb-php": "1.15.2",
"phpmailer/phpmailer": "6.4.1",
"phpmailer/phpmailer": "6.5.0",
"chillerlan/php-qrcode": "4.3.0",
"adhocore/jwt": "1.1.2",
"slickdeals/statsd": "3.0.2"
"slickdeals/statsd": "3.1.0"
},
"require-dev": {
"appwrite/sdk-generator": "0.10.6",
"swoole/ide-helper": "4.6.6",
"phpunit/phpunit": "9.5.4",
"appwrite/sdk-generator": "0.12.0",
"swoole/ide-helper": "4.6.7",
"phpunit/phpunit": "9.5.6",
"vimeo/psalm": "4.7.2"
},
"provide": {
Generated
+318 -187
View File
File diff suppressed because it is too large Load Diff
+4
View File
@@ -0,0 +1,4 @@
<?php
echo 'execute init_file success' . PHP_EOL;
Yasd\Api\setRemoteHost('127.0.0.1'); //Set your development machine's IP
+12 -3
View File
@@ -2,7 +2,6 @@
# This is a development version of THE Appwrite docker-compose.yml file.
# Avoid using this file in your production environment.
# We're exposing here sensetive ports and mounting code volumes for rapid development and debugging of the server stack.
# For a production ready compose file please use: https://appwrite.io/docker-compose.yml
version: '3'
@@ -40,6 +39,7 @@ services:
build:
context: .
args:
- DEBUG=false
- TESTING=true
- VERSION=dev
ports:
@@ -68,11 +68,17 @@ services:
- ./public:/usr/src/code/public
- ./src:/usr/src/code/src
- ./debug:/tmp
- ./dev:/usr/local/dev
depends_on:
- mariadb
- redis
# - clamav
- influxdb
entrypoint:
- php
- -e
- app/http.php
- -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
environment:
- _APP_ENV
- _APP_LOCALE
@@ -391,7 +397,7 @@ services:
- MYSQL_DATABASE=${_APP_DB_SCHEMA}
- MYSQL_USER=${_APP_DB_USER}
- MYSQL_PASSWORD=${_APP_DB_PASS}
command: 'mysqld --innodb-flush-method=fsync' # add ' --query_cache_size=0' for DB tests
command: 'mysqld --innodb-flush-method=fsync --wait_timeout=86400' # add ' --query_cache_size=0' for DB tests
# command: mv /var/lib/mysql/ib_logfile0 /var/lib/mysql/ib_logfile0.bu && mv /var/lib/mysql/ib_logfile1 /var/lib/mysql/ib_logfile1.bu
# smtp:
@@ -431,10 +437,13 @@ services:
- appwrite-influxdb:/var/lib/influxdb:rw
telegraf:
image: appwrite/telegraf:1.1.0
image: appwrite/telegraf:1.2.0
container_name: appwrite-telegraf
networks:
- appwrite
environment:
- _APP_INFLUXDB_HOST
- _APP_INFLUXDB_PORT
# Dev Tools Start ------------------------------------------------------------------------------------------
#
@@ -6,7 +6,7 @@ client = Client()
(client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
)
account = Account(client)
@@ -6,7 +6,7 @@ client = Client()
(client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
)
account = Account(client)
@@ -6,7 +6,7 @@ client = Client()
(client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
)
account = Account(client)
@@ -6,7 +6,7 @@ client = Client()
(client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
)
account = Account(client)
@@ -6,7 +6,7 @@ client = Client()
(client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
)
account = Account(client)
@@ -6,7 +6,7 @@ client = Client()
(client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
)
account = Account(client)
@@ -6,7 +6,7 @@ client = Client()
(client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
)
account = Account(client)
@@ -6,7 +6,7 @@ client = Client()
(client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
)
account = Account(client)
@@ -6,7 +6,7 @@ client = Client()
(client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
)
account = Account(client)
@@ -6,7 +6,7 @@ client = Client()
(client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
)
account = Account(client)
@@ -6,7 +6,7 @@ client = Client()
(client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
)
account = Account(client)
@@ -6,7 +6,7 @@ client = Client()
(client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
)
account = Account(client)
@@ -6,7 +6,7 @@ client = Client()
(client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
)
account = Account(client)
@@ -6,7 +6,7 @@ client = Client()
(client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
)
account = Account(client)
@@ -6,7 +6,7 @@ client = Client()
(client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
)
account = Account(client)
@@ -11,4 +11,4 @@ client = Client()
avatars = Avatars(client)
result = avatars.get_q_r('[TEXT]')
result = avatars.get_qr('[TEXT]')
@@ -11,4 +11,4 @@ client = Client()
health = Health(client)
result = health.get_d_b()
result = health.get_db()
@@ -11,4 +11,4 @@ client = Client()
locale = Locale(client)
result = locale.get_countries_e_u()
result = locale.get_countries_eu()
@@ -6,7 +6,7 @@ client = Client()
(client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
)
teams = Teams(client)
@@ -5,7 +5,7 @@ client = Appwrite::Client.new()
client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
;
account = Appwrite::Account.new(client);
@@ -5,7 +5,7 @@ client = Appwrite::Client.new()
client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
;
account = Appwrite::Account.new(client);
@@ -5,7 +5,7 @@ client = Appwrite::Client.new()
client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
;
account = Appwrite::Account.new(client);
@@ -5,7 +5,7 @@ client = Appwrite::Client.new()
client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
;
account = Appwrite::Account.new(client);
@@ -5,7 +5,7 @@ client = Appwrite::Client.new()
client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
;
account = Appwrite::Account.new(client);
@@ -5,7 +5,7 @@ client = Appwrite::Client.new()
client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
;
account = Appwrite::Account.new(client);
@@ -5,7 +5,7 @@ client = Appwrite::Client.new()
client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
;
account = Appwrite::Account.new(client);
@@ -5,7 +5,7 @@ client = Appwrite::Client.new()
client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
;
account = Appwrite::Account.new(client);
@@ -5,7 +5,7 @@ client = Appwrite::Client.new()
client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
;
account = Appwrite::Account.new(client);
@@ -5,7 +5,7 @@ client = Appwrite::Client.new()
client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
;
account = Appwrite::Account.new(client);
@@ -5,7 +5,7 @@ client = Appwrite::Client.new()
client
.set_endpoint('https://[HOSTNAME_OR_IP]/v1') # Your API Endpoint
.set_project('5df5acd0d48c2') # Your project ID
.set_j_w_t('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
.set_jwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ...') # Your secret JSON Web Token
;
account = Appwrite::Account.new(client);

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