Compare commits

...
833 Commits
Author SHA1 Message Date
Eldad Fux 933b3459bd Updated windows logo 2021-05-30 14:55:36 +03:00
Eldad Fux accea42af1 Updated windows logo 2021-05-30 14:33:29 +03:00
Eldad A. FuxandGitHub 2b467de5b8 Merge pull request #1216 from appwrite/fix-delete-user
fix(users): rename deleteUser to delete
2021-05-29 10:32:52 +03:00
Christy Jacob b662de694b fix(users): rename deleteUser to delete 2021-05-29 01:54:24 +05:30
Eldad Fux 726077716b Updated changelog 2021-05-28 22:23:26 +03:00
Eldad A. FuxandGitHub 29114f8299 Merge pull request #1208 from appwrite/feat-1176-pass-session-to-function
feat: pass session to cloud function in oauth create sessions
2021-05-28 22:21:51 +03:00
Eldad A. FuxandGitHub b9565e26ab Merge pull request #1209 from appwrite/fix-1205-twitch-oauth-issue
fix: twitch oAuth issue
2021-05-28 22:12:12 +03:00
Eldad A. FuxandGitHub bf0f6aa9a5 Merge pull request #1214 from TorstenDittmann/fix-console-team-invite
fix(console): team invite
2021-05-28 22:10:30 +03:00
Eldad A. FuxandGitHub 4b006a1be0 Merge pull request #1167 from TorstenDittmann/feat-account-sessions
refactor(console): users devices into session
2021-05-28 19:30:32 +03:00
Eldad A. FuxandGitHub 735cb90a44 Merge pull request #1206 from lohanidamodar/fix-delete-session-removing-fallback-cookie
fixes deleteSession API removes browser's cookieFallback #1193
2021-05-28 19:24:49 +03:00
d39758ba49 Update src/Appwrite/Auth/OAuth2/Twitch.php
Co-authored-by: Eldad A. Fux <eldad.fux@gmail.com>
2021-05-28 21:50:04 +05:30
Torsten Dittmann 8f8ba1cb6d fix(api): time limit with empty values 2021-05-28 18:03:51 +02:00
Torsten Dittmann 0ecc34429a fix(console): tema invite 2021-05-28 17:03:14 +02:00
Torsten Dittmann b11e32327e feat(console): use new web sdk 2021-05-28 17:02:59 +02:00
Christy Jacob 8ffd822965 fix: twitch oauth issue 2021-05-28 13:53:46 +05:30
Christy Jacob f4538f0c6b feat: indentation 2021-05-28 12:32:39 +05:30
Christy Jacob faa7c3e708 feat: pass session to cloud function in oauth create sessions 2021-05-28 12:26:11 +05:30
Damodar Lohani 59338afb40 fixes deleteSession API removes browser's cookieFallback #1193 2021-05-28 12:12:14 +05:45
Torsten Dittmann 76c5fcf774 docs(changelog): add changelog for devices refactor 2021-05-26 13:51:08 +02:00
Torsten Dittmann b34d09f8a8 refactor(console): add provider to session in account 2021-05-26 10:41:17 +02:00
Torsten Dittmann b54747b3ac refactor(console): sessions icons 2021-05-26 10:40:52 +02:00
Eldad A. FuxandGitHub 33aaa5c1ef Merge pull request #1189 from lohanidamodar/fix-storage-issue-with-large-files
modify swoole buffer output size
2021-05-26 08:42:26 +03:00
Eldad A. FuxandGitHub 0efea6af74 Merge pull request #1183 from appwrite/feat-added-file-metadata
Added metadata
2021-05-25 23:08:21 +03:00
Eldad A. FuxandGitHub d9a0765efc Merge pull request #1188 from lohanidamodar/fix-clamav-health-status
fixing clamav status when clamav is not running
2021-05-25 23:06:10 +03:00
Damodar Lohani 19e2ebf79b modify swoole buffer output size 2021-05-25 16:04:49 +05:45
Damodar Lohani 40a8a4c366 fixing clamav status when clamav is not running 2021-05-25 15:11:20 +05:45
Eldad Fux 7b8542d0c2 Added metadata 2021-05-24 19:33:55 +03:00
Eldad Fux 82abcb29ae Merge branch 'master' of github.com:appwrite/appwrite 2021-05-24 19:14:13 +03:00
Eldad A. FuxandGitHub 2f471c0f7b Merge pull request #1173 from lohanidamodar/fix-nepal-flag
update nepal flag
2021-05-24 19:00:01 +03:00
Eldad A. FuxandGitHub 3472b1545e Merge pull request #1166 from TorstenDittmann/fix-anon-session-id
fix(account): add anon session id
2021-05-24 18:30:52 +03:00
Eldad Fux 63ea200f96 Updated SDKS 2021-05-24 18:08:54 +03:00
Eldad A. FuxandGitHub 6ab46910d9 Merge pull request #1165 from TorstenDittmann/fix-web-sdk-getting-started
fix(docs): web sdk getting started
2021-05-24 17:36:40 +03:00
Eldad A. FuxandGitHub 9f3ffd7b63 Merge pull request #1175 from appwrite/feat-upgrade-sdks
Upgraded sdks versions
2021-05-21 22:52:50 +03:00
Eldad Fux 699bd49eee Updated web sdk version 2021-05-21 21:43:06 +03:00
Eldad Fux 347ae809d8 Updated web sdk version 2021-05-21 17:36:48 +03:00
Eldad Fux 34fd7fee56 Updated dependency 2021-05-21 17:19:58 +03:00
Eldad Fux 07ca2d8608 Upgraded sdks versions 2021-05-21 17:01:49 +03:00
Damodar Lohani 6be6ad8e97 Merge branch 'master' into fix-nepal-flag 2021-05-21 18:19:43 +05:45
Eldad A. FuxandGitHub 4cfce5547e Merge pull request #1170 from lohanidamodar/fix-image-preview-validator
fix-image-preview-validator
2021-05-21 15:25:09 +03:00
Damodar Lohani 546214012d fix openAPI spec 2021-05-21 16:32:08 +05:45
Damodar Lohani 09874e9c5d fix spec type mismatch 2021-05-21 14:29:51 +05:45
Damodar Lohani 8d45cbefe1 update nepal flag 2021-05-21 13:47:43 +05:45
Damodar Lohani fd509ad282 fix password format 2021-05-21 13:16:49 +05:45
Damodar Lohani 87bbcff3a7 fix wrong type value 2021-05-21 13:04:19 +05:45
Damodar Lohani 54fdc647c2 updated specs to get validator getType 2021-05-21 12:53:53 +05:45
Damodar Lohani c03e3709a6 proper range validator for opacity 2021-05-21 12:42:43 +05:45
Damodar Lohani 4199dcc1f4 updated framework 2021-05-21 12:38:20 +05:45
Eldad Fux 79d4fbc203 Added 0.8 releas announcment 2021-05-20 17:33:53 +03:00
Torsten Dittmann 54baea36f3 fix(console): switch browser with provider icon in users session 2021-05-20 16:17:50 +02:00
Torsten Dittmann 5dc1759901 docs(oauth): fixed tutorial image path 2021-05-20 16:16:19 +02:00
Torsten Dittmann 5149b3880a refactor(console): users devices into session 2021-05-20 16:03:47 +02:00
Torsten Dittmann d118b09d90 fix(account): add anon sessiom id 2021-05-20 15:41:55 +02:00
Torsten Dittmann 7ea0871dc9 fix(docs): web sdk getting started 2021-05-20 14:40:41 +02:00
Eldad Fux bcdf8835ca Updated the Node.js SDK 2021-05-20 12:07:51 +03:00
Eldad Fux ed751160de Fixed missing JWT model 2021-05-20 11:52:19 +03:00
Damodar Lohani 3318631d9d converting to numeric validator 2021-05-20 12:27:20 +05:45
Eldad Fux c454bc2a65 Updated CLI version 2021-05-19 22:37:30 +03:00
Torsten DittmannandGitHub a8dcd9efe3 Merge pull request #1159 from appwrite/0.8.x
0.8.x
2021-05-19 18:08:30 +02:00
Eldad Fux 284236ab17 Fixed docs 2021-05-19 18:56:44 +03:00
Eldad Fux d316ecbfd9 Fixed config 2021-05-19 18:53:53 +03:00
Eldad Fux f1644af6a3 Updated specs 2021-05-19 18:30:30 +03:00
Eldad Fux 98df165050 Updated platform types 2021-05-19 18:29:06 +03:00
Eldad Fux 44a87a144d Added line break 2021-05-19 17:58:28 +03:00
Eldad Fux e9db13bc82 Added line break 2021-05-19 17:56:55 +03:00
Eldad Fux a2ccbfabff Added line break 2021-05-19 17:55:45 +03:00
Eldad Fux b8154a2840 Updated docs 2021-05-19 17:53:13 +03:00
Eldad Fux 019f1e9d57 Fixed specs and code examples 2021-05-19 17:26:06 +03:00
Eldad Fux 8084292cb5 Updated specs 2021-05-19 17:11:46 +03:00
Eldad Fux cb038a2cfd Updated specs 2021-05-19 16:10:32 +03:00
Eldad Fux 785f5a876d Updated change log 2021-05-19 14:52:44 +03:00
Eldad Fux 1cd7cfbc2c Updated Dart changelog 2021-05-19 14:44:22 +03:00
Eldad Fux 4febefc853 Updated Dart changelog 2021-05-19 14:43:55 +03:00
Eldad Fux 28bdfd2436 Updated Flutter changelog 2021-05-19 14:38:02 +03:00
Eldad Fux f4e12acf9b Updated Flutter changelog 2021-05-19 14:36:58 +03:00
Eldad A. FuxandGitHub c257c20570 Merge pull request #1162 from appwrite/fix-docker-influx
fix(docker): influxdb image
2021-05-19 14:17:42 +03:00
Torsten DittmannandGitHub ca14298a65 fix(docker): influxdb image 2021-05-19 13:15:58 +02:00
Eldad A. FuxandGitHub 46a4036a0a Merge pull request #1161 from TorstenDittmann/fix-worker-envs
fix(docker): functions worker missing openssl key
2021-05-19 12:59:20 +03:00
Torsten Dittmann 9ede38c326 fix(docker): functions worker openssl key 2021-05-19 11:25:38 +02:00
Torsten Dittmann 86a94aff97 fix(docker): functions worker openssl key 2021-05-19 11:23:56 +02:00
b730350ed0 Update CHANGES.md
Co-authored-by: Torsten Dittmann <torsten.dittmann@googlemail.com>
2021-05-19 11:42:40 +03:00
Eldad Fux 5157906cbb Updated sdk-generator 2021-05-19 08:57:30 +03:00
Eldad Fux 72733964c3 Merge branch '0.8.x' of github.com:appwrite/appwrite into 0.8.x 2021-05-18 23:37:30 +03:00
Eldad Fux e6597bb6e1 Updated cachebuster 2021-05-18 23:37:23 +03:00
Eldad A. FuxandGitHub 552c67d9f3 Merge pull request #1157 from appwrite/feat-update-code-examples
Feat update code examples
2021-05-18 23:32:54 +03:00
Eldad A. FuxandGitHub 6a56095c8f Merge pull request #1158 from appwrite/feat-update-sdks-versions
Updated SDKs versions
2021-05-18 22:43:16 +03:00
Eldad Fux dfdb162477 updated the change log 2021-05-18 22:38:51 +03:00
Eldad Fux 8830828d80 Updated SDKs versions 2021-05-18 22:35:04 +03:00
Eldad A. FuxandGitHub cb97b8cc6a Merge pull request #1154 from lohanidamodar/feat-auto-generate-secret-keys
feat-auto-generate-secret-keys
2021-05-18 22:30:37 +03:00
Eldad A. FuxandGitHub a0daea0bb9 Update app/tasks/install.php 2021-05-18 22:30:17 +03:00
Eldad A. FuxandGitHub 5185321566 Update app/tasks/install.php 2021-05-18 22:30:09 +03:00
Eldad A. FuxandGitHub 8ec0c666e4 Update app/tasks/install.php 2021-05-18 22:29:44 +03:00
Eldad Fux 1c7ac36d7f Updated specs and examples 2021-05-18 22:19:54 +03:00
Eldad Fux 666f51f986 Updated code examples 2021-05-18 22:05:44 +03:00
Eldad A. FuxandGitHub e9e501bf8e Merge pull request #1156 from appwrite/feat-updated-docs-expiry-times
Updated docs
2021-05-18 19:30:25 +03:00
Eldad A. FuxandGitHub d9f8236d14 Merge pull request #1153 from lohanidamodar/feat-response-format-header-sdks
feat-response-format-header-sdks
2021-05-18 19:25:10 +03:00
Eldad A. FuxandGitHub 44cccf1ff3 Merge pull request #1155 from lohanidamodar/fix-certificates-queueing
fix-certificates-queueing
2021-05-18 19:24:12 +03:00
Eldad A. FuxandGitHub 50e779fc2f Update app/controllers/general.php 2021-05-18 19:24:00 +03:00
Eldad Fux 77f67b1017 Updated docs 2021-05-18 16:48:36 +03:00
Eldad Fux 3927406d51 Updated change log 2021-05-18 16:41:34 +03:00
Eldad A. FuxandGitHub 4ff892d29f Merge pull request #1150 from appwrite/fect-stateless-webhooks-worker
Feat stateless webhooks worker
2021-05-18 16:40:04 +03:00
Damodar Lohani 8b60061875 remove delay 2021-05-18 18:55:09 +05:45
Damodar Lohani 6bb46a676d multiple backups of old files 2021-05-18 14:21:22 +05:45
Damodar Lohani 52e2dc3182 specify image and org name for main appwrite image 2021-05-18 14:19:19 +05:45
Damodar Lohani 80ded8e77d providing organization and image as param to the installation script and compose file 2021-05-18 13:49:51 +05:45
Damodar Lohani fd2edd9164 creating backup of existing file 2021-05-18 13:43:01 +05:45
Damodar Lohani a2466956ec fix filter and mysql root password 2021-05-18 12:18:48 +05:45
Damodar Lohani 7864b19232 supporting generating password and secret key 2021-05-18 12:09:09 +05:45
Damodar Lohani 0f7b7459ca response format header 2021-05-18 11:17:03 +05:45
Eldad A. FuxandGitHub f2405dc219 Merge pull request #1151 from appwrite/fix-certificate-collection-rules-error
Fix - Add certificate collection rules for updated and certificateID
2021-05-17 22:28:45 +03:00
kodumbeats 98ca565534 Add certificates exception fix to changelog 2021-05-17 15:19:52 -04:00
Eldad Fux d2749524b7 Merge branch 'dev' of github.com:appwrite/appwrite into 0.8.x 2021-05-17 21:27:07 +03:00
Eldad Fux 49fa978de4 Merge branch 'master' of github.com:appwrite/appwrite into dev 2021-05-17 21:24:35 +03:00
kodumbeats 1120e8885a CertificateID not a required param 2021-05-17 14:10:17 -04:00
kodumbeats 6f22854c54 Add certificate collection rules for updated and certificateID 2021-05-17 13:50:44 -04:00
Eldad Fux 63a92a768a Fixed functions webhooks trigger 2021-05-17 18:52:22 +03:00
Eldad Fux a8cc398c85 Updated functions trigger 2021-05-17 14:32:37 +03:00
Eldad Fux af470a3f1a Cleanups 2021-05-17 12:54:04 +03:00
Eldad Fux 79bf99372e Removed DB connection 2021-05-17 12:49:17 +03:00
Eldad A. FuxandGitHub af7f9dd6e1 Merge pull request #1149 from appwrite/feat-response-filters
feat: 0.7 response filters
2021-05-15 13:50:39 +03:00
Eldad A. FuxandGitHub 5050e6fd60 Merge pull request #1145 from appwrite/fix-auth-redirect
Fix redirect from signup
2021-05-15 13:50:12 +03:00
Eldad A. FuxandGitHub 18a1a2b8a0 Merge pull request #1147 from appwrite/fix-1144-users-list
Added string escaping
2021-05-15 13:49:19 +03:00
Eldad A. FuxandGitHub b6b48b7684 Merge pull request #1148 from appwrite/fix-oauth-autocomplete
Fix oauth autocomplete
2021-05-15 11:15:02 +03:00
Eldad Fux 85dffbdc8f Removed duplicated class attribute 2021-05-15 11:00:29 +03:00
Eldad Fux 27837871e4 Added comments 2021-05-15 10:44:00 +03:00
Eldad Fux 2a3a73de34 Fixed autocomplete 2021-05-15 03:58:26 +03:00
Eldad Fux 9c0ebc5608 Added string escaping 2021-05-15 03:24:12 +03:00
Christy Jacob d7c81ba818 feat: update response filters 2021-05-14 20:45:29 +05:30
Eldad A. FuxandGitHub dc003464fa Merge pull request #1142 from appwrite/feat-add-update-membership-endpoint
feat(teams): endpoint to update membership roles
2021-05-14 14:28:11 +03:00
Eldad Fux d7e411cb4f Fix redirect from signup 2021-05-14 14:26:15 +03:00
Eldad A. FuxandGitHub fb8561f958 Merge pull request #1141 from lohanidamodar/feat-newsletter-subscribe
feat-newsletter-subscribe
2021-05-14 12:20:25 +03:00
Eldad A. FuxandGitHub 3804f718a4 Merge pull request #1139 from lohanidamodar/feat-automated-install
feat-automated-install
2021-05-14 09:58:59 +03:00
Eldad A. FuxandGitHub 52dc0a9f17 Update app/tasks/install.php 2021-05-14 09:58:18 +03:00
Damodar LohaniandGitHub bb39d90da6 updating description for param 2021-05-14 11:43:45 +05:45
Christy Jacob 6a9d9edc01 feat: some comments 2021-05-13 23:31:57 +05:30
Christy Jacob 2c838bfa77 fix: failing tests 2021-05-13 23:29:54 +05:30
Eldad Fux 3704dc69e8 Merge branch '0.8.x' of github.com:appwrite/appwrite into feat-add-update-membership-endpoint 2021-05-13 20:49:52 +03:00
Eldad Fux 732163bf9f Debug 2021-05-13 20:05:19 +03:00
Christy Jacob bd02cc8370 feat: added changelog 2021-05-13 20:36:10 +05:30
Christy Jacob a35a567e0e feat: added server side test 2021-05-13 20:17:35 +05:30
Eldad A. FuxandGitHub 69ab1ea5b5 Merge pull request #1120 from appwrite/feat-update-team-membership-password
Allow external users to update password without an old password
2021-05-13 17:40:49 +03:00
Eldad A. FuxandGitHub 5c4ee95d23 Merge branch '0.8.x' into feat-update-team-membership-password 2021-05-13 17:40:35 +03:00
3b74a92ab3 Apply suggestions from code review
Co-authored-by: Eldad A. Fux <eldad.fux@gmail.com>
2021-05-13 19:31:52 +05:30
Christy Jacob eefe7f7c9b feat: update doc 2021-05-13 19:29:29 +05:30
Eldad A. FuxandGitHub 8d603386a3 Merge pull request #1143 from appwrite/fix-teams-api-issues
fix(teams): some minor issues with the API
2021-05-13 16:57:05 +03:00
Christy Jacob 06344ee3c2 feat: added to changelog 2021-05-13 19:18:34 +05:30
Damodar Lohani 40c334a109 adding loading alert on signup 2021-05-13 19:01:30 +05:45
Damodar Lohani a346f7ab2a Merge branch '0.8.x' of github.com:appwrite/appwrite into feat-newsletter-subscribe 2021-05-13 18:26:56 +05:45
Damodar Lohani 5206d58883 updated signup process 2021-05-13 18:22:54 +05:45
Eldad A. FuxandGitHub 956f5c1a9b Merge pull request #937 from appwrite/feat-god-user
Feat Root Account
2021-05-13 12:38:03 +03:00
Eldad Fux 7192fc58d8 Fixed root redirect 2021-05-13 08:59:00 +03:00
Christy Jacob 67b4e8c729 feat: correct the event names 2021-05-12 22:50:10 +05:30
Christy Jacob af0bbd7b91 feat: increase memberships fetched to 2000 2021-05-12 22:45:55 +05:30
Christy Jacob df3f2d73e3 feat: reorder tests 2021-05-12 22:40:44 +05:30
Christy Jacob 978f6463fc feat: uncomment tests 2021-05-12 22:32:08 +05:30
Christy Jacob 31dc2d79eb feat: added enpoint for updating membership roles 2021-05-12 22:30:22 +05:30
Eldad A. FuxandGitHub 73e45c295a Merge pull request #1133 from lohanidamodar/feat-auto-ssl-generation
feat-auto-ssl-generation
2021-05-12 19:07:31 +03:00
Eldad A. FuxandGitHub 6b5b1b4cb3 Merge pull request #1140 from lohanidamodar/feat-discord-link
feat-discord-link
2021-05-12 18:13:13 +03:00
Eldad Fux 69abbba02b Changed god account to root account 2021-05-12 17:53:25 +03:00
Christy Jacob 10435d4392 feat: update membership roles 2021-05-12 20:17:56 +05:30
Christy Jacob a38678f30d feat: adding update membership role 2021-05-12 19:14:41 +05:30
Damodar Lohani c20d5785d4 signup to newsletter option in console signup 2021-05-12 18:00:22 +05:45
Damodar Lohani d94771471c format update for travis reboot 2021-05-12 17:40:16 +05:45
Eldad Fux f7f54c0d2f Leverage auth limit for god feature 2021-05-12 14:35:46 +03:00
Eldad Fux c5a2a93f96 Merge branch '0.8.x' of github.com:appwrite/appwrite into feat-god-user 2021-05-12 14:14:15 +03:00
Damodar Lohani bd73b3aa58 discord link in the footer 2021-05-12 16:58:31 +05:45
Damodar Lohani e2000dbdf8 remove extra white space 2021-05-12 16:42:13 +05:45
Damodar Lohani d198977e5d check interactive with a param 2021-05-12 16:39:14 +05:45
Damodar Lohani 7a75c3558f remove log 2021-05-12 16:10:57 +05:45
Damodar Lohani 9097cf2d42 unattended installl 2021-05-12 13:57:33 +05:45
Damodar Lohani 3330841b9e changelog 2021-05-12 12:57:08 +05:45
Eldad A. FuxandGitHub 18536627bc Merge pull request #1138 from appwrite/dependabot/npm_and_yarn/tests/resources/functions/node/lodash-4.17.21
Bump lodash from 4.17.20 to 4.17.21 in /tests/resources/functions/node
2021-05-12 08:52:36 +03:00
Damodar Lohani 0e90c75a12 refactor based on review 2021-05-12 11:04:48 +05:45
be5b882fe7 Apply suggestions from code review
Co-authored-by: Eldad A. Fux <eldad.fux@gmail.com>
2021-05-12 11:02:34 +05:45
dependabot[bot]andGitHub 33ca604f02 Bump lodash from 4.17.20 to 4.17.21 in /tests/resources/functions/node
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.20 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-12 00:05:26 +00:00
Damodar Lohani f83ad43187 fix auth issue 2021-05-11 17:21:27 +05:45
Damodar Lohani dc52c6975a fix error 2021-05-11 17:09:23 +05:45
Damodar Lohani dc92498d93 disable auth for writing 2021-05-11 17:06:55 +05:45
Damodar Lohani 4170eaa45a fix error 2021-05-11 17:00:26 +05:45
Damodar Lohani 35b76c1aee refactoring moving ssl generation to init function 2021-05-11 16:32:02 +05:45
Damodar Lohani c22dd1571f implementing review suggestions 2021-05-11 11:41:11 +05:45
Eldad A. FuxandGitHub 934b9aec27 Merge pull request #1129 from appwrite/feat-refactor-inviteid
feat: refactor inviteId to membershipId
2021-05-10 17:54:31 +03:00
Eldad A. FuxandGitHub a57174ae80 Merge pull request #1130 from appwrite/dependabot/npm_and_yarn/lodash-4.17.21
Bump lodash from 4.17.20 to 4.17.21
2021-05-10 17:54:07 +03:00
Eldad A. FuxandGitHub c29dca813e Merge pull request #1134 from appwrite/dependabot/npm_and_yarn/hosted-git-info-2.8.9
Bump hosted-git-info from 2.7.1 to 2.8.9
2021-05-10 17:34:54 +03:00
Damodar Lohani 75d8076ac9 skip certificate generation when localhost or hostname is IP 2021-05-10 16:23:05 +05:45
dependabot[bot]andGitHub 72c3434860 Bump hosted-git-info from 2.7.1 to 2.8.9
Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.7.1 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.7.1...v2.8.9)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-10 08:49:42 +00:00
Damodar Lohani 0c3bcb40a4 poc certificate auto generation 2021-05-10 14:33:27 +05:45
Christy Jacob c97dcbf9c9 feat: fix tests and update changelog 2021-05-10 09:55:52 +05:30
dependabot[bot]andGitHub 618324222f Bump lodash from 4.17.20 to 4.17.21
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.20 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-08 18:39:59 +00:00
Christy Jacob 18e12ee6ad feat: fix tests 2021-05-07 22:24:56 +05:30
Christy Jacob 391ff24192 feat: refactor inviteId to membershipId 2021-05-07 21:22:14 +05:30
Christy Jacob f128cd9578 feat: refactor inviteId to membershipId 2021-05-07 21:19:23 +05:30
Eldad A. FuxandGitHub eaa67732b7 Merge pull request #1128 from TorstenDittmann/fix-502-spec
fix(mock): 502 error spec
2021-05-07 16:53:35 +03:00
Torsten Dittmann ded3cbbb73 fix(mock): 502 error spec 2021-05-07 15:52:40 +02:00
Eldad A. FuxandGitHub a512edf7c3 Merge pull request #1127 from TorstenDittmann/merge-dev-into-0.8.x
0.8 - Sync dev into 0.8.x
2021-05-07 16:49:26 +03:00
Torsten Dittmann b357119fcd chore(changelog): update changelog 2021-05-07 09:47:27 +02:00
Torsten Dittmann fd3d789361 chore(composer): update composer 2021-05-07 09:39:58 +02:00
Torsten Dittmann a6b08dd1d8 chore(composer): update lock file 2021-05-07 09:16:43 +02:00
Torsten Dittmann 501f68ca38 Merge branch 'dev' of https://github.com/appwrite/appwrite into merge-dev-into-0.8.x 2021-05-07 09:15:56 +02:00
Torsten Dittmann a0d30aef8c chore(vars): fix typo on god account description 2021-05-07 09:06:36 +02:00
Eldad A. FuxandGitHub 57d6be0399 Merge pull request #1125 from TorstenDittmann/feat-mock-text-endpoint
feat(mock): add text response error
2021-05-07 01:42:39 +03:00
Christy Jacob d99f0cbc5c feat: review comments 2021-05-06 22:00:57 +05:30
Christy Jacob e8172f72e3 feat: review comments 2021-05-06 22:00:44 +05:30
Torsten Dittmann 1f91e8a460 fix(docs): typos 2021-05-06 17:53:48 +02:00
Torsten Dittmann 1894ea6490 fix(docs): typos 2021-05-06 17:53:07 +02:00
Torsten Dittmann c2849a53eb fix(phpdocs): remove unused char 2021-05-06 17:48:22 +02:00
Torsten Dittmann b3badfeb8d feat(mock): add text response error 2021-05-06 17:45:32 +02:00
Christy Jacob 80328f1dc7 feat: review comments 2021-05-06 18:51:36 +05:30
Eldad A. FuxandGitHub a2d60ac269 Merge pull request #1119 from appwrite/dependabot/composer/phpmailer/phpmailer-6.4.1
Bump phpmailer/phpmailer from 6.3.0 to 6.4.1
2021-05-05 15:18:08 +03:00
Eldad A. FuxandGitHub 762bd8bcc4 Merge pull request #1116 from appwrite/feat-new-platform-logos
Feat new OS logos
2021-05-05 13:32:11 +03:00
Eldad Fux 3b73ab46cf Merge branch '0.8.x' of github.com:appwrite/appwrite into feat-new-platform-logos 2021-05-05 09:17:47 +03:00
Christy Jacob eaac52b9b7 feat: allow external users to update password without oldPassword 2021-05-05 00:22:46 +05:30
dependabot[bot]andGitHub 34dfa8785a Bump phpmailer/phpmailer from 6.3.0 to 6.4.1
Bumps [phpmailer/phpmailer](https://github.com/PHPMailer/PHPMailer) from 6.3.0 to 6.4.1.
- [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.3.0...v6.4.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-04 17:46:06 +00:00
Eldad A. FuxandGitHub fee94d3eb1 Merge pull request #1118 from TorstenDittmann/fix-project-usage
tests(project): change order for influxdb to have a database
2021-05-04 19:13:34 +03:00
Torsten Dittmann 9c2b066e9e test(travis): use new runtimes env variable 2021-05-04 17:42:29 +02:00
Torsten Dittmann d5beb05206 tests(project): change test order for influxdb to have a database 2021-05-04 17:24:33 +02:00
Eldad A. FuxandGitHub 2db5ea69fc Merge pull request #1117 from TorstenDittmann/feat-influxdb-client-php
fix(influxdb): change driver to `curl`
2021-05-04 18:03:27 +03:00
Torsten Dittmann cee42bfd57 tests(project): remove timeout from usage call 2021-05-04 15:15:46 +02:00
Torsten Dittmann 3ab5fefb79 fix(influx): use curl as driver 2021-05-04 14:32:20 +02:00
Torsten Dittmann a46638544f debug influx 2021-05-04 14:15:29 +02:00
Torsten Dittmann bf8994fa3a Revert "feat(influxdb): introduce official client SDK"
This reverts commit 15522c2cb9.
2021-05-04 13:55:01 +02:00
Torsten Dittmann 15522c2cb9 feat(influxdb): introduce official client SDK 2021-05-04 13:15:36 +02:00
Eldad Fux c42c0a6091 Added new OS logos 2021-05-04 12:52:52 +03:00
Eldad A. FuxandGitHub 0aaf504549 Merge pull request #1113 from appwrite/fix-usage-worker-errors
fix-usage-worker-errors
2021-04-30 22:30:49 +03:00
Eldad Fux 7272ca857e Fixed missing default values 2021-04-30 18:09:15 +03:00
Eldad A. FuxandGitHub 252249e56c Update README.md 2021-04-30 07:58:00 +03:00
Eldad A. FuxandGitHub 8e4a87ea04 Merge pull request #1102 from TorstenDittmann/feat-prefs-response-model
feat: preferences response model
2021-04-29 20:59:41 +03:00
Eldad A. FuxandGitHub 5aad3f7e15 Merge pull request #713 from appwrite/feat-upgrade-php-version
Feat upgrade php version (8.0)
2021-04-29 20:09:22 +03:00
Torsten Dittmann 5e4b335183 fix: cloud functions 2021-04-29 17:59:19 +02:00
Torsten Dittmann d58cc6024b fix: deprecation notice for 2021-04-29 17:20:03 +02:00
Torsten Dittmann 6a196716b3 fix: adapt to review 2021-04-29 17:08:59 +02:00
Eldad A. FuxandGitHub e09c80ccd2 Merge pull request #1111 from TorstenDittmann/fix-migration-errors
fix(migration): prevent throwing error when document is missing ID
2021-04-29 13:38:29 +03:00
Torsten Dittmann 24705f2d08 Merge branch '0.8.x' of https://github.com/appwrite/appwrite into feat-upgrade-php-version 2021-04-29 09:37:08 +02:00
Torsten Dittmann 3c4476f689 fix: prevent throwing error when document is missing ID 2021-04-29 09:32:30 +02:00
Torsten Dittmann 53526d4fba chore: fix whitespace in travis file 2021-04-28 12:48:02 +02:00
Torsten Dittmann cac9875b97 tests: clean up travis file 2021-04-28 12:20:32 +02:00
Torsten Dittmann ebd41c784f tests: add travis prepare script 2021-04-28 11:54:21 +02:00
Torsten Dittmann 7ddf277110 tests: only use php-8.0 for runtimes 2021-04-28 11:30:43 +02:00
Torsten Dittmann c2a3d527df tests: revert debug changes 2021-04-28 11:04:44 +02:00
Eldad A. FuxandGitHub cffa50f272 Merge pull request #1109 from TorstenDittmann/fix-executions-permissions
fix: executions permission validation
2021-04-28 11:59:33 +03:00
Torsten Dittmann 86c7ff74b0 tests: remove docker-compose upgrade 2021-04-28 10:39:22 +02:00
Torsten Dittmann c3bf481ad2 tests: remove debug 2021-04-28 10:11:19 +02:00
Torsten Dittmann 0ddefb97eb tests: adjust curl 2021-04-28 09:14:41 +02:00
Torsten Dittmann ef7c4549af tests: adjust curl 2021-04-28 08:54:09 +02:00
Torsten Dittmann 107bbf57fb tests: debug travis 2021-04-28 08:10:40 +02:00
Torsten Dittmann c557e6c471 tests: add sleep before project usage test 2021-04-27 18:26:37 +02:00
Torsten Dittmann 1ce0536afa tests: re-arrange order 2021-04-27 16:33:47 +02:00
Torsten Dittmann 4689d0b69f Revert "fix: influx db client"
This reverts commit 5ddcdf1779.
2021-04-27 15:51:35 +02:00
Torsten Dittmann 5ddcdf1779 fix: influx db client 2021-04-27 15:39:40 +02:00
Torsten Dittmann acbf643ff3 tests: revert influxdb image 2021-04-27 13:06:40 +02:00
Torsten Dittmann d775b17f71 tests: fix typo 2021-04-27 12:45:21 +02:00
Torsten Dittmann b747c5c7f5 tests: try different influxdb 2021-04-27 12:07:46 +02:00
Torsten Dittmann 1c8be29ea5 tests: debug influxdb 2021-04-27 11:46:26 +02:00
Torsten Dittmann ab325bf4e9 chore: upgrade MaxMind-DB-Reader to 1.10.1 2021-04-27 11:08:06 +02:00
Torsten Dittmann c905803acc chore: updated changelog 2021-04-27 10:37:13 +02:00
Torsten Dittmann a21bb8d402 tests: reorder tests 2021-04-27 10:07:13 +02:00
Torsten Dittmann f2426aa473 fix: use authorization control instead of arguments 2021-04-27 09:28:42 +02:00
Torsten Dittmann 4eb298e4e0 fix: executions permission validation 2021-04-27 09:12:59 +02:00
Torsten Dittmann ee9a041e20 fix: breaking deps 2021-04-27 08:55:09 +02:00
Torsten Dittmann 4c511e4ee5 deps: update composer 2021-04-27 08:24:19 +02:00
Torsten Dittmann 1367e572bc tests: debug travis 2021-04-26 19:29:25 +02:00
Torsten Dittmann 140aa14a40 tests: debug travis 2021-04-26 18:43:22 +02:00
Torsten Dittmann 3838c935ce tests: debug travis 2021-04-26 18:40:54 +02:00
Torsten Dittmann 7084cc6479 tests: debug travis 2021-04-26 18:22:29 +02:00
Torsten Dittmann 18a927e522 tests: debug travis 2021-04-26 18:17:17 +02:00
Torsten Dittmann cc711df562 tests: debug travis 2021-04-26 18:16:58 +02:00
Torsten Dittmann 4b7ddb953c tests: debug travis 2021-04-26 18:13:01 +02:00
Torsten Dittmann fa8f337d9b tests: debug travis 2021-04-26 18:04:59 +02:00
Torsten Dittmann e3fa1e6e3e tests: debug travis 2021-04-26 17:59:44 +02:00
Torsten Dittmann 0c98ee1e4b tests: debug travis 2021-04-26 17:37:21 +02:00
Torsten Dittmann bc19c4c692 tests: debug travis 2021-04-26 17:18:41 +02:00
Torsten Dittmann 3a9b6e2e76 tests: debug travis 2021-04-26 16:57:21 +02:00
Torsten Dittmann e7fc22e003 tests: debug travis 2021-04-26 16:39:53 +02:00
Torsten Dittmann 8d0184af29 tests: debug travis 2021-04-26 16:28:48 +02:00
Torsten Dittmann 2d909a1e02 tests: debug travis 2021-04-26 14:35:46 +02:00
Torsten Dittmann 1bda8546a6 tests: debug travis 2021-04-26 14:06:37 +02:00
Torsten Dittmann 038a93b107 tests: debug travis 2021-04-26 12:52:21 +02:00
Torsten Dittmann a17bfffa42 tests: debug travis 2021-04-26 12:29:12 +02:00
Torsten Dittmann 72d820ec36 tests: debug travis 2021-04-26 12:12:49 +02:00
Torsten Dittmann 9b75f7b2aa tests: debug travis 2021-04-26 11:54:32 +02:00
Torsten Dittmann 061f3895be fix: test flow 2021-04-26 11:34:15 +02:00
Torsten Dittmann be9b49d696 fix: runtimes logo path 2021-04-26 10:14:02 +02:00
Eldad Fux 77fdd1ab35 Reverted 2021-04-23 23:53:14 +03:00
Eldad Fux f7fa0296f6 Updated image paths 2021-04-23 23:52:19 +03:00
Eldad Fux 61a73eec1f Updated vars order 2021-04-23 23:33:19 +03:00
Eldad Fux 1a4e813e45 Merge branch '0.8.x' of github.com:appwrite/appwrite into feat-god-user 2021-04-23 23:33:04 +03:00
Torsten Dittmann 62f7418ef4 revert: travis phpunit exec 2021-04-23 19:13:00 +02:00
Torsten Dittmann 204a3c9bf3 tests: debug travis 2021-04-23 18:51:00 +02:00
Torsten Dittmann ef57c355a0 tests: debug travis 2021-04-23 18:20:50 +02:00
Torsten Dittmann d2792b3527 tests: fix functions schedule 2021-04-23 17:08:18 +02:00
Torsten Dittmann 2c12396823 chore: update composer 2021-04-23 17:06:53 +02:00
Torsten Dittmann 3d960a2971 Merge branch '0.8.x' of https://github.com/appwrite/appwrite into feat-upgrade-php-version 2021-04-23 17:06:42 +02:00
Torsten Dittmann 72f4f3a6b9 tests: fix function execution 2021-04-23 17:05:17 +02:00
Torsten Dittmann 5b2549c003 deps: update swoole to 4.6.6 2021-04-23 16:43:29 +02:00
Eldad A. FuxandGitHub c80ddfb06e Merge pull request #947 from appwrite/feat-auth-limits
Feat Disable auth methods and limit number of users.
2021-04-23 17:13:07 +03:00
Eldad A. FuxandGitHub 4629cc1ac5 Merge pull request #1101 from TorstenDittmann/feat-upgrade-php-version-runtimes
feat: Introduce appwrite/php-runtimes
2021-04-23 16:21:06 +03:00
Torsten Dittmann cb5c88a4d0 fix: use new runtimes filter syntax 2021-04-23 10:40:45 +02:00
Torsten Dittmann a82531d6c8 deps: update appwrite/php-runtimes to 0.2.0 2021-04-23 10:22:44 +02:00
Eldad A. FuxandGitHub ba49f4d367 Merge branch '0.8.x' into feat-auth-limits 2021-04-23 09:34:16 +03:00
Eldad Fux 04d53eab7a Fixed missing permissions 2021-04-23 09:31:22 +03:00
Torsten Dittmann fe5c004a56 revert: php-runtimes to composer dep 2021-04-22 12:11:53 +02:00
Torsten Dittmann 7eb9891cf1 chore: update composer dep to github and adust readme 2021-04-22 12:07:57 +02:00
Torsten Dittmann 457aeb18be deps: update appwrite/php-runtimes to 0.1.* 2021-04-22 12:04:35 +02:00
Torsten Dittmann 26a747d29e feat: update new php-runtimes version 2021-04-22 11:26:10 +02:00
Eldad A. FuxandGitHub 9dd754959d Merge pull request #1103 from TorstenDittmann/fix-anon-login-error
fix: improve error message on anon login
2021-04-22 10:08:09 +03:00
Torsten Dittmann 5668579021 fix: improve error message on anon login 2021-04-21 16:54:05 +02:00
Torsten Dittmann 222b9ab097 chore: update changelog 2021-04-21 15:39:39 +02:00
Torsten Dittmann cc34719768 feat: preferences response model 2021-04-21 15:37:51 +02:00
Torsten Dittmann 664201c112 composer: remove unused system library 2021-04-21 14:21:21 +02:00
Torsten Dittmann 0719806885 fix: runtime whitelist 2021-04-21 13:27:02 +02:00
Torsten Dittmann 25b03c90f8 feat: introduce appwrite/php-runtimes 2021-04-21 13:02:54 +02:00
Eldad Fux 7fc3b95541 Updated SDK version 2021-04-21 13:13:37 +03:00
Eldad Fux 2bcfaffec3 Updated SDK version 2021-04-21 13:13:12 +03:00
Eldad Fux 5d1492b034 Fixed code examples 2021-04-21 09:54:28 +03:00
Eldad Fux 0a0af89a4d Updated CLI examples 2021-04-21 09:41:27 +03:00
Eldad Fux dcee9fc68e Updated specs 2021-04-21 09:38:27 +03:00
Eldad Fux 71f7de08c7 Merge branch 'dev' of github.com:appwrite/appwrite into dev 2021-04-21 09:33:08 +03:00
Eldad Fux 791de55713 Merge branch 'master' of github.com:appwrite/appwrite into dev 2021-04-21 09:31:01 +03:00
Eldad Fux c95342a260 Updated SDKs 2021-04-21 09:28:47 +03:00
Eldad Fux dff75f768a Updated CLI docs for 0.7.x 2021-04-21 08:59:55 +03:00
Eldad A. FuxandGitHub b0cb7a9b8d Merge pull request #1097 from TorstenDittmann/fix-false-boolean-properties
fix: save false values in database for filtering
2021-04-20 16:52:09 +03:00
Torsten Dittmann 56c2c039b2 tests: remove cloud function env tests 2021-04-20 14:35:07 +02:00
Torsten Dittmann 36665e19b1 tests: use only latest env version 2021-04-20 14:05:03 +02:00
Eldad A. FuxandGitHub a12db546ea Merge branch '0.8.x' into feat-auth-limits 2021-04-20 13:54:16 +03:00
Torsten Dittmann 6ed97886f9 tests: fix env skip for functions 2021-04-20 12:51:29 +02:00
Torsten Dittmann 26d8ef4e23 Revert "tests: add timeout after executing fiunction for webhooks"
This reverts commit 474f45c85e.
2021-04-20 12:28:30 +02:00
Torsten Dittmann f6c163d4a5 Revert "tests: adjust schedule for functions"
This reverts commit fe819ee326.
2021-04-20 12:28:23 +02:00
Torsten Dittmann 04fbb9b02b tests: temporarily disable tests 2021-04-20 12:27:41 +02:00
Torsten Dittmann fe819ee326 tests: adjust schedule for functions 2021-04-20 12:01:40 +02:00
Torsten Dittmann 474f45c85e tests: add timeout after executing fiunction for webhooks 2021-04-20 10:37:27 +02:00
Torsten Dittmann f40f82f91e fix: save false value in database for filtering 2021-04-20 10:05:09 +02:00
Torsten Dittmann d94ddf1ac5 Merge branch '0.8.x' of https://github.com/appwrite/appwrite into feat-upgrade-php-version 2021-04-20 09:11:40 +02:00
Eldad Fux 5318eac6be Test Swagger files 2021-04-20 09:02:50 +03:00
Eldad A. FuxandGitHub 7ad56d2a29 Merge pull request #1077 from appwrite/refactor-whitelist-type
Refactor with updated validators
2021-04-20 08:54:31 +03:00
Eldad A. FuxandGitHub c6af32fb57 Merge pull request #726 from appwrite/feat-465-add-arm-support
Feat 465 add ARM support
2021-04-20 00:50:49 +03:00
Eldad Fux 9ba6b38014 Fixed swagger test 2021-04-20 00:17:42 +03:00
Torsten Dittmann 94d2ec5578 Merge branch '0.8.x' of https://github.com/appwrite/appwrite into feat-upgrade-php-version 2021-04-19 18:08:20 +02:00
kodumbeats 5f60c09158 Update composer to calculate hashes 2021-04-19 09:32:27 -04:00
kodumbeats d609940de1 Merge branch 'dev' into refactor-whitelist-type 2021-04-19 09:29:55 -04:00
Torsten Dittmann 74f06d12cd chore: add arm to changelog 2021-04-19 14:44:08 +02:00
Torsten Dittmann 5433f59771 fix: remove arm support from deno environments 2021-04-19 13:20:35 +02:00
Eldad Fux c8a5d05a3e Merge branch '0.8.x' of github.com:appwrite/appwrite into feat-auth-limits 2021-04-19 14:19:57 +03:00
Torsten Dittmann 70ee7c3fcb Merge branch 'feat-465-add-arm-support' of https://github.com/appwrite/appwrite into feat-465-add-arm-support 2021-04-19 12:33:49 +02:00
Torsten Dittmann dd5d5f59e0 fix: cloud functions environment 2021-04-19 12:31:40 +02:00
Torsten Dittmann f102e43704 Merge branch '0.8.x' of https://github.com/appwrite/appwrite into feat-465-add-arm-support 2021-04-19 11:35:57 +02:00
Eldad Fux fdfcd0cfb2 Updated Dart note 2021-04-18 14:24:37 +03:00
Eldad A. FuxandGitHub fea932551b Merge pull request #1040 from appwrite/feat-new-demos
Added list of web demos
2021-04-17 12:23:01 +03:00
Eldad Fux 7dc51e93e4 Hide dotnet 2021-04-17 12:02:51 +03:00
Eldad Fux 181fb05fd4 Fixed tests 2021-04-17 01:10:27 +03:00
Eldad Fux 5c6d17bd87 Fixed tests 2021-04-17 00:25:25 +03:00
Eldad A. FuxandGitHub 65f9c97e8a Merge pull request #1094 from appwrite/fix-avatars-shared-cache
Fixed cached bug
2021-04-17 00:15:43 +03:00
Eldad A. FuxandGitHub 7698b17b19 Merge pull request #1095 from appwrite/fix-dashboard-tooltip
fix: dashboard tooltip message
2021-04-17 00:15:32 +03:00
Eldad A. FuxandGitHub 1138752d65 Merge branch 'dev' into fix-dashboard-tooltip 2021-04-17 00:15:13 +03:00
Christy Jacob 6786b744bc fix: dashboard tooltip message 2021-04-17 02:10:49 +05:30
Eldad Fux 293badbd90 Fixed cached bug 2021-04-16 22:04:42 +03:00
Torsten Dittmann bd02df15af deps: update composer after merge 2021-04-16 19:10:12 +02:00
Torsten Dittmann e4c02dda80 Merge branch '0.8.x' of https://github.com/appwrite/appwrite into feat-upgrade-php-version 2021-04-16 19:09:34 +02:00
Torsten Dittmann ca8920a152 style: fix typo 2021-04-16 19:07:25 +02:00
Torsten Dittmann 3b989cf6a7 fix: anonymous account tests 2021-04-16 18:50:16 +02:00
Torsten Dittmann 2f7f8ab03d test: disabling coroutine in functions worker 2021-04-16 17:53:36 +02:00
Eldad Fux f2a54d8f00 Fixed functions tests 2021-04-16 18:13:03 +03:00
kodumbeats 64081ea048 Replace Mock with new Wildcard 2021-04-16 12:09:39 +00:00
Eldad Fux 3ece691efc Updated SDKs 2021-04-16 14:24:03 +03:00
Eldad Fux 611d781562 Merge branch '0.8.x' of github.com:appwrite/appwrite into feat-465-add-arm-support 2021-04-16 14:03:43 +03:00
Eldad A. FuxandGitHub 69607e6839 Merge pull request #1042 from appwrite/feat-jwt-support-for-sdks
Feat JWT support for SDKs
2021-04-16 12:07:23 +03:00
Eldad Fux 85ffcb3e7a Added JWT auth to client SDKs 2021-04-16 11:01:02 +03:00
Eldad Fux 63c93aab1f Added JWT auth to client SDKs 2021-04-16 10:59:41 +03:00
Eldad Fux dddc8100e8 Updated swagger files for 0.8.x 2021-04-16 10:49:18 +03:00
Eldad A. FuxandGitHub f62a06da74 Merge pull request #1092 from TorstenDittmann/fix-migrate-0.8
fix: migration script to 0.8
2021-04-16 10:39:07 +03:00
Eldad Fux ce8b3686d8 Replaced sdk.security with sdk.auth 2021-04-16 10:22:17 +03:00
Eldad Fux 7a0ff7699a Merge branch '0.8.x' of github.com:appwrite/appwrite into feat-jwt-support-for-sdks 2021-04-16 10:20:12 +03:00
Torsten Dittmann 52574d40dd fix: comparing multidimensional array on migration 2021-04-16 09:08:42 +02:00
kodumbeats 20f08f79ac Validators refactored out of utopia 2021-04-15 21:50:33 +00:00
kodumbeats 604b3217f3 Use validator type constants 2021-04-15 16:33:47 -04:00
Eldad A. FuxandGitHub 42a449da6c Merge pull request #1087 from TorstenDittmann/refactor-whitelist-type-spec
Refactor: whitelist type for spec generation
2021-04-15 23:23:32 +03:00
Eldad Fux be344c2b38 Updated CLI version 2021-04-15 21:04:51 +03:00
Torsten Dittmann 08586aa78c deps: update composer 2021-04-15 19:14:56 +02:00
Torsten Dittmann f6aa9e8108 fix: migration tests 2021-04-15 19:13:29 +02:00
Eldad A. FuxandGitHub 1336ea69e4 Merge pull request #1086 from TorstenDittmann/patch-npm-deps
deps: update npm packages and add scripts
2021-04-15 19:46:04 +03:00
Eldad A. FuxandGitHub 5148c5419c Merge pull request #1008 from appwrite/feat-new-image-features
feat-new-image-features
2021-04-15 15:48:42 +03:00
Eldad Fux e2f543cd85 Merge branch 'dev' of github.com:appwrite/appwrite into 0.8.x 2021-04-15 12:01:52 +03:00
Eldad A. FuxandGitHub c5029028f3 Merge pull request #1073 from lohanidamodar/feat-deno-1.8-functions-env
feat-deno-1.8-functions-env
2021-04-15 11:39:59 +03:00
Eldad A. FuxandGitHub e61f50f514 Merge pull request #1088 from TorstenDittmann/feat-abuse-limit-teaminvite-storage
Feat: Introduce new abuse limits
2021-04-15 11:37:46 +03:00
Eldad A. FuxandGitHub 8c6c3627eb Merge pull request #1091 from TorstenDittmann/fix-migration-0.8
fix: migration for 0.8.x
2021-04-15 10:59:03 +03:00
Torsten Dittmann d5694815f3 fix: migration for 0.8.x 2021-04-15 09:56:45 +02:00
Torsten DittmannandGitHub 9b4fca1212 Update CHANGES.md 2021-04-15 09:45:20 +02:00
Torsten DittmannandGitHub 15c80628ac Update storage.php 2021-04-15 09:45:05 +02:00
Eldad A. FuxandGitHub e3e28719be Merge pull request #1089 from TorstenDittmann/rename-users-delete-method
Rename: users delete method
2021-04-15 09:58:55 +03:00
Damodar Lohani 1f37f7da29 composer update 2021-04-15 11:55:39 +05:45
Torsten Dittmann b7833a862b fix: disable co-routine hooks 2021-04-14 17:56:15 +02:00
Torsten Dittmann 74908f4965 fix: disable co-routine hooks 2021-04-14 17:55:08 +02:00
Torsten Dittmann 8f7c679604 tests: enable tests again 2021-04-14 17:25:30 +02:00
Torsten Dittmann 32587f9d80 tests: disable test 2021-04-14 17:09:36 +02:00
Torsten Dittmann 942bd4d56f fix: collection unit test 2021-04-14 16:39:04 +02:00
Torsten Dittmann d97e1674aa tests: fix 2021-04-14 15:07:26 +02:00
Torsten Dittmann c24c17f1a2 Merge branch '0.8.x' of https://github.com/appwrite/appwrite into rename-users-delete-method 2021-04-14 13:10:54 +02:00
Torsten Dittmann e021b8795a fix: enable coroutine in functions worker 2021-04-14 12:40:55 +02:00
Torsten Dittmann 3829b4b8da Merge branch '0.8.x' of https://github.com/appwrite/appwrite into feat-auth-limits 2021-04-14 12:36:40 +02:00
Eldad Fux 43b97a5364 Merge branch '0.8.x' of github.com:appwrite/appwrite into 0.8.x 2021-04-14 12:02:24 +03:00
Eldad Fux 994dd3164f Merge branch 'dev' of github.com:appwrite/appwrite into 0.8.x 2021-04-14 12:02:17 +03:00
Torsten Dittmann 0b4d7f0844 Merge branch '0.8.x' of https://github.com/appwrite/appwrite into rename-users-delete-method 2021-04-14 10:21:35 +02:00
Torsten Dittmann 282bdd3a14 changelog: updated! 2021-04-14 10:20:05 +02:00
Eldad A. FuxandGitHub c961382fb7 Merge pull request #1090 from alexweininger/patch-1
doc-na-Make update password docs more clear.
2021-04-14 08:09:16 +03:00
Alex WeiningerandGitHub 02061701c0 Make update password docs more clear. 2021-04-13 21:12:09 -07:00
Eldad Fux f73a68b63d Fixed demo name 2021-04-14 00:22:27 +03:00
Torsten Dittmann 004d3d5270 rename: users delete method 2021-04-13 13:01:33 +02:00
Torsten Dittmann e0fa4d6856 fix: adapt storage limit 2021-04-13 11:41:10 +02:00
Torsten Dittmann 3e2dcb2cac feat: add abuse limit to file upload 2021-04-13 11:38:48 +02:00
Torsten Dittmann 7e7662096a feat: add abuse limit to team invite 2021-04-13 11:38:40 +02:00
Torsten Dittmann 20e858dbfe fix: validator class and spec generator 2021-04-13 10:46:30 +02:00
Torsten Dittmann 7d08c30672 Merge branch 'dev' of https://github.com/appwrite/appwrite into refactor-whitelist-type 2021-04-13 09:57:26 +02:00
Torsten Dittmann c3150ce301 deps: update npm packages and add scripts 2021-04-13 09:30:23 +02:00
Damodar Lohani 509154afcc Merge branch 'feat-deno-1.8-functions-env' of github.com:lohanidamodar/appwrite into feat-deno-1.8-functions-env 2021-04-13 12:27:25 +05:45
Damodar Lohani 7245b40da0 Merge branch 'dev' of github.com:appwrite/appwrite into feat-deno-1.8-functions-env 2021-04-13 12:27:17 +05:45
Eldad A. FuxandGitHub 3a60e421ac Merge pull request #1075 from TorstenDittmann/feat-document-response-model
Feat: Document Response Model
2021-04-13 07:09:09 +03:00
Eldad A. FuxandGitHub f48846f64b Merge pull request #1070 from appwrite/fix-form-array-casting
Fix form array casting in dashboard
2021-04-13 07:07:35 +03:00
Eldad A. FuxandGitHub 74c2def989 Merge pull request #1069 from appwrite/fix-collection-rules-form
Fix collection document rule form in dashboard
2021-04-13 07:06:36 +03:00
kodumbeats 84aa5f6a0d Merge branch 'dev' into refactor-whitelist-type 2021-04-12 12:34:35 -04:00
Torsten Dittmann e7265c392d Merge branch 'dev' of https://github.com/appwrite/appwrite into feat-document-response-model 2021-04-12 09:29:27 +02:00
Torsten Dittmann 666c2d7b6f Merge branch 'dev' of https://github.com/appwrite/appwrite into fix-collection-rules-form 2021-04-12 09:28:59 +02:00
Torsten Dittmann 04c06cc6c5 Merge branch 'dev' of https://github.com/appwrite/appwrite into fix-form-array-casting 2021-04-12 09:28:26 +02:00
Damodar Lohani a88b93d1cb Merge branch '0.8.x' into feat-new-image-features 2021-04-12 06:22:04 +05:45
Eldad Fux a2f1aa55a2 Updated description 2021-04-11 23:27:06 +03:00
Eldad Fux 2d8b8ef2ff Updated config 2021-04-11 22:26:33 +03:00
Eldad Fux 318ed0b1f2 Updated git repos 2021-04-11 20:49:40 +03:00
Eldad Fux 72a2ca08b0 Updated Node SDK 2021-04-10 19:14:15 +03:00
Torsten Dittmann 9dc206051f Merge branch '0.8.x' of https://github.com/appwrite/appwrite into feat-upgrade-php-version 2021-04-10 16:25:04 +02:00
Eldad A. FuxandGitHub f2e85df8de Merge pull request #1081 from appwrite/dev
Sync 0.8.x with dev
2021-04-10 17:23:13 +03:00
Eldad A. FuxandGitHub 61db72aa1e Merge pull request #1080 from TorstenDittmann/fix-disable-clamav
fix: disable clamav for development and ci
2021-04-10 17:19:35 +03:00
Torsten Dittmann 2150c7e63f fix: tests for docker services 2021-04-10 15:54:03 +02:00
Torsten Dittmann 8b9cf9abdd fix: disable clamav for development and ci 2021-04-10 15:28:55 +02:00
Eldad Fux 2c9de1d488 Merge branch '0.8.x' of github.com:appwrite/appwrite into 0.8.x 2021-04-10 15:15:22 +03:00
Eldad A. FuxandGitHub 1e1dfe8787 Merge branch 'dev' into feat-deno-1.8-functions-env 2021-04-10 11:29:05 +03:00
Torsten Dittmann 65c3e2536e deps: fix missplaced dash 2021-04-09 13:02:11 +02:00
Torsten Dittmann 6dd2cc1af2 deps: set imagich to master version until php8 is officialy released 2021-04-09 12:54:59 +02:00
Torsten Dittmann 6b3ea91e66 deps: update php extensions 2021-04-09 12:41:22 +02:00
Torsten Dittmann 8a93f404e9 deps: update dependencies 2021-04-09 12:35:44 +02:00
Damodar Lohani 6c8cb0545b handle when opacity is set to 0 2021-04-09 13:41:49 +05:45
Damodar Lohani b7920ab26c fix issue with opacity 2021-04-09 13:27:45 +05:45
Damodar Lohani d82bb692b2 fix for border with border radius issue 2021-04-09 12:49:46 +05:45
kodumbeats bc54b8b35e Set whitelist type when not string 2021-04-08 09:41:54 -04:00
Damodar Lohani 7b81ce2550 updating cache key 2021-04-08 16:42:30 +05:45
Torsten Dittmann 3cc08c849f fix: add error types 2021-04-08 11:27:59 +02:00
Torsten Dittmann ccf114120e fix: add nested models in models 2021-04-08 11:24:41 +02:00
Torsten Dittmann 8bac3caeb5 feat: filter response models in openapi3 spec 2021-04-08 10:46:45 +02:00
Torsten Dittmann d8fd30cffa feat: filter response models in swagger spec 2021-04-08 10:39:44 +02:00
Torsten Dittmann 3ff66179c5 feat: add document response model that extends any type 2021-04-08 10:39:23 +02:00
Damodar Lohani 4e24c5aa46 default functions env contains latest deno 2021-04-07 12:30:50 +05:45
Damodar Lohani e55f62a0a5 deno 1.8.3 upgrade 2021-04-07 12:30:05 +05:45
Torsten Dittmann a8af10dbca build scripts 2021-04-06 18:12:32 +02:00
Torsten Dittmann 317a0b6324 build scripts 2021-04-06 15:48:28 +02:00
Torsten DittmannandGitHub fd5ff9ac8f Update form.js 2021-04-06 15:40:24 +02:00
Torsten DittmannandGitHub 03111a2a46 Update collection.phtml 2021-04-06 13:52:49 +02:00
Torsten DittmannandGitHub 3c7b62d889 Update form.js 2021-04-06 13:51:59 +02:00
Eldad A. FuxandGitHub 19e9582df2 Merge branch '0.7.x' into feat-upgrade-php-version 2021-04-05 14:56:45 +03:00
Eldad A. FuxandGitHub 7ee487a0cb Merge pull request #1021 from appwrite/refactor-validators
Move validators from utopia
2021-04-05 14:52:07 +03:00
Eldad Fux 64b243880b Update change log 2021-04-05 14:49:08 +03:00
Eldad A. FuxandGitHub 86df88781f Merge pull request #1064 from lohanidamodar/feat-disable-clamav
Feat Disable Clamav
2021-04-05 14:48:23 +03:00
Damodar Lohani 5f3b44d5b7 remove old file 2021-04-05 12:47:48 +05:45
Damodar Lohani ec87c11a0a production doc section to enable ClamAV 2021-04-05 12:33:45 +05:45
Damodar Lohani 272607ad3f update description 2021-04-05 12:25:37 +05:45
Eldad A. FuxandGitHub b15aef0c5d Merge pull request #1056 from appwrite/feat-locale-env-support
feat-locale-env-support
2021-04-05 09:29:37 +03:00
d10c758e80 parameter description changes
Co-authored-by: Christy Jacob <christyjacob4@gmail.com>
2021-04-04 14:25:03 +05:45
Eldad A. FuxandGitHub e801fa383d Merge pull request #1044 from appwrite/feat-python-3.9-env
feat-python-3.9-env
2021-04-04 11:36:33 +03:00
Eldad A. FuxandGitHub 6b3f6f97e5 Merge pull request #1062 from appwrite/feat-consistent-bottom-controls
Feat: Consistent Bottom Controls
2021-04-04 11:36:14 +03:00
Damodar Lohani 7794204acb disable clamav stuff on installation 2021-04-04 07:55:56 +05:45
Damodar Lohani c3fb2e6c46 adding locale to dev docker compose, dockerfile and compose and variables 2021-04-04 07:15:41 +05:45
Damodar Lohani a9950edcc1 updating default functions env python env 2021-04-04 07:08:41 +05:45
Eldad Fux d9528ef1ce Update anon login limits and tests 2021-04-03 11:56:32 +03:00
Eldad Fux f070eb0a3a Merge branch '0.8.x' of github.com:appwrite/appwrite into feat-auth-limits 2021-04-03 10:16:46 +03:00
Eldad Fux 6bd9169323 Updated change log 2021-04-03 09:47:27 +03:00
Eldad Fux ae2cc44817 First commit 2021-04-03 09:29:13 +03:00
Eldad Fux a9dd80af76 Updated change log 2021-04-03 09:06:24 +03:00
Eldad A. FuxandGitHub 02bbc7c2db Merge pull request #989 from lohanidamodar/feat-dart-env-update
feat-dart-env-update
2021-04-03 09:04:05 +03:00
Eldad A. FuxandGitHub f97b3e34aa Merge pull request #1045 from appwrite/refactor-event-payload-to-data
Refactor event payload to data
2021-04-02 08:14:11 +03:00
Eldad A. FuxandGitHub 2f17dba1be Merge pull request #1051 from lohanidamodar/fix-getting-started-self-signed-cert
fix-getting-started-self-signed-cert
2021-04-02 08:13:21 +03:00
Damodar Lohani 5d0ea6a45f Set default locale on .env #1052 2021-04-01 11:59:23 +05:45
Damodar Lohani 1c9fbf0b17 self signed certs on readmes 2021-03-31 07:15:25 +05:45
Eldad A. FuxandGitHub 83749ba2ab Merge pull request #1050 from appwrite/dependabot/npm_and_yarn/y18n-3.2.2
Bump y18n from 3.2.1 to 3.2.2
2021-03-30 23:24:42 +03:00
dependabot[bot]andGitHub b994a49dcc Bump y18n from 3.2.1 to 3.2.2
Bumps [y18n](https://github.com/yargs/y18n) from 3.2.1 to 3.2.2.
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-30 18:21:45 +00:00
Eldad A. FuxandGitHub c446fa1534 Update README.md 2021-03-30 20:23:47 +03:00
kodumbeats 456793ebd8 Added space for styling and consistency 2021-03-30 07:42:58 -04:00
kodumbeats aeb0cb9eac Correct changelog var name 2021-03-30 07:42:40 -04:00
kodumbeats c491662487 Remove utopia license comments 2021-03-30 07:25:21 -04:00
kodumbeats be75fc08cb Function env var noted as breaking change 2021-03-29 15:34:43 -04:00
kodumbeatsandGitHub d4b107bf1d Merge branch '0.8.x' into refactor-event-payload-to-data 2021-03-29 15:32:14 -04:00
kodumbeats 365d2d50dd Update testing functions with new env name 2021-03-29 14:31:41 -04:00
Eldad A. FuxandGitHub cd6263e8b7 Merge pull request #922 from TorstenDittmann/refactor-user-tokens
refactor-user-tokens
2021-03-29 21:00:12 +03:00
kodumbeats 9f8e7358d4 Refactor event $payload to $eventData 2021-03-29 14:00:10 -04:00
Torsten Dittmann df69799ebb adapt to review 2021-03-29 13:22:50 +02:00
Torsten Dittmann f5fa640e68 remove providerUid on session verification for anon login 2021-03-29 12:29:18 +02:00
Torsten Dittmann ceeb30fd4f adapt to anon login 2021-03-29 11:16:56 +02:00
Torsten Dittmann 078a07d6b8 Merge branch '0.8.x' of https://github.com/appwrite/appwrite into refactor-user-tokens 2021-03-29 11:07:18 +02:00
Damodar Lohani 617edbf3ff fix deno 1.8 env 2021-03-29 13:14:51 +05:45
Damodar Lohani 30fc7df975 python functions env 3.9 2021-03-29 13:14:20 +05:45
Damodar Lohani ed90bc1d24 deno 1.8 function env 2021-03-29 12:49:42 +05:45
Eldad Fux 0f67c500a2 Fixed missing API scope 2021-03-29 01:56:05 +03:00
Eldad Fux a22243b998 Updated specs 2021-03-29 01:36:25 +03:00
Eldad Fux 3c0d74ec81 Merge branch '0.8.x' of github.com:appwrite/appwrite into feat-jwt-support-for-sdks 2021-03-29 00:52:29 +03:00
Eldad Fux 9b25bcb1b6 Merge branch 'master' of github.com:appwrite/appwrite into feat-jwt-support-for-sdks 2021-03-29 00:52:14 +03:00
Eldad Fux 6e5c2ecf90 Merge branch 'dev' of github.com:appwrite/appwrite into 0.8.x 2021-03-29 00:51:30 +03:00
Eldad Fux b74a88262b Merge branch 'master' of github.com:appwrite/appwrite into dev 2021-03-29 00:50:31 +03:00
Eldad Fux d60e43ddaa Merge branch 'master' of github.com:appwrite/appwrite 2021-03-29 00:49:34 +03:00
Eldad Fux 1174216bfd Updated changelog 2021-03-29 00:49:29 +03:00
Eldad Fux 72e0daf2bd Updated version number 2021-03-29 00:49:07 +03:00
Eldad Fux aaa43bb154 Added JWT example 2021-03-29 00:47:17 +03:00
Eldad Fux 31c7c31d33 Updated version list 2021-03-29 00:38:21 +03:00
Eldad Fux c7559758c3 Updated 0.8.x specs 2021-03-29 00:37:23 +03:00
Eldad Fux 8ea83b24c3 Added new JWT as SDK auth method 2021-03-29 00:22:12 +03:00
Eldad A. FuxandGitHub d496ba37e2 Update README.md 2021-03-28 16:28:47 +03:00
Eldad Fux db4530a5e5 Merge branch 'dev' of github.com:appwrite/appwrite into 0.8.x 2021-03-28 16:13:53 +03:00
Eldad Fux 298edef242 Updated change log 2021-03-28 15:36:59 +03:00
Eldad Fux 70e809fa92 Fixed default value for https force option 2021-03-28 15:36:15 +03:00
Damodar Lohani cd84de8fae Merge branch '0.8.x' of github.com:appwrite/appwrite into feat-new-image-features 2021-03-28 16:01:40 +05:45
Damodar Lohani 2d6ba7c861 fix docker-compose conflict 2021-03-28 15:59:04 +05:45
Eldad A. FuxandGitHub 5d687ce3dd Merge pull request #914 from TorstenDittmann/feat-anon-login
feat-anon-login
2021-03-28 12:48:30 +03:00
Eldad A. FuxandGitHub 2df9b9ff0a Merge pull request #1034 from lohanidamodar/feat-error-handling-section-on-sdks
feat-error-handling-section-on-sdks
2021-03-28 12:40:14 +03:00
Eldad A. FuxandGitHub 133f28a3d1 Merge pull request #1017 from TorstenDittmann/feat-getting-started-web
Add Web Getting started
2021-03-28 12:39:51 +03:00
Eldad Fux 7a400afb5b Merge branch 'master' of github.com:appwrite/appwrite into 0.8.x 2021-03-27 01:36:41 +03:00
Eldad Fux d05c2b4dda Added list of web demos 2021-03-26 21:49:04 +03:00
Damodar Lohani 0e20eaac77 ruby sdk exception handling section 2021-03-26 18:20:18 +05:45
Damodar Lohani 00934a3d3e Merge branch 'dev' into feat-new-image-features 2021-03-26 17:34:02 +05:45
Damodar Lohani d069e83b79 python error handling 2021-03-26 14:22:57 +05:45
Damodar Lohani 7db2ad9222 php sdk error handling 2021-03-26 14:19:47 +05:45
Damodar Lohani 447b21bd7e node sdk error handling 2021-03-26 14:05:23 +05:45
Damodar Lohani d2e0472091 flutter error handling 2021-03-26 14:03:49 +05:45
Damodar Lohani d52825d134 .net error handling 2021-03-26 13:45:50 +05:45
Damodar Lohani e25a632cfa deno error handling 2021-03-26 13:41:57 +05:45
Torsten DittmannandGitHub c2608c5629 Update GETTING_STARTED.md 2021-03-26 08:56:32 +01:00
Damodar Lohani ca5911b4f1 fix typo 2021-03-26 13:32:06 +05:45
Damodar Lohani 9c5db44104 dart error handling section 2021-03-26 13:01:14 +05:45
Damodar Lohani 1dbe8f980c test and resources for new preview api features 2021-03-26 11:27:39 +05:45
kodumbeats 2175302e9b ClamAV was reverted to v1.2.0 2021-03-25 15:08:02 -04:00
Torsten Dittmann 38d58a8060 fix default code param on tag creation 2021-03-25 17:53:27 +01:00
Eldad Fux 889111ca1c Updated Flutter SDK 2021-03-25 15:23:37 +02:00
Eldad A. FuxandGitHub 6a8098f30a Merge pull request #1027 from rjn01/Doc-Corrected-the-spelling
Doc: Corrected the spelling in tutorials and updated the Contributing.md
2021-03-25 07:16:29 +02:00
rjn01 f92cc587b5 Merge https://github.com/appwrite/appwrite into Doc-Corrected-the-spelling 2021-03-25 00:58:56 +05:30
rjn01 22e430625b Updated Contributing.md 2021-03-25 00:55:08 +05:30
rjn01 4907ffefd8 Doc: Corrected-the-spelling 2021-03-25 00:34:04 +05:30
rjn01 44c2a811da Doc: Corrected-the-spelling 2021-03-25 00:31:55 +05:30
kodumbeats 448276fcd4 Validator constants not defined 2021-03-24 14:35:36 -04:00
kodumbeats 31bf1bdcef Update validator namespaces 2021-03-24 14:34:47 -04:00
kodumbeats 07140bda5a Replace utopia libs with native validators 2021-03-24 13:47:43 -04:00
kodumbeats 7f485ce536 Update validator namespaces 2021-03-24 13:47:17 -04:00
kodumbeats 871182b066 Merge remote-tracking branch 'origin/dev' into refactor-validators 2021-03-24 12:51:40 -04:00
Eldad A. FuxandGitHub a365234be7 Merge pull request #1026 from appwrite/0.7.x
0.7.x
2021-03-24 17:15:12 +02:00
kodumbeats 2f90b5a343 Refactor EVENT_PAYLOAD to EVENT_DATA 2021-03-24 09:36:36 -04:00
Eldad A. FuxandGitHub 5e6ea672b2 Merge pull request #1023 from appwrite/dev
0.7.2 release
2021-03-24 14:29:49 +02:00
Eldad Fux 86d962e17f Updated version numbers 2021-03-24 14:29:19 +02:00
Eldad Fux 9709667fc1 Updated changelog 2021-03-24 14:27:12 +02:00
Eldad Fux e36df74be3 Enabled ClamAV 2021-03-24 12:38:19 +02:00
Eldad Fux 90adfe8760 Revreted back to ClamAV 1.2 2021-03-24 12:37:58 +02:00
Eldad A. FuxandGitHub 19d319dde7 Merge pull request #1024 from TorstenDittmann/feat-update-analytics
bump utopia/analytics to 0.2.0
2021-03-24 12:07:32 +02:00
Torsten Dittmann 90a9127baf bump utopia/analytics to 0.2.0 2021-03-24 10:44:24 +01:00
Eldad A. FuxandGitHub 8c6d01e90d Merge pull request #1020 from JulianWebb/docs-update-docker-compose-link-in-readme
Updated the docker-compose link in the Installation Section of the README
2021-03-23 23:16:10 +02:00
Eldad A. FuxandGitHub 16eb91bf25 Merge pull request #1002 from appwrite/feat-new-timestamp-log
Added timestamp
2021-03-23 23:15:37 +02:00
kodumbeats b262ebfeb3 Move validators from utopia 2021-03-23 13:27:51 -04:00
Julian Webb 390e8ed069 Updated the link in the Installation Section of the README to point to an up to date version 2021-03-23 08:26:48 -07:00
Eldad A. FuxandGitHub 96610bfccd Merge pull request #1016 from TorstenDittmann/feat-getting-start-dotnet
Add .NET Getting started
2021-03-23 17:10:00 +02:00
Eldad A. FuxandGitHub 96d13aa996 Merge pull request #1006 from lohanidamodar/feat-tests-time
feat-tests-time
2021-03-23 15:28:31 +02:00
Eldad A. FuxandGitHub 0cb3f09363 Merge pull request #1019 from JulianWebb/doc-fixing-broken-environment-variables-link
Doc fixing broken environment variables link
2021-03-23 15:10:12 +02:00
Julian Webb fef109ed1b Fixed misspelling of "beginner" and corrected the issue label under "Advanced Topics" in CONTRIBUTING.md 2021-03-23 06:03:46 -07:00
Julian Webb 3a9f8d1736 Changed 'environmental variables' link from a relative one to one pointing toward the documentation on the appwrite website 2021-03-23 05:58:53 -07:00
Torsten Dittmann 79f9801ec2 fix typo 2021-03-23 12:51:56 +01:00
Torsten Dittmann b4292eb366 add web getting started 2021-03-23 12:51:21 +01:00
Eldad Fux 464fc5a813 Merge branch 'dev' of github.com:appwrite/appwrite into feat-new-timestamp-log 2021-03-23 13:37:24 +02:00
Eldad Fux bd17ac8f28 Merge branch 'dev' of github.com:appwrite/appwrite into dev 2021-03-23 13:36:26 +02:00
Eldad Fux caca0f8c52 Updated the changelog for 0.7.2 2021-03-23 13:36:20 +02:00
Eldad A. FuxandGitHub cbfe60a87a Merge pull request #1015 from lohanidamodar/feat-ruby-getting-started
feat-ruby-getting-started
2021-03-23 13:09:56 +02:00
Eldad A. FuxandGitHub 59e36b365b Merge pull request #1007 from appwrite/feat-set-default-permissions-to-user
Updated default permissions
2021-03-23 13:09:09 +02:00
Torsten Dittmann 32906110a8 add dotnet getting started 2021-03-23 11:35:45 +01:00
Damodar Lohani dbac4083ad fix missing param rotation 2021-03-23 15:53:09 +05:45
Damodar Lohani 144c2aa61b Merge branch 'dev' into feat-tests-time 2021-03-23 15:18:20 +05:45
Eldad A. FuxandGitHub 22350a7049 Merge pull request #993 from lohanidamodar/fix-redis-auth-on-workers
fix-redis-auth-on-workers
2021-03-23 11:21:56 +02:00
Torsten Dittmann 74853da211 Merge branch 'feat-anon-login' of https://github.com/TorstenDittmann/appwrite into feat-anon-login 2021-03-23 09:39:03 +01:00
Torsten Dittmann b9017549c2 remove env variable in favor of #947 2021-03-23 09:38:56 +01:00
Eldad Fux 4df643f541 Merge branch 'dev' of github.com:appwrite/appwrite into feat-new-timestamp-log 2021-03-23 10:19:24 +02:00
Eldad Fux a9d05968a1 Merge branch 'dev' of github.com:appwrite/appwrite into feat-set-default-permissions-to-user 2021-03-23 10:09:59 +02:00
Damodar Lohani 9f5fb08363 ruby getting started 2021-03-23 13:50:40 +05:45
Eldad A. FuxandGitHub 5399d0c7b7 Merge pull request #1013 from appwrite/fix-redirect-warning
Fix Redirect Warning
2021-03-23 09:59:43 +02:00
Damodar Lohani 64996379fc Merge branch 'dev' into feat-dart-env-update 2021-03-23 13:19:30 +05:45
Damodar Lohani ee6536f224 Merge branch 'dev' into feat-tests-time 2021-03-23 13:18:51 +05:45
Damodar Lohani 464486743a Merge branch 'dev' into feat-new-image-features 2021-03-23 13:18:03 +05:45
Damodar Lohani 40680188b2 Merge branch 'dev' into fix-redis-auth-on-workers 2021-03-23 12:37:06 +05:45
Eldad A. FuxandGitHub c421741386 Merge pull request #967 from appwrite/feat-962-pass-data-to-function-execution
Pass custom function $data to execution
2021-03-23 00:53:31 +02:00
Eldad Fux 5ab87a107b Updated utopia libs 2021-03-23 00:42:25 +02:00
Eldad A. FuxandGitHub d17c830b8c Merge pull request #999 from appwrite/feat-upgrade-abuse-recaptcha
Upgrade utopia-php/abuse to version 0.4.0
2021-03-22 22:45:33 +02:00
Eldad Fux 65f77351f4 Merge branch 'dev' of github.com:appwrite/appwrite into feat-new-timestamp-log 2021-03-22 22:09:41 +02:00
Eldad Fux 866dd3cad1 Merge branch 'dev' of github.com:appwrite/appwrite into feat-set-default-permissions-to-user 2021-03-22 22:09:01 +02:00
Eldad Fux 7eb45d30f4 Updated change log 2021-03-22 22:07:59 +02:00
Eldad A. FuxandGitHub 98784dfdf8 Merge pull request #1010 from appwrite/fix-1001-worker-certificates-error-handling
Throw certbot error on nonzero exit code
2021-03-22 22:03:51 +02:00
kodumbeats d33b12bd61 Merge remote-tracking branch 'origin/dev' into feat-962-pass-data-to-function-execution 2021-03-22 12:47:06 -04:00
kodumbeats 1893b87eed Merge remote-tracking branch 'origin/dev' into feat-upgrade-abuse-recaptcha 2021-03-22 12:45:55 -04:00
kodumbeats a3c6fef973 Merge remote-tracking branch 'origin/dev' into fix-1001-worker-certificates-error-handling 2021-03-22 12:37:12 -04:00
Eldad Fux a76016fa37 Fixed functions tests 2021-03-22 18:19:05 +02:00
kodumbeatsandGitHub 011e0ca677 Merge branch 'dev' into feat-upgrade-abuse-recaptcha 2021-03-22 08:55:07 -04:00
kodumbeats d6fc03ca63 Throw error only on nonzero exit code 2021-03-22 08:44:13 -04:00
kodumbeatsandGitHub 64e349be4d Merge branch '0.8.x' into feat-962-pass-data-to-function-execution 2021-03-22 07:15:09 -04:00
kodumbeats 22ba2e4d12 Merge dev branch 2021-03-22 07:05:53 -04:00
Eldad Fux 46c465b80e Added some fixes and dedicated tests 2021-03-22 09:34:51 +02:00
Damodar Lohani 0ac81f8f69 update image preview api 2021-03-22 12:39:42 +05:45
Damodar Lohani b7dec3a4f4 fix print line 2021-03-22 10:34:03 +05:45
Eldad Fux e05da0ce3c Fixed comments 2021-03-22 00:26:00 +02:00
Eldad Fux b5846f5a79 Updated default permissions 2021-03-22 00:17:20 +02:00
Damodar Lohani 9843d063f6 autoloading test hook 2021-03-21 20:13:03 +05:45
Damodar Lohani 6b8876a82e enabling extension in phpunit 2021-03-21 20:12:50 +05:45
Damodar Lohani e0f38dad9f test hook to print test result 2021-03-21 20:12:37 +05:45
Damodar Lohani a5295a1c09 test hook to print time 2021-03-21 20:11:05 +05:45
Eldad Fux 4ba037d9d2 Merge branch 'dev' of github.com:appwrite/appwrite into feat-465-add-arm-support 2021-03-20 13:53:46 +02:00
Eldad Fux f36f9ff752 Merge branch 'dev' of github.com:appwrite/appwrite into 0.8.x 2021-03-20 13:53:22 +02:00
Eldad Fux fc83bc1276 Merge branch 'master' of github.com:appwrite/appwrite into dev 2021-03-20 13:52:52 +02:00
Eldad A. FuxandGitHub 03d1633445 Merge pull request #998 from appwrite/fix-head-requests
Fix for head requests in Utopia
2021-03-20 13:52:28 +02:00
Eldad Fux 50f97becd0 Fixed tests 2021-03-20 10:50:30 +02:00
Eldad Fux 600692bcac Fixed AV health check 2021-03-20 09:14:02 +02:00
Eldad Fux 7443bcf2d8 Disabled ClamAV from tests (for now) 2021-03-20 08:23:42 +02:00
kodumbeats b33d54ef35 Reducing sleep time 2021-03-19 11:47:06 -04:00
kodumbeats 90833683fa Update env names for consistency 2021-03-19 11:46:03 -04:00
Eldad Fux 1dfb18fc1b Upgraded ClamAV 2021-03-19 00:11:37 +02:00
Eldad Fux 11053b0b60 Added timestamp 2021-03-19 00:08:19 +02:00
kodumbeats d8990fba99 Upgrade utopia-php/abuse to version 0.4.0 2021-03-18 08:11:23 -04:00
kodumbeats 132baa3e9b Pass projectId to function as env var 2021-03-18 07:46:48 -04:00
Damodar Lohani 185970a123 fix workers for redis - user can be null 2021-03-18 17:07:12 +05:45
kodumbeatsandGitHub daeed74473 Merge branch '0.8.x' into feat-962-pass-data-to-function-execution 2021-03-18 07:14:16 -04:00
Eldad Fux 77e4eefc00 Fix for head requests 2021-03-18 00:55:36 +02:00
Eldad A. FuxandGitHub 7899211076 Merge branch '0.8.x' into feat-anon-login 2021-03-17 23:08:59 +02:00
Eldad A. FuxandGitHub ef07db1561 Merge pull request #985 from lohanidamodar/feat-deno-sdk-getting-started
feat-deno-sdk-getting-started
2021-03-17 23:01:05 +02:00
Eldad A. FuxandGitHub 38ef5ce7f4 Merge pull request #971 from appwrite/feat-functions-and-executions-events
Add events for functions and executions
2021-03-17 22:55:55 +02:00
Eldad A. FuxandGitHub 08dd968ab9 Merge branch '0.8.x' into feat-functions-and-executions-events 2021-03-17 22:55:43 +02:00
Eldad A. FuxandGitHub bade0932cb Merge pull request #976 from appwrite/feat-execution-permission
Feat execution permission
2021-03-17 22:54:46 +02:00
Eldad A. FuxandGitHub 45e09210c9 Merge pull request #986 from lohanidamodar/feat-php-sdk-getting-started
feat-php-sdk-getting-started
2021-03-17 22:50:17 +02:00
Eldad A. FuxandGitHub b82adde29e Merge pull request #987 from lohanidamodar/feat-python-sdk-getting-started
feat-python-sdk-getting-started
2021-03-17 22:49:36 +02:00
Eldad A. FuxandGitHub 49c8be099e Merge pull request #997 from appwrite/fix-var-redis-docs
Updated docs
2021-03-17 22:46:02 +02:00
Eldad Fux 886d303683 Updated docs 2021-03-17 22:43:54 +02:00
Eldad Fux eeb7247138 Merge branch 'master' of github.com:appwrite/appwrite into dev 2021-03-17 22:34:44 +02:00
Eldad A. FuxandGitHub 309729a507 Merge pull request #988 from lohanidamodar/feat-node-sdk-getting-started
feat-node-sdk-getting-started
2021-03-17 22:28:24 +02:00
Eldad Fux 4df8ba3910 Updated cachebuster 2021-03-17 16:20:07 +02:00
Damodar LohaniandGitHub 8547c4e523 fix grammar 2021-03-17 18:32:00 +05:45
Damodar LohaniandGitHub d5be4f4c88 fix grammar 2021-03-17 18:31:40 +05:45
Damodar LohaniandGitHub ff1ebd0e3a fix grammar 2021-03-17 18:30:47 +05:45
Damodar LohaniandGitHub 82e1ceb8a9 fix grammar 2021-03-17 18:29:20 +05:45
Damodar Lohani c8c4b11dad test for dart 2.12 2021-03-17 18:13:42 +05:45
Damodar Lohani a4be12a13c docker build env 2021-03-17 18:01:34 +05:45
Damodar Lohani f430854e1e dart 2.12 environment support 2021-03-17 11:04:31 +05:45
Damodar Lohani 56e2b7c18b dart 2.12 docker file 2021-03-17 11:04:24 +05:45
Damodar LohaniandGitHub b7538e0a6d text corrections 2021-03-17 10:43:47 +05:45
Damodar Lohani 06edde5caf node sdk getting started 2021-03-17 10:38:24 +05:45
Damodar LohaniandGitHub db7b7f5374 text corrections 2021-03-17 10:36:02 +05:45
Damodar LohaniandGitHub 4d9e021eb2 corrections 2021-03-17 10:35:27 +05:45
Damodar Lohani 17b0c9ec96 Python sdk getting started 2021-03-16 19:26:27 +05:45
Damodar Lohani 21da9e3d89 PHP SDK getting started 2021-03-16 19:03:08 +05:45
Damodar Lohani 655cc59376 deno getting started 2021-03-16 17:51:17 +05:45
Eldad A. FuxandGitHub 1f4ba216b2 Merge pull request #981 from lohanidamodar/feat-flutter-sdk-getting-started
Feat flutter sdk getting started
2021-03-16 13:07:51 +02:00
Damodar Lohani 57a3978d7d fix indentation and headings 2021-03-16 15:03:16 +05:45
Damodar Lohani b250364562 updates to docs 2021-03-15 16:29:13 +05:45
Damodar Lohani 95ba49c1c0 updates 2021-03-15 16:26:41 +05:45
Damodar Lohani 6b83b45424 Merge branch 'dev' into feat-flutter-sdk-getting-started 2021-03-15 16:19:54 +05:45
Eldad A. FuxandGitHub 76e54de739 Merge pull request #970 from lohanidamodar/feat-dart-sdk-getting-started
feat-dart-sdk-getting-started
2021-03-15 09:48:37 +02:00
Damodar LohaniandGitHub 14e7a63287 getting started tutorial 2021-03-15 09:08:24 +05:45
Damodar Lohani 583b9c8c5c learn more section 2021-03-14 10:14:55 +05:45
Damodar Lohani 16e446bbf5 update sdk generator version 2021-03-14 10:13:06 +05:45
Eldad Fux 0a0d46ff05 Updated test 2021-03-14 01:56:29 +02:00
Eldad Fux 024fae0d21 Changed execution default permissions 2021-03-14 01:52:05 +02:00
kodumbeats 8d3d636620 Define order to run FunctionsServerTest before Client 2021-03-13 09:06:34 -05:00
kodumbeatsandGitHub a7a9eec4f7 Merge branch 'dev' into feat-functions-and-executions-events 2021-03-12 18:06:07 -05:00
kodumbeats 04e9f4f720 Added events for functions and executions to changelog 2021-03-12 18:02:23 -05:00
kodumbeats c0b020dd07 Test for functions.delete 2021-03-12 17:58:33 -05:00
kodumbeats ac7efc8d1b Test for functions.update 2021-03-12 17:48:15 -05:00
kodumbeats 3cff27a125 Test for functions.tags.delete 2021-03-12 17:13:44 -05:00
kodumbeats 1bfc259247 Add function exectution webhook tests 2021-03-12 16:55:01 -05:00
kodumbeats 444994a98d Add function webhook tests 2021-03-12 16:23:37 -05:00
kodumbeats 52a314877c Adjust custom data input to textarea 2021-03-12 14:40:11 -05:00
kodumbeats e0cbea64ae Ensure function completes 2021-03-12 14:31:17 -05:00
kodumbeats ce7e1034af Increase sleep time 2021-03-12 14:22:50 -05:00
kodumbeats c04396b254 Pass userId to function 2021-03-12 14:01:58 -05:00
kodumbeats 731c87d740 Add functions.executions.update 2021-03-12 13:28:29 -05:00
kodumbeats 8be72d5756 Sleep and assert only one execution 2021-03-12 10:01:03 -05:00
kodumbeats 1d3dc5d240 Revert debugging changes 2021-03-12 08:49:57 -05:00
kodumbeats 7e5b2dfa81 Remove event triggers 2021-03-12 07:57:18 -05:00
kodumbeats c6fe041989 Increase container limit 2021-03-12 07:50:29 -05:00
kodumbeats 1e12c66ea3 Add debugging stuff 2021-03-12 07:44:11 -05:00
kodumbeats bbc353359c Change function order 2021-03-12 07:03:47 -05:00
kodumbeats 35bb80741f Increase sleep time so execution can complete 2021-03-12 06:22:18 -05:00
kodumbeats 622b1da457 Add debugging checks 2021-03-11 15:39:20 -05:00
kodumbeats 5a4afd1cc5 Correct sleep time 2021-03-11 13:47:44 -05:00
kodumbeats f734fc1de2 Add events for functions and executions 2021-03-11 13:25:46 -05:00
kodumbeats 59b6c6efb8 Add custom data info to changelog 2021-03-11 11:45:19 -05:00
kodumbeats 994b47edd9 Clean up tests 2021-03-11 11:42:19 -05:00
kodumbeats 4b8fc24980 Fix tests 2021-03-11 10:19:34 -05:00
kodumbeats 75668ab6da Refactor test to store functionId 2021-03-11 09:19:40 -05:00
kodumbeats 925bceec37 Set custom data as optional input param 2021-03-11 09:02:11 -05:00
kodumbeats 277ebc1151 Add data param to console SDK 2021-03-11 08:53:36 -05:00
kodumbeats 84e5577934 Adjust form metadata 2021-03-11 08:02:18 -05:00
kodumbeats a737b23fa5 Add modal for execution data 2021-03-11 07:39:06 -05:00
Damodar Lohani 98d7d13f16 remove other files 2021-03-11 14:38:44 +05:45
Damodar Lohani 6295bdba86 remove other files 2021-03-11 13:49:59 +05:45
Damodar Lohani 90fc752ffe flutter sdk learn more section 2021-03-11 10:41:16 +05:45
Damodar Lohani ce17d5d886 learn more section in Deno SDK 2021-03-11 10:39:49 +05:45
Damodar Lohani af8c52087b learn more section dart SDK 2021-03-11 10:38:40 +05:45
Damodar Lohani a70977f27f exception and small fixes 2021-03-11 10:27:07 +05:45
kodumbeats 034679930a Add client e2e test 2021-03-10 15:50:20 -05:00
kodumbeats 681ab12f76 Instantiate jwt outside conditionals 2021-03-10 15:25:54 -05:00
kodumbeats 36b8e6defb Server test assertions 2021-03-10 14:43:15 -05:00
kodumbeats 8373db80ef Comment unneeded function calls 2021-03-10 14:42:36 -05:00
kodumbeats 33fb2e3edd Test for custom data in execution 2021-03-10 13:05:43 -05:00
kodumbeats f56a63c611 Make JWT for each execution 2021-03-10 12:48:05 -05:00
kodumbeats a2bf6269bf Create script for testing execution custom data 2021-03-10 12:43:59 -05:00
kodumbeats da8984f66e Pass userId and JWT to function as env vars 2021-03-10 11:58:46 -05:00
Damodar Lohani 3f96ff85b8 deno getting started 2021-03-10 12:38:51 +05:45
Damodar Lohani 13c7ded9db Flutter getting started 2021-03-10 12:29:28 +05:45
Damodar Lohani e157ac9584 updates 2021-03-10 07:21:25 +05:45
kodumbeats 59984fa6c0 Pass custom function $data to execution 2021-03-09 14:58:03 -05:00
Damodar Lohani b087d8ffc3 dart getting started section 2021-03-08 17:04:18 +05:45
Damodar Lohani 9fdfdbdc4b getting started in the SDKs 2021-03-08 17:00:39 +05:45
Eldad Fux 538ffb0b24 Fixed type 2021-03-01 23:04:53 +02:00
Eldad Fux 7267e8eeca Deprecated deno 1.2 2021-02-28 23:45:05 +02:00
Eldad Fux c5dd0d1542 Merge branch 'dev' of github.com:appwrite/appwrite into feat-465-add-arm-support 2021-02-28 23:43:59 +02:00
Eldad Fux b621ed8c69 Updated change log 2021-02-28 23:37:10 +02:00
Eldad Fux e7466a91cc Added e2e tests 2021-02-28 23:22:03 +02:00
Eldad Fux 7f47bfc9f8 Fixed default values 2021-02-28 22:46:26 +02:00
Eldad Fux a6edf2f227 Removed space 2021-02-28 20:36:37 +02:00
Eldad Fux b09afd1921 Updated API 2021-02-28 20:36:13 +02:00
Eldad Fux 74c21ce3af Updated dependencies 2021-02-28 17:57:57 +02:00
Eldad Fux 8f9d3aaaa7 Updated UI 2021-02-28 17:01:16 +02:00
Eldad Fux 2c0942851e Updated API 2021-02-28 17:00:27 +02:00
Eldad Fux a4f285df9c Merge branch 'dev' of github.com:appwrite/appwrite into feat-auth-limits 2021-02-28 13:44:22 +02:00
Eldad Fux a3a27ced66 Updated UI 2021-02-28 13:41:18 +02:00
Eldad Fux 55891e14d7 Updated project API 2021-02-28 13:40:59 +02:00
Eldad Fux d637437988 Updated config 2021-02-28 13:40:42 +02:00
Eldad Fux 42b75f3dfd Fixed typo 2021-02-28 13:00:22 +02:00
Eldad Fux 45be379e0e Updated console SDK 2021-02-28 13:00:08 +02:00
Eldad Fux 27f0dc4c37 Updated config files 2021-02-28 12:16:27 +02:00
Eldad Fux b94803fc84 Updated invites icon 2021-02-28 12:12:26 +02:00
Eldad Fux 0e0aeba451 Updated icons 2021-02-28 10:48:48 +02:00
Torsten DittmannandGitHub 6e5ce2c646 Merge branch 'dev' into feat-anon-login 2021-02-23 23:44:59 +01:00
Torsten Dittmann e829f8f7bc add env var and console prevention 2021-02-23 23:43:05 +01:00
Eldad Fux 76cb9c14fe Fix for tests 2021-02-23 15:19:19 +02:00
Eldad Fux 3b9b751d5a Fixed count 2021-02-23 15:03:43 +02:00
Eldad Fux db898d9f9c Fixed count method 2021-02-23 14:52:14 +02:00
Eldad Fux cdf54fd19c Disable recovery when SMTP is off 2021-02-23 14:00:31 +02:00
Eldad Fux 40d7a235ea Merge branch 'dev' of github.com:appwrite/appwrite into feat-god-user 2021-02-23 13:31:00 +02:00
Eldad Fux c10500c882 Added an option for a console god user 2021-02-23 13:29:12 +02:00
Torsten Dittmann e388cb462b check duplicate collection rules 2021-02-22 13:44:47 +01:00
Torsten Dittmann 7aab693d66 remove duplicate secret prop from session collection 2021-02-22 13:03:34 +01:00
Torsten Dittmann 6dbc3966b2 adds migration and migration tests 2021-02-22 12:27:31 +01:00
Eldad A. FuxandGitHub 0237768ebf Merge branch '0.7.x' into feat-upgrade-php-version 2021-02-21 23:29:37 +02:00
Torsten Dittmann 19b85d7ae6 revert stupid change 2021-02-19 15:53:52 +01:00
Torsten Dittmann 70666ddf0a add current to sessions collection 2021-02-19 15:41:17 +01:00
Torsten Dittmann 8bc484dfca fix leftovers 2021-02-19 14:59:36 +01:00
Torsten Dittmann d4bd9c0d06 decouple user session from tokens 2021-02-19 13:12:47 +01:00
Torsten Dittmann 312ab65794 decouple oauth2 from user to tokens 2021-02-19 11:02:02 +01:00
Eldad Fux f860fe1770 Merge branch 'master' of github.com:appwrite/appwrite into feat-465-add-arm-support 2021-02-19 10:39:05 +02:00
Torsten Dittmann 2c1247d667 change sdk method name 2021-02-18 15:52:27 +01:00
Torsten Dittmann 8d3d3bca68 added anon login to changelog 2021-02-17 10:38:45 +01:00
Torsten Dittmann d1ae8aa15c adapt to review 2021-02-17 09:47:07 +01:00
Torsten Dittmann 1387fb50f1 add tests for oauth2 2021-02-16 16:51:08 +01:00
Torsten Dittmann 6a31e19d73 add test to convert to existing email 2021-02-16 16:01:15 +01:00
Torsten Dittmann b559f8068e add test to login after converting 2021-02-16 15:20:15 +01:00
Torsten Dittmann c9b46d93dc fix comment 2021-02-16 15:16:09 +01:00
Torsten Dittmann 6005551023 update tests 2021-02-16 15:14:36 +01:00
Torsten Dittmann 6c717b7a31 add tests 2021-02-16 14:49:21 +01:00
Torsten Dittmann f199e70a8f update docs 2021-02-16 14:46:44 +01:00
Torsten Dittmann 9d18916504 create new endpoint 2021-02-16 14:46:30 +01:00
Torsten Dittmann ec6e4f3a06 adapt user collection properties 2021-02-16 14:46:16 +01:00
Eldad Fux a99133d5d8 Updated Swoole version 2021-02-09 12:37:34 +02:00
Eldad Fux 45fff3e51f Fixed test for php8 2021-02-06 10:27:07 +02:00
Eldad Fux 429ac1098c Fixed JSON syntax 2021-02-06 07:35:42 +02:00
Eldad Fux c8b6a18939 Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-upgrade-php-version 2021-02-06 00:19:15 +02:00
Eldad Fux a856d618de Updated PHP version 2021-02-06 00:17:06 +02:00
Eldad A. FuxandGitHub 469fe6a9c3 Merge pull request #882 from TorstenDittmann/feat-465-add-arm-support
feat(tests): add architecture detection
2021-02-05 20:46:30 +02:00
Torsten Dittmann 277ee1b18b fix(env): remove arm support from dotnet 3.1 2021-02-05 18:32:44 +01:00
Torsten Dittmann 8d9966bbef feat(tests): add architecture detection 2021-02-05 17:45:37 +01:00
Eldad Fux dec6c4e38f Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-465-add-arm-support 2021-02-04 19:53:23 +02:00
Eldad Fux d4519cab0b Deno test for ARM 2021-02-01 00:23:34 +02:00
Eldad Fux 94a14bd8af Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-465-add-arm-support 2021-01-30 12:37:17 +02:00
Eldad Fux 70e0e5b1a3 Upgraded Swoole 2021-01-30 12:00:08 +02:00
Eldad Fux 8c7cedc240 Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-upgrade-php-version 2021-01-30 11:58:58 +02:00
Eldad Fux 8373be65d0 Fix for swoole error 2021-01-15 19:19:48 +02:00
Eldad Fux 4c1d5419f4 Updated Influx SDK 2021-01-15 11:25:04 +02:00
Eldad Fux 59f5a0eb55 Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-upgrade-php-version 2021-01-15 08:52:42 +02:00
Eldad Fux e8c1d3ae9d Updated dependencies 2021-01-15 08:08:02 +02:00
Eldad Fux bc16ec93db Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-upgrade-php-version 2021-01-15 00:26:09 +02:00
Eldad Fux f975110e07 Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-upgrade-php-version 2021-01-11 17:00:36 +02:00
Eldad Fux c4124136e7 Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-upgrade-php-version 2021-01-05 00:39:27 +02:00
Eldad Fux f3024e1873 Removed deno test 2021-01-04 10:55:25 +02:00
Eldad Fux cbb0584006 Synced with 0.7 2021-01-04 01:29:04 +02:00
Eldad Fux b4969f553c Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-upgrade-php-version 2021-01-04 01:28:46 +02:00
Eldad Fux 9bc3184ee3 Updated CI configuration 2021-01-04 00:37:52 +02:00
Eldad Fux 89ca10259d Updated ports 2 2021-01-03 23:22:41 +02:00
Eldad Fux 17e90e2b25 Updated CI 2021-01-03 21:53:46 +02:00
Eldad Fux 7e2920a5f8 Updated port types 2021-01-03 20:03:27 +02:00
Eldad Fux f87d25bd2e Updated docker images and settings 2021-01-03 19:16:44 +02:00
Eldad Fux ab825cd736 Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-465-add-arm-support 2021-01-03 07:49:30 +02:00
Eldad Fux a579c1c19f Updated request & mail catchers 2021-01-03 00:48:50 +02:00
Eldad Fux 29311cb2be Remove $collection tests, attribute has been removed 2020-12-21 09:23:43 +02:00
Eldad Fux b99bb1557f Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-upgrade-php-version 2020-12-17 10:10:27 +02:00
Eldad Fux 422252506f Added docs 2020-12-16 13:02:31 +02:00
Eldad Fux 3190b05ec7 Upgraded Swoole version 2020-12-13 09:27:08 +02:00
Eldad A. FuxandGitHub a23f38c769 Merge branch '0.7.x' into feat-upgrade-php-version 2020-12-13 01:56:32 +02:00
Eldad Fux b55bbdf79c Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-465-add-arm-support 2020-12-12 20:32:49 +02:00
Eldad Fux 02ef52c13d Official release tag! 2020-12-01 08:08:01 +02:00
Eldad Fux 4e83a988fc Fixed tests 2020-11-21 10:02:25 +02:00
Eldad Fux dda4f2935a Updated RC version 2020-11-21 08:18:39 +02:00
Eldad Fux 1a2c3c1551 Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-upgrade-php-version 2020-11-21 08:17:53 +02:00
Eldad Fux b4037b9da3 Upgraded to RC3 2020-11-07 20:10:28 +02:00
Eldad Fux c9117ba3d8 Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-upgrade-php-version 2020-11-07 20:05:55 +02:00
Eldad Fux a2d5dd190f Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-465-add-arm-support 2020-11-03 23:33:58 +02:00
Eldad Fux 0f812b1713 Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-upgrade-php-version 2020-10-31 19:23:10 +02:00
Eldad Fux c613ec0f4a Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-465-add-arm-support 2020-10-31 16:57:11 +02:00
Eldad Fux 46ae720816 Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-upgrade-php-version 2020-10-31 16:37:35 +02:00
Eldad Fux de4ea2a79a Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-upgrade-php-version 2020-10-31 16:32:54 +02:00
Eldad Fux 6cdeaac325 Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-upgrade-php-version 2020-10-31 07:44:07 +02:00
Eldad Fux 608cf36d1f Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-upgrade-php-version 2020-10-31 07:43:09 +02:00
Eldad Fux 47255f1df9 Merge branch 'feat-upgrade-php-version' of github.com:appwrite/appwrite into feat-upgrade-php-version 2020-10-29 00:34:28 +02:00
Eldad Fux eb9730b606 Removed imagemagick dev 2020-10-29 00:34:21 +02:00
Eldad A. FuxandGitHub 8d60a6a759 Merge branch '0.7.x' into feat-upgrade-php-version 2020-10-27 23:57:39 +02:00
Eldad Fux 42d9a64473 New line :) 2020-10-27 23:56:47 +02:00
Eldad Fux 2996260e41 Added missing docs 2020-10-27 21:34:27 +02:00
Eldad Fux 8bbdac232d Removed multiple docker-cli setups 2020-10-27 20:42:42 +02:00
Eldad Fux 9fe744dad2 Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-465-add-arm-support 2020-10-27 20:37:20 +02:00
Eldad Fux e8fb01604c Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-upgrade-php-version 2020-10-27 20:08:20 +02:00
Eldad Fux 146046a119 Fixed mock params 2020-10-27 17:33:13 +02:00
Eldad Fux 38e52eaf7b Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-upgrade-php-version 2020-10-27 10:48:51 +02:00
Eldad Fux 745860a68d Fixed reference 2020-10-27 09:48:39 +02:00
Eldad Fux cb82657a58 Fix for PHP8 array_push 2020-10-27 08:48:19 +02:00
Eldad Fux e5c5cb0a25 Updated PDO PHP8 signature 2020-10-27 08:34:02 +02:00
Eldad Fux be33726e76 Upgraded to php8 2020-10-27 08:20:52 +02:00
Eldad A. FuxandGitHub 5b1de0b42d Merge pull request #667 from SoftCreatR/patch-2
Update docker-compose.yml
2020-10-10 22:59:26 +03:00
Sascha GreuelandGitHub 0097e6afa6 Update docker-compose.yml 2020-10-10 20:48:33 +02:00
Sascha GreuelandGitHub ec4b060bec Update docker-compose.yml 2020-10-10 20:27:31 +02:00
Eldad Fux 92a89b0b11 Test Influxdb non-alpine 2020-10-08 16:08:43 +03:00
Eldad Fux ba83d7ca87 Merge branch '0.7.x' of github.com:appwrite/appwrite into feat-465-add-arm-support 2020-10-08 15:38:49 +03:00
Eldad Fux 7ff6ad69bd Updated ClamAV version 2020-10-08 15:36:47 +03:00
Eldad Fux 7a85b1da76 Updated Docker service setup 2020-09-27 10:46:28 +03:00
Eldad Fux 62d0129f80 Added new CPU arch settings to Travis CI 2020-09-27 10:32:16 +03:00
1292 changed files with 32511 additions and 12273 deletions
+6 -2
View File
@@ -1,5 +1,9 @@
_APP_ENV=production
_APP_ENV=development
_APP_LOCALE=en
_APP_CONSOLE_WHITELIST_ROOT=disabled
_APP_CONSOLE_WHITELIST_EMAILS=
_APP_CONSOLE_WHITELIST_IPS=
_APP_SYSTEM_EMAIL_NAME=Appwrite
_APP_SYSTEM_EMAIL_ADDRESS=team@appwrite.io
_APP_SYSTEM_SECURITY_EMAIL_ADDRESS=security@appwrite.io
@@ -16,7 +20,7 @@ _APP_DB_PORT=3306
_APP_DB_SCHEMA=appwrite
_APP_DB_USER=user
_APP_DB_PASS=password
_APP_STORAGE_ANTIVIRUS=enabled
_APP_STORAGE_ANTIVIRUS=disabled
_APP_STORAGE_ANTIVIRUS_HOST=clamav
_APP_STORAGE_ANTIVIRUS_PORT=3310
_APP_INFLUXDB_HOST=influxdb
@@ -24,7 +28,7 @@ _APP_INFLUXDB_PORT=8086
_APP_STATSD_HOST=telegraf
_APP_STATSD_PORT=8125
_APP_SMTP_HOST=maildev
_APP_SMTP_PORT=25
_APP_SMTP_PORT=1025
_APP_SMTP_SECURE=
_APP_SMTP_USERNAME=
_APP_SMTP_PASSWORD=
+4 -3
View File
@@ -2,6 +2,7 @@ dist: xenial
arch:
- amd64
- arm64
os: linux
@@ -10,9 +11,6 @@ language: shell
notifications:
email:
- team@appwrite.io
services:
- docker
before_install:
- curl -fsSL https://get.docker.com | sh
@@ -27,6 +25,9 @@ before_install:
- docker --version
- docker buildx create --use
- chmod -R u+x ./.travis-ci
- export COMPOSE_INTERACTIVE_NO_CLI=1
# Only pass a single runtime for CI stability
- echo "_APP_FUNCTIONS_RUNTIMES=php-8.0" >> .env
install:
- docker-compose up -d
+91 -2
View File
@@ -1,6 +1,94 @@
# Version 0.8.0 (Not Released Yet)
# NOT PUBLISHED YET
- Anonymous login
## Features
- 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
## Bugs
- Fixed bug 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)
# Version 0.8.0
## Features
- Refactoring SSL generation to work on every request so no domain environment variable is required for SSL generation (#1133)
- Added Anonymous Login ([RFC-010](https://github.com/appwrite/rfc/blob/main/010-anonymous-login.md), #914)
- Added events for functions and executions (#971)
- Added JWT support (#784)
- Added ARM support (#726)
- New awesome image preview features, supports borderRadius, borderColor, borderWidth
- Split token & session models to become 2 different internal entities (#922)
- Added Dart 2.12 as a new Cloud Functions runtime (#989)
- Added option to disable email/password (#947)
- Added option to disable anonymous login (need to merge and apply changed) (#947)
- Added option to disable JWT auth (#947)
- Added option to disable team invites (#947)
- Option to limit number of users (good for app launches + root account PR) (#947)
- Added 2 new endpoints to the projects API to allow new settings
- Enabled 501 errors (Not Implemented) from the error handler
- Added Python 3.9 as a new Cloud Functions runtime (#1044)
- Added Deno 1.8 as a new Cloud Functions runtime (#989)
- Upgraded to PHP 8.0 (#713)
- ClamAV is now disabled by default to allow lower min requirements for Appwrite (#1064)
- Added a new env var named `_APP_LOCALE` that allow to change the default `en` locale value (#1056)
- Updated all the console bottom control to be consistent. Dropped the `+` icon (#1062)
- Added Response Models for Documents and Preferences (#1075, #1102)
- Added new endpoint to update team membership roles (#1142)
- Removed DB connection from webhooks worker for improved performance (#1150)
## Bugs
- Fixed default value for HTTPS force option
- Fixed form array casting in dashboard (#1070)
- Fixed collection document rule form in dashboard (#1069)
- Bugs in the Teams API:
- Fixed incorrect audit worker event names (#1143)
- Increased limit of memberships fetched in `createTeamMembership` to 2000 (#1143)
- Fixed exception thrown when SSL certificate is already stored in the database (#1151)
## Breaking Changes (Read before upgrading!)
- Rename `deleteuser` to `delete` on Users Api (#1089)
- Environment variable `_APP_FUNCTIONS_ENVS` renamed to `_APP_FUNCTIONS_RUNTIMES` (#1101)
- Only logged in users can execute functions (for guests, use anonymous login) (#976)
- Only the user who has triggered the execution get access to the relevant execution logs (#1045)
- Function execution environment variable `APPWRITE_FUNCTION_EVENT_PAYLOAD` renamed to `APPWRITE_FUNCTION_EVENT_DATA` (#1045)
- Function execution environment variable `APPWRITE_FUNCTION_ENV_NAME` renamed to `APPWRITE_FUNCTION_RUNTIME_NAME` (#1101)
- Function execution environment variable `APPWRITE_FUNCTION_ENV_VERSION` renamed to `APPWRITE_FUNCTION_RUNTIME_VERSION` (#1101)
- Introduces rate limits for:
- Team invite (10 requests in every 60 minutes per IP address) (#1088)
- Rename param `inviteId` to the more accurate `membershipId` in the Teams API (#1129)
# Version 0.7.2
## Features
- When creating new resources from the client API, the current user gets both read & write permissions by default. (#1007)
- Added timestamp to errors logs on the HTTP API container (#1002)
- Added verbose tests output on the terminal and CI (#1006)
## Upgrades
- Upgraded utopia-php/abuse to version 0.4.0
- Upgraded utopia-php/analytics to version 0.2.0
## Bugs
- Fixed certificates worker error on successful operations (#1010)
- Fixed head requests not responding (#998)
- Fixed bug when using auth credential for the Redis container (#993)
- Fixed server warning logs on 3** redirect endpoints (#1013)
# Version 0.7.1
@@ -11,6 +99,7 @@
- Force adding a security email on setup
- SMTP is now disabled by default, no dummy SMTP is included in setup
- Added a new endpoint that returns the server and SDKs latest versions numbers #941
- Custom data strings, userId, and JWT available for cloud functions #967
## Upgrades
+4 -7
View File
@@ -92,7 +92,7 @@ After finishing the installation process, you can start writing and editing code
#### Advanced Topics
We love to create issues that are good for begginers and label them as `good for begginers` or `hacktoberfest`, but some more advanced topics might require extra knowledge. Below is a list of links you can use to learn more about some of the more advance topics that will help you master the Appwrite codebase.
We love to create issues that are good for beginners and label them as `good first issue` or `hacktoberfest`, but some more advanced topics might require extra knowledge. Below is a list of links you can use to learn more about some of the more advance topics that will help you master the Appwrite codebase.
##### Tools and Libs
- [Docker](https://www.docker.com/get-started)
@@ -278,13 +278,9 @@ Before running the command, make sure you have proper write permissions to the A
```bash
docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x -t appwrite/appwrite:dev --push .
```
**Build Functions Envs**
**Build Functions Runtimes**
Build envs for all supported cloud functions (multicore builds)
```bash
bash ./docker/environments/build.sh
```
The Runtimes for all supported cloud functions (multicore builds) can be found at the [appwrite/php-runtimes](https://github.com/appwrite/php-runtimes) repository.
## Tests
@@ -365,6 +361,7 @@ From time to time, our team will add tutorials that will help contributors find
* [Adding Support for a New OAuth2 Provider](./docs/tutorials/add-oauth2-provider.md)
* [Appwrite Environment Variables](./docs/tutorials/environment-variables.md)
* [Running in Production](./docs/tutorials/running-in-production.md)
* [Adding Storage Adapter](./docs/tutorials/add-storage-adapter.md)
## Other Ways to Help
+48 -21
View File
@@ -12,12 +12,13 @@ RUN composer update --ignore-platform-reqs --optimize-autoloader \
--no-plugins --no-scripts --prefer-dist \
`if [ "$TESTING" != "true" ]; then echo "--no-dev"; fi`
FROM php:7.4-cli-alpine as step1
FROM php:8.0-cli-alpine as step1
ENV PHP_REDIS_VERSION=5.3.3 \
PHP_SWOOLE_VERSION=v4.5.8 \
PHP_MAXMINDDB_VERSION=v1.10.0 \
PHP_XDEBUG_VERSION=sdebug_2_9-beta
ENV PHP_REDIS_VERSION=5.3.4 \
PHP_SWOOLE_VERSION=v4.6.6 \
PHP_IMAGICK_VERSION=master \
PHP_YAML_VERSION=2.2.1 \
PHP_MAXMINDDB_VERSION=v1.10.1
RUN \
apk add --no-cache --virtual .deps \
@@ -29,38 +30,52 @@ RUN \
git \
zlib-dev \
brotli-dev \
yaml-dev \
imagemagick \
imagemagick-dev \
libmaxminddb-dev
RUN docker-php-ext-install sockets
RUN \
# Redis Extension
git clone https://github.com/phpredis/phpredis.git && \
git clone --depth 1 --branch $PHP_REDIS_VERSION https://github.com/phpredis/phpredis.git && \
cd phpredis && \
git checkout $PHP_REDIS_VERSION && \
phpize && \
./configure && \
make && make install && \
cd .. && \
## Swoole Extension
git clone https://github.com/swoole/swoole-src.git && \
git clone --depth 1 --branch $PHP_SWOOLE_VERSION https://github.com/swoole/swoole-src.git && \
cd swoole-src && \
git checkout $PHP_SWOOLE_VERSION && \
phpize && \
./configure --enable-sockets --enable-http2 && \
./configure --enable-http2 && \
make && make install && \
cd .. && \
## Imagick Extension
git clone --depth 1 --branch $PHP_IMAGICK_VERSION https://github.com/Imagick/imagick && \
cd imagick && \
phpize && \
./configure && \
make && make install && \
cd .. && \
## YAML Extension
git clone --depth 1 --branch $PHP_YAML_VERSION https://github.com/php/pecl-file_formats-yaml && \
cd pecl-file_formats-yaml && \
phpize && \
./configure && \
make && make install && \
cd .. && \
## Maxminddb extension
git clone https://github.com/maxmind/MaxMind-DB-Reader-php.git && \
git clone --depth 1 --branch $PHP_MAXMINDDB_VERSION https://github.com/maxmind/MaxMind-DB-Reader-php.git && \
cd MaxMind-DB-Reader-php && \
git checkout $PHP_MAXMINDDB_VERSION && \
cd ext && \
phpize && \
./configure && \
make && make install && \
cd ../..
FROM php:7.4-cli-alpine as final
FROM php:8.0-cli-alpine as final
LABEL maintainer="team@appwrite.io"
@@ -68,10 +83,18 @@ ARG VERSION=dev
ENV _APP_SERVER=swoole \
_APP_ENV=production \
_APP_LOCALE=en \
_APP_DOMAIN=localhost \
_APP_DOMAIN_TARGET=localhost \
_APP_HOME=https://appwrite.io \
_APP_EDITION=community \
_APP_CONSOLE_WHITELIST_ROOT=enabled \
_APP_CONSOLE_WHITELIST_EMAILS= \
_APP_CONSOLE_WHITELIST_IPS= \
_APP_SYSTEM_EMAIL_NAME= \
_APP_SYSTEM_EMAIL_ADDRESS= \
_APP_SYSTEM_RESPONSE_FORMAT= \
_APP_SYSTEM_SECURITY_EMAIL_ADDRESS= \
_APP_OPTIONS_ABUSE=enabled \
_APP_OPTIONS_FORCE_HTTPS=disabled \
_APP_OPENSSL_KEY_V1=your-secret-key \
@@ -123,16 +146,14 @@ RUN \
curl-dev \
&& apk add --no-cache \
libstdc++ \
certbot \
brotli-dev \
yaml-dev \
imagemagick \
imagemagick-dev \
libmaxminddb-dev \
certbot \
docker-cli \
docker-compose \
libmaxminddb \
libmaxminddb-dev \
&& pecl install imagick yaml \
&& docker-php-ext-enable imagick yaml \
&& docker-php-ext-install sockets opcache pdo_mysql \
&& apk del .deps \
&& rm -rf /var/cache/apk/*
@@ -140,9 +161,11 @@ RUN \
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-20190902/swoole.so /usr/local/lib/php/extensions/no-debug-non-zts-20190902/
COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20190902/redis.so /usr/local/lib/php/extensions/no-debug-non-zts-20190902/
COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20190902/maxminddb.so /usr/local/lib/php/extensions/no-debug-non-zts-20190902/
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/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/
COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/maxminddb.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
# Add Source Code
COPY ./app /usr/src/code/app
@@ -190,11 +213,15 @@ RUN mkdir -p /etc/letsencrypt/live/ && chmod -Rf 755 /etc/letsencrypt/live/
# Enable Extensions
RUN echo extension=swoole.so >> /usr/local/etc/php/conf.d/swoole.ini
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 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
RUN echo "opcache.jit_buffer_size=100M" >> /usr/local/etc/php/conf.d/appwrite.ini
RUN echo "opcache.jit=1235" >> /usr/local/etc/php/conf.d/appwrite.ini
EXPOSE 80
+9 -7
View File
@@ -1,3 +1,4 @@
<br />
<p align="center">
<a href="https://appwrite.io" target="_blank"><img width="260" height="39" src="https://appwrite.io/images/github-logo.png" alt="Appwrite Logo"></a>
<br />
@@ -14,9 +15,11 @@
[![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 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.
Using Appwrite, you can easily integrate your app with user authentication & multiple sign-in methods, a database for storing and querying users and team data, storage and file management, image manipulation, schedule CRON tasks, and [more services](https://appwrite.io/docs).
Using Appwrite, you can easily integrate your app with user authentication & multiple sign-in methods, a database for storing and querying users and team data, storage and file management, image manipulation, Cloud Functions, and [more services](https://appwrite.io/docs).
![Appwrite](public/images/github.png)
@@ -53,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.7.1
appwrite/appwrite:0.8.0
```
### Windows
@@ -65,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.7.1
appwrite/appwrite:0.8.0
```
#### PowerShell
@@ -75,13 +78,13 @@ 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.7.1
appwrite/appwrite:0.8.0
```
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.
For advanced production and custom installation, check out our Docker [environment variables](docs/tutorials/environment-variables.md) docs. You can also use our public [docker-compose.yml](https://appwrite.io/docker-compose.yml) file to manually set up an environment.
For advanced production and custom installation, check out our Docker [environment variables](https://appwrite.io/docs/environment-variables) docs. You can also use our public [docker-compose.yml](https://gist.github.com/eldadfux/977869ff6bdd7312adfd4e629ee15cc5#file-docker-compose-yml) file to manually set up an environment.
### Upgrade from an Older Version
@@ -122,12 +125,11 @@ Below is a list of currently supported platforms and languages. If you wish to h
#### 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; [.NET](https://github.com/appwrite/sdk-for-dotnet) - **Experimental** (Maintained by the Appwrite Team)
* ✅ &nbsp; [Dart](https://github.com/appwrite/sdk-for-dart) **Experimental** (Maintained by the Appwrite Team)
* ✅ &nbsp; [Go](https://github.com/appwrite/sdk-for-go) **Work in progress** (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)!
+42
View File
@@ -0,0 +1,42 @@
<?php
// Auth methods
return [
'email-password' => [
'name' => 'Email/Password',
'key' => 'usersAuthEmailPassword',
'icon' => '/images/users/email.png',
'docs' => 'https://appwrite.io/docs/client/account?sdk=web#accountCreateSession',
'enabled' => true,
],
'anonymous' => [
'name' => 'Anonymous',
'key' => 'usersAuthAnonymous',
'icon' => '/images/users/anonymous.png',
'docs' => 'https://appwrite.io/docs/client/account?sdk=web#accountCreateAnonymousSession',
'enabled' => true,
],
'invites' => [
'name' => 'Invites',
'key' => 'usersAuthInvites',
'icon' => '/images/users/invites.png',
'docs' => 'https://appwrite.io/docs/client/teams?sdk=web#teamsCreateMembership',
'enabled' => true,
],
'jwt' => [
'name' => 'JWT',
'key' => 'usersAuthJWT',
'icon' => '/images/users/jwt.png',
'docs' => 'https://appwrite.io/docs/client/account?sdk=web#accountCreateJWT',
'enabled' => true,
],
'phone' => [
'name' => 'Phone',
'key' => 'usersAuthPhone',
'icon' => '/images/users/phone.png',
'docs' => 'https://appwrite.io/docs/client/account?sdk=web#accountCreatePhoneSession',
'docs' => '',
'enabled' => false,
],
];
Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 19 KiB

+136 -27
View File
@@ -5,6 +5,7 @@ use Utopia\Config\Config;
use Appwrite\Database\Database;
$providers = Config::getParam('providers', []);
$auth = Config::getParam('auth', []);
$collections = [
'console' => [
@@ -45,7 +46,7 @@ $collections = [
'legalTaxId' => '',
'authWhitelistEmails' => (!empty(App::getEnv('_APP_CONSOLE_WHITELIST_EMAILS', null))) ? \explode(',', App::getEnv('_APP_CONSOLE_WHITELIST_EMAILS', null)) : [],
'authWhitelistIPs' => (!empty(App::getEnv('_APP_CONSOLE_WHITELIST_IPS', null))) ? \explode(',', App::getEnv('_APP_CONSOLE_WHITELIST_IPS', null)) : [],
'authWhitelistDomains' => (!empty(App::getEnv('_APP_CONSOLE_WHITELIST_DOMAINS', null))) ? \explode(',', App::getEnv('_APP_CONSOLE_WHITELIST_DOMAINS', null)) : [],
'usersAuthLimit' => (App::getEnv('_APP_CONSOLE_WHITELIST_ROOT', 'enabled') === 'enabled') ? 1 : 0, // limit signup to 1 user
],
Database::SYSTEM_COLLECTION_COLLECTIONS => [
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
@@ -204,7 +205,7 @@ $collections = [
'key' => 'email',
'type' => Database::SYSTEM_VAR_TYPE_EMAIL,
'default' => '',
'required' => true,
'required' => false,
'array' => false,
],
[
@@ -222,7 +223,7 @@ $collections = [
'key' => 'password',
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
'default' => '',
'required' => true,
'required' => false,
'array' => false,
],
[
@@ -271,6 +272,16 @@ $collections = [
'required' => true,
'array' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Sessions',
'key' => 'sessions',
'type' => Database::SYSTEM_VAR_TYPE_DOCUMENT,
'default' => [],
'required' => false,
'array' => true,
'list' => [Database::SYSTEM_COLLECTION_SESSIONS],
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Tokens',
@@ -293,11 +304,11 @@ $collections = [
],
],
],
Database::SYSTEM_COLLECTION_TOKENS => [
Database::SYSTEM_COLLECTION_SESSIONS => [
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
'$id' => Database::SYSTEM_COLLECTION_TOKENS,
'$id' => Database::SYSTEM_COLLECTION_SESSIONS,
'$permissions' => ['read' => ['*']],
'name' => 'Token',
'name' => 'Session',
'structure' => true,
'rules' => [
[
@@ -306,16 +317,34 @@ $collections = [
'key' => 'userId',
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
'default' => null,
'required' => true,
'array' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Provider',
'key' => 'provider',
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
'default' => '',
'required' => true,
'array' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Provider User Identifier',
'key' => 'providerUid',
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
'default' => '',
'required' => false,
'array' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Type',
'key' => 'type',
'type' => Database::SYSTEM_VAR_TYPE_NUMERIC,
'default' => null,
'required' => true,
'label' => 'Provider Token',
'key' => 'providerToken',
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
'default' => '',
'required' => false,
'array' => false,
],
[
@@ -473,6 +502,69 @@ $collections = [
],
],
],
Database::SYSTEM_COLLECTION_TOKENS => [
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
'$id' => Database::SYSTEM_COLLECTION_TOKENS,
'$permissions' => ['read' => ['*']],
'name' => 'Token',
'structure' => true,
'rules' => [
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'User ID',
'key' => 'userId',
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
'default' => null,
'required' => false,
'array' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Type',
'key' => 'type',
'type' => Database::SYSTEM_VAR_TYPE_NUMERIC,
'default' => null,
'required' => true,
'array' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Secret',
'key' => 'secret',
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
'default' => '',
'required' => true,
'array' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Expire',
'key' => 'expire',
'type' => Database::SYSTEM_VAR_TYPE_NUMERIC,
'default' => 0,
'required' => true,
'array' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'User Agent',
'key' => 'userAgent',
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
'default' => '',
'required' => true,
'array' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'IP',
'key' => 'ip',
'type' => Database::SYSTEM_VAR_TYPE_IP,
'default' => '',
'required' => true,
'array' => false,
],
],
],
Database::SYSTEM_COLLECTION_MEMBERSHIPS => [
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
'$id' => Database::SYSTEM_COLLECTION_MEMBERSHIPS,
@@ -679,6 +771,14 @@ $collections = [
'default' => '',
'required' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Max users allowed',
'key' => 'usersAuthLimit',
'type' => Database::SYSTEM_VAR_TYPE_NUMERIC,
'default' => 0,
'required' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Webhooks',
@@ -1172,6 +1272,24 @@ $collections = [
'required' => false,
'array' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Updated Date',
'key' => 'updated',
'type' => Database::SYSTEM_VAR_TYPE_NUMERIC,
'default' => 0,
'required' => false,
'array' => false,
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Certificate ID',
'key' => 'certificateId',
'type' => Database::SYSTEM_VAR_TYPE_KEY,
'default' => '',
'required' => false,
'array' => false,
],
],
],
Database::SYSTEM_COLLECTION_FILES => [
@@ -1617,25 +1735,16 @@ foreach ($providers as $index => $provider) {
'array' => false,
'filter' => ['encrypt'],
];
}
$collections[Database::SYSTEM_COLLECTION_USERS]['rules'][] = [
foreach ($auth as $index => $method) {
$collections[Database::SYSTEM_COLLECTION_PROJECTS]['rules'][] = [
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'OAuth2 '.\ucfirst($index).' ID',
'key' => 'oauth2'.\ucfirst($index),
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
'default' => '',
'label' => $method['name'] || '',
'key' => $method['key'] || '',
'type' => Database::SYSTEM_VAR_TYPE_BOOLEAN,
'default' => true,
'required' => false,
'array' => false,
];
$collections[Database::SYSTEM_COLLECTION_USERS]['rules'][] = [
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'OAuth2 '.\ucfirst($index).' Access Token',
'key' => 'oauth2'.\ucfirst($index).'AccessToken',
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
'default' => '',
'required' => false,
'array' => false,
];
}
-138
View File
@@ -1,138 +0,0 @@
<?php
use Utopia\App;
use Utopia\System\System;
/**
* List of Appwrite Cloud Functions supported environments
*/
$environments = [
'node-14.5' => [
'name' => 'Node.js',
'version' => '14.5',
'base' => 'node:14.5-alpine',
'image' => 'appwrite/env-node-14.5:1.0.0',
'build' => '/usr/src/code/docker/environments/node-14.5',
'logo' => 'node.png',
'supports' => [System::X86, System::PPC, System::ARM],
],
'node-15.5' => [
'name' => 'Node.js',
'version' => '15.5',
'base' => 'node:15.5-alpine',
'image' => 'appwrite/env-node-15.5:1.0.0',
'build' => '/usr/src/code/docker/environments/node-15.5',
'logo' => 'node.png',
'supports' => [System::X86, System::PPC, System::ARM],
],
'php-7.4' => [
'name' => 'PHP',
'version' => '7.4',
'base' => 'php:7.4-cli-alpine',
'image' => 'appwrite/env-php-7.4:1.0.0',
'build' => '/usr/src/code/docker/environments/php-7.4',
'logo' => 'php.png',
'supports' => [System::X86, System::PPC, System::ARM],
],
'php-8.0' => [
'name' => 'PHP',
'version' => '8.0',
'base' => 'php:8.0-cli-alpine',
'image' => 'appwrite/env-php-8.0:1.0.0',
'build' => '/usr/src/code/docker/environments/php-8.0',
'logo' => 'php.png',
'supports' => [System::X86, System::PPC, System::ARM],
],
'ruby-2.7' => [
'name' => 'Ruby',
'version' => '2.7',
'base' => 'ruby:2.7-alpine',
'image' => 'appwrite/env-ruby-2.7:1.0.2',
'build' => '/usr/src/code/docker/environments/ruby-2.7',
'logo' => 'ruby.png',
'supports' => [System::X86, System::PPC, System::ARM],
],
'ruby-3.0' => [
'name' => 'Ruby',
'version' => '3.0',
'base' => 'ruby:3.0-alpine',
'image' => 'appwrite/env-ruby-3.0:1.0.0',
'build' => '/usr/src/code/docker/environments/ruby-3.0',
'logo' => 'ruby.png',
'supports' => [System::X86, System::PPC, System::ARM],
],
'python-3.8' => [
'name' => 'Python',
'version' => '3.8',
'base' => 'python:3.8-alpine',
'image' => 'appwrite/env-python-3.8:1.0.0',
'build' => '/usr/src/code/docker/environments/python-3.8',
'logo' => 'python.png',
'supports' => [System::X86, System::PPC, System::ARM],
],
'deno-1.2' => [
'name' => 'Deno',
'version' => '1.2',
'base' => 'hayd/deno:alpine-1.2.0',
'image' => 'appwrite/env-deno-1.2:1.0.0',
'build' => '/usr/src/code/docker/environments/deno-1.2',
'logo' => 'deno.png',
'supports' => [System::X86, System::PPC, System::ARM],
],
'deno-1.5' => [
'name' => 'Deno',
'version' => '1.5',
'base' => 'hayd/deno:alpine-1.5.0',
'image' => 'appwrite/env-deno-1.5:1.0.0',
'build' => '/usr/src/code/docker/environments/deno-1.5',
'logo' => 'deno.png',
'supports' => [System::X86, System::PPC, System::ARM],
],
'deno-1.6' => [
'name' => 'Deno',
'version' => '1.6',
'base' => 'hayd/deno:alpine-1.6.0',
'image' => 'appwrite/env-deno-1.6:1.0.0',
'build' => '/usr/src/code/docker/environments/deno-1.6',
'logo' => 'deno.png',
'supports' => [System::X86, System::PPC, System::ARM],
],
'dart-2.10' => [
'name' => 'Dart',
'version' => '2.10',
'base' => 'google/dart:2.10',
'image' => 'appwrite/env-dart-2.10:1.0.0',
'build' => '/usr/src/code/docker/environments/dart-2.10',
'logo' => 'dart.png',
'supports' => [System::X86],
],
'dotnet-3.1' => [
'name' => '.NET',
'version' => '3.1',
'base' => 'mcr.microsoft.com/dotnet/runtime:3.1-alpine',
'image' => 'appwrite/env-dotnet-3.1:1.0.0',
'build' => '/usr/src/code/docker/environments/dotnet-3.1',
'logo' => 'dotnet.png',
'supports' => [System::X86, System::ARM],
],
'dotnet-5.0' => [
'name' => '.NET',
'version' => '5.0',
'base' => 'mcr.microsoft.com/dotnet/runtime:5.0-alpine',
'image' => 'appwrite/env-dotnet-5.0:1.0.0',
'build' => '/usr/src/code/docker/environments/dotnet-5.0',
'logo' => 'dotnet.png',
'supports' => [System::X86, System::ARM],
],
];
$allowList = empty(App::getEnv('_APP_FUNCTIONS_ENVS', null)) ? false : \explode(',', App::getEnv('_APP_FUNCTIONS_ENVS', null));
$environments = array_filter($environments, function ($environment, $key) use ($allowList) {
$isAllowed = $allowList && in_array($key, $allowList);
$isSupported = in_array(System::getArchEnum(), $environment["supports"]);
return $allowList ? ($isAllowed && $isSupported) : $isSupported;
}, ARRAY_FILTER_USE_BOTH);
return $environments;
+49 -4
View File
@@ -84,19 +84,59 @@ return [
],
'database.documents.create' => [
'description' => 'This event triggers when a database document is created.',
'model' => Response::MODEL_ANY,
'model' => Response::MODEL_DOCUMENT,
'note' => '',
],
'database.documents.update' => [
'description' => 'This event triggers when a database document is updated.',
'model' => Response::MODEL_ANY,
'model' => Response::MODEL_DOCUMENT,
'note' => '',
],
'database.documents.delete' => [
'description' => 'This event triggers when a database document is deleted.',
'model' => Response::MODEL_ANY,
'model' => Response::MODEL_DOCUMENT,
'note' => '',
],
'functions.create' => [
'description' => 'This event triggers when a function is created.',
'model' => Response::MODEL_FUNCTION,
'note' => 'version >= 0.7',
],
'functions.update' => [
'description' => 'This event triggers when a function is updated.',
'model' => Response::MODEL_FUNCTION,
'note' => 'version >= 0.7',
],
'functions.delete' => [
'description' => 'This event triggers when a function is deleted.',
'model' => Response::MODEL_ANY,
'note' => 'version >= 0.7',
],
'functions.tags.create' => [
'description' => 'This event triggers when a function tag is created.',
'model' => Response::MODEL_TAG,
'note' => 'version >= 0.7',
],
'functions.tags.update' => [
'description' => 'This event triggers when a function tag is updated.',
'model' => Response::MODEL_FUNCTION,
'note' => 'version >= 0.7',
],
'functions.tags.delete' => [
'description' => 'This event triggers when a function tag is deleted.',
'model' => Response::MODEL_ANY,
'note' => 'version >= 0.7',
],
'functions.executions.create' => [
'description' => 'This event triggers when a function execution is created.',
'model' => Response::MODEL_EXECUTION,
'note' => 'version >= 0.7',
],
'functions.executions.update' => [
'description' => 'This event triggers when a function execution is updated.',
'model' => Response::MODEL_EXECUTION,
'note' => 'version >= 0.7',
],
'storage.files.create' => [
'description' => 'This event triggers when a storage file is created.',
'model' => Response::MODEL_FILE,
@@ -157,6 +197,11 @@ return [
'model' => Response::MODEL_MEMBERSHIP,
'note' => 'version >= 0.7',
],
'teams.memberships.update' => [
'description' => 'This event triggers when a team membership is updated.',
'model' => Response::MODEL_MEMBERSHIP,
'note' => 'version >= 0.8',
],
'teams.memberships.update.status' => [
'description' => 'This event triggers when a team memberships status is updated.',
'model' => Response::MODEL_MEMBERSHIP,
@@ -167,4 +212,4 @@ return [
'model' => Response::MODEL_MEMBERSHIP,
'note' => 'version >= 0.7',
],
];
];
+41 -11
View File
@@ -15,7 +15,7 @@ return [
[
'key' => 'web',
'name' => 'Web',
'version' => '2.0.0',
'version' => '3.0.4',
'url' => 'https://github.com/appwrite/sdk-for-web',
'package' => 'https://www.npmjs.com/package/appwrite',
'enabled' => true,
@@ -28,11 +28,41 @@ return [
'gitUrl' => 'git@github.com:appwrite/sdk-for-web.git',
'gitRepoName' => 'sdk-for-web',
'gitUserName' => 'appwrite',
'demos' => [
[
'icon' => 'react.svg',
'name' => 'Todo App with React JS',
'description' => 'A simple Todo app that uses both the Appwrite account and database APIs.',
'source' => 'https://github.com/appwrite/todo-with-react',
'url' => 'https://appwrite-todo-with-react.vercel.app/',
],
[
'icon' => 'vue.svg',
'name' => 'Todo App with Vue JS',
'description' => 'A simple Todo app that uses both the Appwrite account and database APIs.',
'source' => 'https://github.com/appwrite/todo-with-vue',
'url' => 'https://appwrite-todo-with-vue.vercel.app/',
],
[
'icon' => 'angular.svg',
'name' => 'Todo App with Angular.js',
'description' => 'A simple Todo app that uses both the Appwrite account and database APIs.',
'source' => 'https://github.com/appwrite/todo-with-angular',
'url' => 'https://appwrite-todo-with-angular.vercel.app/',
],
[
'icon' => 'svelte.svg',
'name' => 'Todo App with Svelte',
'description' => 'A simple Todo app that uses both the Appwrite account and database APIs.',
'source' => 'https://github.com/appwrite/todo-with-svelte',
'url' => 'https://appwrite-todo-with-svelte.vercel.app/',
],
]
],
[
'key' => 'flutter',
'name' => 'Flutter',
'version' => '0.4.0-dev.3',
'version' => '0.6.2',
'url' => 'https://github.com/appwrite/sdk-for-flutter',
'package' => 'https://pub.dev/packages/appwrite',
'enabled' => true,
@@ -121,7 +151,7 @@ return [
[
'key' => 'web',
'name' => 'Console',
'version' => '1.0.0',
'version' => '2.0.0',
'url' => 'https://github.com/appwrite/sdk-for-console',
'package' => '',
'enabled' => true,
@@ -148,7 +178,7 @@ return [
[
'key' => 'nodejs',
'name' => 'Node.js',
'version' => '2.0.0',
'version' => '2.2.2',
'url' => 'https://github.com/appwrite/sdk-for-node',
'package' => 'https://www.npmjs.com/package/node-appwrite',
'enabled' => true,
@@ -165,7 +195,7 @@ return [
[
'key' => 'deno',
'name' => 'Deno',
'version' => '0.1.1',
'version' => '0.2.1',
'url' => 'https://github.com/appwrite/sdk-for-deno',
'package' => 'https://deno.land/x/appwrite',
'enabled' => true,
@@ -182,7 +212,7 @@ return [
[
'key' => 'php',
'name' => 'PHP',
'version' => '2.0.0',
'version' => '2.1.1',
'url' => 'https://github.com/appwrite/sdk-for-php',
'package' => 'https://packagist.org/packages/appwrite/appwrite',
'enabled' => true,
@@ -199,7 +229,7 @@ return [
[
'key' => 'python',
'name' => 'Python',
'version' => '0.1.1',
'version' => '0.2.1',
'url' => 'https://github.com/appwrite/sdk-for-python',
'package' => 'https://pypi.org/project/appwrite/',
'enabled' => true,
@@ -216,7 +246,7 @@ return [
[
'key' => 'ruby',
'name' => 'Ruby',
'version' => '2.0.2',
'version' => '2.1.1',
'url' => 'https://github.com/appwrite/sdk-for-ruby',
'package' => 'https://rubygems.org/gems/appwrite',
'enabled' => true,
@@ -267,7 +297,7 @@ return [
[
'key' => 'dotnet',
'name' => '.NET',
'version' => '0.1.0',
'version' => '0.3.0',
'url' => 'https://github.com/appwrite/sdk-for-dotnet',
'package' => 'https://www.nuget.org/packages/Appwrite',
'enabled' => true,
@@ -284,7 +314,7 @@ return [
[
'key' => 'dart',
'name' => 'Dart',
'version' => '0.4.0',
'version' => '0.6.1',
'url' => 'https://github.com/appwrite/sdk-for-dart',
'package' => 'https://pub.dev/packages/dart_appwrite',
'enabled' => true,
@@ -301,7 +331,7 @@ return [
[
'key' => 'cli',
'name' => 'Command Line',
'version' => '0.6.0',
'version' => '0.10.1',
'url' => 'https://github.com/appwrite/sdk-for-cli',
'package' => 'https://github.com/appwrite/sdk-for-cli',
'enabled' => true,
+28 -2
View File
@@ -6,6 +6,7 @@ return [ // Ordered by ABC.
'developers' => 'https://developer.amazon.com/apps-and-games/services-and-apis',
'icon' => 'icon-amazon',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false,
@@ -15,6 +16,7 @@ return [ // Ordered by ABC.
'developers' => 'https://developer.apple.com/',
'icon' => 'icon-apple',
'enabled' => true,
'sandbox' => false,
'form' => 'apple.phtml', // Perperation for adding ability to customized OAuth UI forms, currently handled hardcoded.
'beta' => true,
'mock' => false,
@@ -24,6 +26,7 @@ return [ // Ordered by ABC.
'developers' => 'https://developer.atlassian.com/bitbucket',
'icon' => 'icon-bitbucket',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false,
@@ -33,6 +36,7 @@ return [ // Ordered by ABC.
'developers' => 'https://dev.bitly.com/v4_documentation.html',
'icon' => 'icon-bitly',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false
@@ -42,6 +46,7 @@ return [ // Ordered by ABC.
'developers' => 'https://developer.box.com/reference/',
'icon' => 'icon-box',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false
@@ -51,6 +56,7 @@ return [ // Ordered by ABC.
'developers' => 'https://discordapp.com/developers/docs/topics/oauth2',
'icon' => 'icon-discord',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false,
@@ -60,6 +66,7 @@ return [ // Ordered by ABC.
'developers' => 'https://www.dropbox.com/developers/documentation',
'icon' => 'icon-dropbox',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false,
@@ -69,6 +76,7 @@ return [ // Ordered by ABC.
'developers' => 'https://developers.facebook.com/',
'icon' => 'icon-facebook',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false,
@@ -78,6 +86,7 @@ return [ // Ordered by ABC.
'developers' => 'https://developer.github.com/',
'icon' => 'icon-github-circled',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false,
@@ -87,6 +96,7 @@ return [ // Ordered by ABC.
'developers' => 'https://docs.gitlab.com/ee/api/',
'icon' => 'icon-gitlab',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false,
@@ -96,6 +106,7 @@ return [ // Ordered by ABC.
'developers' => 'https://support.google.com/googleapi/answer/6158849',
'icon' => 'icon-google',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false,
@@ -105,6 +116,7 @@ return [ // Ordered by ABC.
'developers' => 'https://developer.linkedin.com/',
'icon' => 'icon-linkedin',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false,
@@ -114,6 +126,7 @@ return [ // Ordered by ABC.
'developers' => 'https://developer.microsoft.com/en-us/',
'icon' => 'icon-windows',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false,
@@ -123,15 +136,17 @@ return [ // Ordered by ABC.
'developers' => 'https://developer.paypal.com/docs/api/overview/',
'icon' => 'icon-paypal',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false
],
'paypalSandbox' => [
'name' => 'PayPal (Sandbox)',
'name' => 'PayPal',
'developers' => 'https://developer.paypal.com/docs/api/overview/',
'icon' => 'icon-paypal',
'enabled' => true,
'sandbox' => true,
'form' => false,
'beta' => false,
'mock' => false
@@ -141,6 +156,7 @@ return [ // Ordered by ABC.
'developers' => 'https://developer.salesforce.com/docs/',
'icon' => 'icon-salesforce',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false,
@@ -150,6 +166,7 @@ return [ // Ordered by ABC.
'developers' => 'https://api.slack.com/',
'icon' => 'icon-slack',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false,
@@ -159,6 +176,7 @@ return [ // Ordered by ABC.
'developers' => 'https://developer.spotify.com/documentation/general/guides/authorization-guide/',
'icon' => 'icon-spotify',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false,
@@ -168,15 +186,17 @@ return [ // Ordered by ABC.
'developers' => 'https://developers.tradeshift.com/docs/api',
'icon' => 'icon-tradeshift',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false,
],
'tradeshiftBox' => [
'name' => 'Tradeshift Sandbox',
'name' => 'Tradeshift',
'developers' => 'https://developers.tradeshift.com/docs/api',
'icon' => 'icon-tradeshiftbox',
'enabled' => true,
'sandbox' => true,
'form' => false,
'beta' => false,
'mock' => false,
@@ -186,6 +206,7 @@ return [ // Ordered by ABC.
'developers' => 'https://dev.twitch.tv/docs/authentication',
'icon' => 'icon-twitch',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false,
@@ -195,6 +216,7 @@ return [ // Ordered by ABC.
'developers' => 'https://vk.com/dev',
'icon' => 'icon-vk',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false,
@@ -204,6 +226,7 @@ return [ // Ordered by ABC.
'developers' => 'https://developer.yahoo.com/oauth2/guide/flows_authcode/',
'icon' => 'icon-yahoo',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false,
@@ -213,6 +236,7 @@ return [ // Ordered by ABC.
'developers' => 'https://tech.yandex.com/oauth/',
'icon' => 'icon-yandex',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false,
@@ -238,6 +262,7 @@ return [ // Ordered by ABC.
'developers' => 'https://developer.wordpress.com/docs/oauth2/',
'icon' => 'icon-wordpress',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => false
@@ -248,6 +273,7 @@ return [ // Ordered by ABC.
'developers' => 'https://appwrite.io',
'icon' => 'icon-appwrite',
'enabled' => true,
'sandbox' => false,
'form' => false,
'beta' => false,
'mock' => true,
-2
View File
@@ -60,8 +60,6 @@ return [
'files.read',
'locale.read',
'avatars.read',
'execution.read',
'execution.write',
],
],
Auth::USER_ROLE_MEMBER => [
+15
View File
@@ -0,0 +1,15 @@
<?php
use Utopia\App;
use Appwrite\Runtimes\Runtimes;
/**
* List of Appwrite Cloud Functions supported runtimes
*/
$runtimes = new Runtimes();
$allowList = empty(App::getEnv('_APP_FUNCTIONS_RUNTIMES')) ? [] : \explode(',', App::getEnv('_APP_FUNCTIONS_RUNTIMES'));
$runtimes = $runtimes->getAll(true, $allowList);
return $runtimes;
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+91 -10
View File
@@ -14,6 +14,16 @@ return [
'default' => 'production',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_LOCALE',
'description' => 'Set your Appwrite\'s locale. By default, the locale is set to \'en\'.',
'introduction' => '',
'default' => 'en',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_OPTIONS_ABUSE',
@@ -22,14 +32,16 @@ return [
'default' => 'enabled',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_OPTIONS_FORCE_HTTPS',
'description' => 'Allows you to force HTTPS connection to your API. This feature redirects any HTTP call to HTTPS and adds the \'Strict-Transport-Security\' header to all HTTP responses. By default, set to \'disabled\'. To enable, set to \'enabled\'. This feature will work only when your ports are set to default 80 and 443.',
'description' => 'Allows you to force HTTPS connection to your API. This feature redirects any HTTP call to HTTPS and adds the \'Strict-Transport-Security\' header to all HTTP responses. By default, set to \'enabled\'. To disable, set to \'disabled\'. This feature will work only when your ports are set to default 80 and 443.',
'introduction' => '',
'default' => 'enabled',
'default' => 'disabled',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_OPENSSL_KEY_V1',
@@ -38,6 +50,7 @@ return [
'default' => 'your-secret-key',
'required' => true,
'question' => 'Choose a secret API key, make sure to make a backup of your key in a secure location',
'filter' => 'token'
],
[
'name' => '_APP_DOMAIN',
@@ -46,6 +59,7 @@ return [
'default' => 'localhost',
'required' => true,
'question' => 'Enter your Appwrite hostname',
'filter' => ''
],
[
'name' => '_APP_DOMAIN_TARGET',
@@ -54,14 +68,25 @@ return [
'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.',
'filter' => ''
],
[
'name' => '_APP_CONSOLE_WHITELIST_ROOT',
'description' => 'This option allows you to disable the creation of new users on the Appwrite console. When enabled only 1 user will be able to use the registration form. New users can be added by invting them to your project. By default this option is enabled.',
'introduction' => '0.8.0',
'default' => 'enabled',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_CONSOLE_WHITELIST_EMAILS',
'description' => 'This option allows you to limit creation of users to Appwrite console. This option is very useful for small teams or sole developers. To enable it, pass a list of allowed email addresses separated by a comma.',
'description' => 'This option allows you to limit creation of new users on the Appwrite console. This option is very useful for small teams or sole developers. To enable it, pass a list of allowed email addresses separated by a comma.',
'introduction' => '',
'default' => '',
'required' => false,
'question' => '',
'filter' => ''
],
// [
// 'name' => '_APP_CONSOLE_WHITELIST_DOMAINS',
@@ -78,6 +103,7 @@ return [
'default' => '',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_SYSTEM_EMAIL_NAME',
@@ -86,6 +112,7 @@ return [
'default' => 'Appwrite',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_SYSTEM_EMAIL_ADDRESS',
@@ -94,6 +121,7 @@ return [
'default' => 'team@appwrite.io',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_SYSTEM_RESPONSE_FORMAT',
@@ -102,6 +130,7 @@ return [
'default' => '',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_SYSTEM_SECURITY_EMAIL_ADDRESS',
@@ -110,6 +139,7 @@ return [
'default' => 'certs@appwrite.io',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_USAGE_STATS',
@@ -118,7 +148,8 @@ return [
'default' => 'enabled',
'required' => false,
'question' => '',
],
'filter' => ''
]
],
],
[
@@ -132,6 +163,7 @@ return [
'default' => 'redis',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_REDIS_PORT',
@@ -140,22 +172,25 @@ return [
'default' => '6379',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_REDIS_USER',
'description' => 'Redis server user.',
'description' => 'Redis server user. This is an optional variable. Default value is an empty string.',
'introduction' => '0.7',
'default' => '',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_REDIS_PASS',
'description' => 'Redis server password.',
'description' => 'Redis server password. This is an optional variable. Default value is an empty string.',
'introduction' => '0.7',
'default' => '',
'required' => false,
'question' => '',
'filter' => ''
],
],
],
@@ -170,6 +205,7 @@ return [
'default' => 'mariadb',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_DB_PORT',
@@ -178,6 +214,7 @@ return [
'default' => '3306',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_DB_SCHEMA',
@@ -186,6 +223,7 @@ return [
'default' => 'appwrite',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_DB_USER',
@@ -194,6 +232,7 @@ return [
'default' => 'user',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_DB_PASS',
@@ -202,6 +241,16 @@ return [
'default' => 'password',
'required' => false,
'question' => '',
'filter' => 'password'
],
[
'name' => '_APP_DB_ROOT_PASS',
'description' => 'MariaDB server root password. Default value is: \'rootsecretpassword\'.',
'introduction' => '',
'default' => 'rootsecretpassword',
'required' => false,
'question' => '',
'filter' => 'password'
],
],
],
@@ -216,6 +265,7 @@ return [
'default' => 'influxdb',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_INFLUXDB_PORT',
@@ -224,6 +274,7 @@ return [
'default' => '8086',
'required' => false,
'question' => '',
'filter' => ''
],
],
],
@@ -238,6 +289,7 @@ return [
'default' => 'telegraf',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_STATSD_PORT',
@@ -246,6 +298,7 @@ return [
'default' => '8125',
'required' => false,
'question' => '',
'filter' => ''
],
],
],
@@ -260,6 +313,7 @@ return [
'default' => '',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_SMTP_PORT',
@@ -268,6 +322,7 @@ return [
'default' => '',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_SMTP_SECURE',
@@ -276,6 +331,7 @@ return [
'default' => '',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_SMTP_USERNAME',
@@ -284,6 +340,7 @@ return [
'default' => '',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_SMTP_PASSWORD',
@@ -292,6 +349,7 @@ return [
'default' => '',
'required' => false,
'question' => '',
'filter' => ''
],
],
],
@@ -306,14 +364,16 @@ return [
'default' => '10000000',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_STORAGE_ANTIVIRUS',
'description' => 'This variable allows you to disable the internal anti-virus scans. This value is set to \'enabled\' by default, to cancel the scans set the value to \'disabled\'. When disabled, it\'s recommended to turn off the ClamAV container for better resource usage.',
'description' => 'This variable allows you to disable the internal anti-virus scans. This value is set to \'disabled\' by default, to enable the scans set the value to \'enabled\'. Before enabling, you must add the ClamAV service and depend on it on main Appwrite service.',
'introduction' => '',
'default' => 'enabled',
'default' => 'disabled',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_STORAGE_ANTIVIRUS_HOST',
@@ -322,6 +382,7 @@ return [
'default' => 'clamav',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_STORAGE_ANTIVIRUS_PORT',
@@ -330,6 +391,7 @@ return [
'default' => '3310',
'required' => false,
'question' => '',
'filter' => ''
],
],
],
@@ -344,6 +406,7 @@ return [
'default' => '900',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_FUNCTIONS_CONTAINERS',
@@ -352,6 +415,7 @@ return [
'default' => '10',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_FUNCTIONS_CPUS',
@@ -360,6 +424,7 @@ return [
'default' => '',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_FUNCTIONS_MEMORY',
@@ -368,6 +433,7 @@ return [
'default' => '256',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_FUNCTIONS_MEMORY_SWAP',
@@ -376,14 +442,25 @@ return [
'default' => '256',
'required' => false,
'question' => '',
'filter' => ''
],
[
'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',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_FUNCTIONS_ENVS',
'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('providers'))),
'description' => 'Deprectated with 0.8.0, use \'_APP_FUNCTIONS_RUNTIMES\' instead!',
'introduction' => '0.7.0',
'default' => 'node-14.5,deno-1.6,php-7.4,python-3.8,ruby-3.0,dotnet-5.0',
'default' => 'node-14.5,deno-1.8,php-7.4,python-3.9,ruby-3.0,dotnet-5.0',
'required' => false,
'question' => '',
'filter' => ''
],
],
[
@@ -397,6 +474,7 @@ return [
'default' => '86400',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_MAINTENANCE_RETENTION_EXECUTION',
@@ -405,6 +483,7 @@ return [
'default' => '1209600',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_MAINTENANCE_RETENTION_AUDIT',
@@ -413,6 +492,7 @@ return [
'default' => '1209600',
'required' => false,
'question' => '',
'filter' => ''
],
[
'name' => '_APP_MAINTENANCE_RETENTION_ABUSE',
@@ -421,6 +501,7 @@ return [
'default' => '86400',
'required' => false,
'question' => '',
'filter' => ''
]
],
],
+313 -103
View File
@@ -6,10 +6,10 @@ use Utopia\Exception;
use Utopia\Config\Config;
use Utopia\Validator\Assoc;
use Utopia\Validator\Text;
use Utopia\Validator\Email;
use Appwrite\Network\Validator\Email;
use Utopia\Validator\WhiteList;
use Utopia\Validator\Host;
use Utopia\Validator\URL;
use Appwrite\Network\Validator\Host;
use Appwrite\Network\Validator\URL;
use Utopia\Audit\Audit;
use Utopia\Audit\Adapters\MySQL as AuditAdapter;
use Appwrite\Auth\Auth;
@@ -31,10 +31,11 @@ $oauthDefaultFailure = App::getEnv('_APP_HOME').'/auth/oauth2/failure';
App::post('/v1/account')
->desc('Create Account')
->groups(['api', 'account'])
->groups(['api', 'account', 'auth'])
->label('event', 'account.create')
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('auth.type', 'emailPassword')
->label('sdk.auth', [])
->label('sdk.namespace', 'account')
->label('sdk.method', 'create')
->label('sdk.description', '/docs/references/account/create.md')
@@ -60,7 +61,6 @@ App::post('/v1/account')
if ('console' === $project->getId()) {
$whitlistEmails = $project->getAttribute('authWhitelistEmails');
$whitlistIPs = $project->getAttribute('authWhitelistIPs');
$whitlistDomains = $project->getAttribute('authWhitelistDomains');
if (!empty($whitlistEmails) && !\in_array($email, $whitlistEmails)) {
throw new Exception('Console registration is restricted to specific emails. Contact your administrator for more information.', 401);
@@ -69,9 +69,21 @@ App::post('/v1/account')
if (!empty($whitlistIPs) && !\in_array($request->getIP(), $whitlistIPs)) {
throw new Exception('Console registration is restricted to specific IPs. Contact your administrator for more information.', 401);
}
}
if (!empty($whitlistDomains) && !\in_array(\substr(\strrchr($email, '@'), 1), $whitlistDomains)) {
throw new Exception('Console registration is restricted to specific domains. Contact your administrator for more information.', 401);
$limit = $project->getAttribute('usersAuthLimit', 0);
if ($limit !== 0) {
$projectDB->getCollection([ // Count users
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_USERS,
],
]);
$sum = $projectDB->getSum();
if($sum >= $limit) {
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501);
}
}
@@ -109,7 +121,7 @@ App::post('/v1/account')
throw new Exception('Account already exists', 409);
}
Authorization::enable();
Authorization::reset();
Authorization::unsetRole('role:'.Auth::USER_ROLE_GUEST);
Authorization::setRole('user:'.$user->getId());
@@ -133,10 +145,11 @@ App::post('/v1/account')
App::post('/v1/account/sessions')
->desc('Create Account Session')
->groups(['api', 'account'])
->groups(['api', 'account', 'auth'])
->label('event', 'account.sessions.create')
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('auth.type', 'emailPassword')
->label('sdk.auth', [])
->label('sdk.namespace', 'account')
->label('sdk.method', 'createSession')
->label('sdk.description', '/docs/references/account/create-session.md')
@@ -190,10 +203,11 @@ App::post('/v1/account/sessions')
$secret = Auth::tokenGenerator();
$session = new Document(array_merge(
[
'$collection' => Database::SYSTEM_COLLECTION_TOKENS,
'$collection' => Database::SYSTEM_COLLECTION_SESSIONS,
'$permissions' => ['read' => ['user:'.$profile->getId()], 'write' => ['user:'.$profile->getId()]],
'userId' => $profile->getId(),
'type' => Auth::TOKEN_TYPE_LOGIN,
'provider' => Auth::SESSION_PROVIDER_EMAIL,
'providerUid' => $email,
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
'expire' => $expiry,
'userAgent' => $request->getUserAgent('UNKNOWN'),
@@ -210,7 +224,7 @@ App::post('/v1/account/sessions')
throw new Exception('Failed saving session to DB', 500);
}
$profile->setAttribute('tokens', $session, Document::SET_TYPE_APPEND);
$profile->setAttribute('sessions', $session, Document::SET_TYPE_APPEND);
$profile = $projectDB->updateDocument($profile->getArrayCopy());
@@ -251,7 +265,7 @@ App::get('/v1/account/sessions/oauth2/:provider')
->groups(['api', 'account'])
->label('error', __DIR__.'/../../views/general/error.phtml')
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.auth', [])
->label('sdk.namespace', 'account')
->label('sdk.method', 'createOAuth2Session')
->label('sdk.description', '/docs/references/account/create-session-oauth2.md')
@@ -372,7 +386,8 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
->inject('projectDB')
->inject('geodb')
->inject('audits')
->action(function ($provider, $code, $state, $request, $response, $project, $user, $projectDB, $geodb, $audits) use ($oauthDefaultSuccess) {
->inject('events')
->action(function ($provider, $code, $state, $request, $response, $project, $user, $projectDB, $geodb, $audits, $events) use ($oauthDefaultSuccess) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */
@@ -441,7 +456,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
throw new Exception('Missing ID from OAuth2 provider', 400);
}
$current = Auth::tokenVerify($user->getAttribute('tokens', []), Auth::TOKEN_TYPE_LOGIN, Auth::$secret);
$current = Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret);
if ($current) {
$projectDB->deleteDocument($current); //throw new Exception('User already logged in', 401);
@@ -451,7 +466,8 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
'limit' => 1,
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_USERS,
'oauth2'.\ucfirst($provider).'='.$oauth2ID,
'sessions.provider='.$provider,
'sessions.providerUid='.$oauth2ID
],
]) : $user;
@@ -467,7 +483,23 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
],
]);
if (!$user || empty($user->getId())) { // Last option -> create user alone, generate random password
if (!$user || empty($user->getId())) { // Last option -> create the user, generate random password
$limit = $project->getAttribute('usersAuthLimit', 0);
if ($limit !== 0) {
$projectDB->getCollection([ // Count users
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_USERS,
],
]);
$sum = $projectDB->getSum();
if($sum >= $limit) {
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501);
}
}
Authorization::disable();
try {
@@ -478,7 +510,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
'emailVerification' => true,
'status' => Auth::USER_STATUS_ACTIVATED, // Email should already be authenticated by OAuth2 provider
'password' => Auth::passwordHash(Auth::passwordGenerator()),
'passwordUpdate' => \time(),
'passwordUpdate' => 0,
'registration' => \time(),
'reset' => false,
'name' => $name,
@@ -487,7 +519,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
throw new Exception('Account already exists', 409);
}
Authorization::enable();
Authorization::reset();
if (false === $user) {
throw new Exception('Failed saving user to DB', 500);
@@ -506,10 +538,12 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
$secret = Auth::tokenGenerator();
$expiry = \time() + Auth::TOKEN_EXPIRATION_LOGIN_LONG;
$session = new Document(array_merge([
'$collection' => Database::SYSTEM_COLLECTION_TOKENS,
'$collection' => Database::SYSTEM_COLLECTION_SESSIONS,
'$permissions' => ['read' => ['user:'.$user['$id']], 'write' => ['user:'.$user['$id']]],
'userId' => $user->getId(),
'type' => Auth::TOKEN_TYPE_LOGIN,
'provider' => $provider,
'providerUid' => $oauth2ID,
'providerToken' => $accessToken,
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
'expire' => $expiry,
'userAgent' => $request->getUserAgent('UNKNOWN'),
@@ -517,11 +551,18 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--',
], $detector->getOS(), $detector->getClient(), $detector->getDevice()));
$isAnonymousUser = is_null($user->getAttribute('email')) && is_null($user->getAttribute('password'));
if ($isAnonymousUser) {
$user
->setAttribute('name', $oauth2->getUserName($accessToken))
->setAttribute('email', $oauth2->getUserEmail($accessToken))
;
}
$user
->setAttribute('oauth2'.\ucfirst($provider), $oauth2ID)
->setAttribute('oauth2'.\ucfirst($provider).'AccessToken', $accessToken)
->setAttribute('status', Auth::USER_STATUS_ACTIVATED)
->setAttribute('tokens', $session, Document::SET_TYPE_APPEND)
->setAttribute('sessions', $session, Document::SET_TYPE_APPEND)
;
Authorization::setRole('user:'.$user->getId());
@@ -539,6 +580,8 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
->setParam('data', ['provider' => $provider])
;
$events->setParam('eventData', $response->output($session, Response::MODEL_SESSION));
if (!Config::getParam('domainVerification')) {
$response
->addHeader('X-Fallback-Cookies', \json_encode([Auth::$cookieName => Auth::encodeSession($user->getId(), $secret)]))
@@ -566,15 +609,168 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
;
});
App::post('/v1/account/sessions/anonymous')
->desc('Create Anonymous Session')
->groups(['api', 'account', 'auth'])
->label('event', 'account.sessions.create')
->label('scope', 'public')
->label('auth.type', 'anonymous')
->label('sdk.auth', [])
->label('sdk.namespace', 'account')
->label('sdk.method', 'createAnonymousSession')
->label('sdk.description', '/docs/references/account/create-session-anonymous.md')
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_SESSION)
->label('abuse-limit', 50)
->label('abuse-key', 'ip:{ip}')
->inject('request')
->inject('response')
->inject('locale')
->inject('user')
->inject('project')
->inject('projectDB')
->inject('geodb')
->inject('audits')
->action(function ($request, $response, $locale, $user, $project, $projectDB, $geodb, $audits) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Locale\Locale $locale */
/** @var Appwrite\Database\Document $user */
/** @var Appwrite\Database\Document $project */
/** @var Appwrite\Database\Database $projectDB */
/** @var MaxMind\Db\Reader $geodb */
/** @var Appwrite\Event\Event $audits */
$protocol = $request->getProtocol();
if ('console' === $project->getId()) {
throw new Exception('Failed to create anonymous user.', 401);
}
if ($user->getId()) {
throw new Exception('Cannot create an anonymous user when logged in.', 401);
}
$limit = $project->getAttribute('usersAuthLimit', 0);
if ($limit !== 0) {
$projectDB->getCollection([ // Count users
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_USERS,
],
]);
$sum = $projectDB->getSum();
if($sum >= $limit) {
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501);
}
}
Authorization::disable();
try {
$user = $projectDB->createDocument([
'$collection' => Database::SYSTEM_COLLECTION_USERS,
'$permissions' => [
'read' => ['*'],
'write' => ['user:{self}']
],
'email' => null,
'emailVerification' => false,
'status' => Auth::USER_STATUS_UNACTIVATED,
'password' => null,
'passwordUpdate' => \time(),
'registration' => \time(),
'reset' => false,
'name' => null
]);
} catch (Exception $th) {
throw new Exception('Failed saving user to DB', 500);
}
Authorization::reset();
if (false === $user) {
throw new Exception('Failed saving user to DB', 500);
}
// Create session token
$detector = new Detector($request->getUserAgent('UNKNOWN'));
$record = $geodb->get($request->getIP());
$secret = Auth::tokenGenerator();
$expiry = \time() + Auth::TOKEN_EXPIRATION_LOGIN_LONG;
$session = new Document(array_merge(
[
'$collection' => Database::SYSTEM_COLLECTION_SESSIONS,
'$permissions' => ['read' => ['user:' . $user['$id']], 'write' => ['user:' . $user['$id']]],
'userId' => $user->getId(),
'provider' => Auth::SESSION_PROVIDER_ANONYMOUS,
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
'expire' => $expiry,
'userAgent' => $request->getUserAgent('UNKNOWN'),
'ip' => $request->getIP(),
'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--',
],
$detector->getOS(),
$detector->getClient(),
$detector->getDevice()
));
Authorization::setRole('user:'.$user->getId());
$session = $projectDB->createDocument($session->getArrayCopy());
if (false === $session) {
throw new Exception('Failed saving session to DB', 500);
}
$user->setAttribute('sessions', $session, Document::SET_TYPE_APPEND);
$user = $projectDB->updateDocument($user->getArrayCopy());
if (false === $user) {
throw new Exception('Failed saving user to DB', 500);
}
$audits
->setParam('userId', $user->getId())
->setParam('event', 'account.sessions.create')
->setParam('resource', 'users/'.$user->getId())
;
if (!Config::getParam('domainVerification')) {
$response
->addHeader('X-Fallback-Cookies', \json_encode([Auth::$cookieName => Auth::encodeSession($user->getId(), $secret)]))
;
}
$response
->addCookie(Auth::$cookieName.'_legacy', Auth::encodeSession($user->getId(), $secret), $expiry, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, null)
->addCookie(Auth::$cookieName, Auth::encodeSession($user->getId(), $secret), $expiry, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, Config::getParam('cookieSamesite'))
->setStatusCode(Response::STATUS_CODE_CREATED)
;
$session
->setAttribute('current', true)
->setAttribute('countryName', (isset($countries[$session->getAttribute('countryCode')])) ? $countries[$session->getAttribute('countryCode')] : $locale->getText('locale.country.unknown'))
;
$response->dynamic($session, Response::MODEL_SESSION);
});
App::post('/v1/account/jwt')
->desc('Create Account JWT')
->groups(['api', 'account'])
->groups(['api', 'account', 'auth'])
->label('scope', 'account')
->label('docs', false) // Hidden for now - private beta
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('auth.type', 'jwt')
->label('sdk.auth', [APP_AUTH_TYPE_SESSION])
->label('sdk.namespace', 'account')
->label('sdk.method', 'createJWT')
->label('sdk.description', '/docs/references/account/create-jwt.md')
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
->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}')
->inject('response')
@@ -583,16 +779,18 @@ App::post('/v1/account/jwt')
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $user */
$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()) {
throw new Exception('No valid session found', 401);
}
@@ -606,7 +804,7 @@ App::post('/v1/account/jwt')
// 'scopes' => ['user'],
// 'iss' => 'http://api.mysite.com',
'userId' => $user->getId(),
'sessionId' => $session->getId(),
'sessionId' => $current->getId(),
])]), Response::MODEL_JWT);
});
@@ -614,7 +812,7 @@ App::get('/v1/account')
->desc('Get Account')
->groups(['api', 'account'])
->label('scope', 'account')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'account')
->label('sdk.method', 'get')
->label('sdk.description', '/docs/references/account/get.md')
@@ -634,13 +832,13 @@ App::get('/v1/account/prefs')
->desc('Get Account Preferences')
->groups(['api', 'account'])
->label('scope', 'account')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'account')
->label('sdk.method', 'getPrefs')
->label('sdk.description', '/docs/references/account/get-prefs.md')
->label('sdk.response.code', Response::STATUS_CODE_OK)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_ANY)
->label('sdk.response.model', Response::MODEL_PREFERENCES)
->inject('response')
->inject('user')
->action(function ($response, $user) {
@@ -649,14 +847,14 @@ App::get('/v1/account/prefs')
$prefs = $user->getAttribute('prefs', new \stdClass());
$response->dynamic(new Document($prefs), Response::MODEL_ANY);
$response->dynamic(new Document($prefs), Response::MODEL_PREFERENCES);
});
App::get('/v1/account/sessions')
->desc('Get Account Sessions')
->groups(['api', 'account'])
->label('scope', 'account')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'account')
->label('sdk.method', 'getSessions')
->label('sdk.description', '/docs/references/account/get-sessions.md')
@@ -671,22 +869,19 @@ App::get('/v1/account/sessions')
/** @var Appwrite\Database\Document $user */
/** @var Utopia\Locale\Locale $locale */
$tokens = $user->getAttribute('tokens', []);
$sessions = [];
$sessions = $user->getAttribute('sessions', []);
$countries = $locale->getText('countries');
$current = Auth::tokenVerify($tokens, Auth::TOKEN_TYPE_LOGIN, Auth::$secret);
$current = Auth::sessionVerify($sessions, Auth::$secret);
foreach ($tokens as $token) { /* @var $token Document */
if (Auth::TOKEN_TYPE_LOGIN != $token->getAttribute('type')) {
continue;
}
foreach ($sessions as $key => $session) {
/** @var Document $session */
$token->setAttribute('countryName', (isset($countries[strtoupper($token->getAttribute('countryCode'))]))
? $countries[strtoupper($token->getAttribute('countryCode'))]
$session->setAttribute('countryName', (isset($countries[strtoupper($session->getAttribute('countryCode'))]))
? $countries[strtoupper($session->getAttribute('countryCode'))]
: $locale->getText('locale.country.unknown'));
$token->setAttribute('current', ($current == $token->getId()) ? true : false);
$session->setAttribute('current', ($current == $session->getId()) ? true : false);
$sessions[] = $token;
$sessions[$key] = $session;
}
$response->dynamic(new Document([
@@ -699,7 +894,7 @@ App::get('/v1/account/logs')
->desc('Get Account Logs')
->groups(['api', 'account'])
->label('scope', 'account')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'account')
->label('sdk.method', 'getLogs')
->label('sdk.description', '/docs/references/account/get-logs.md')
@@ -776,7 +971,7 @@ App::patch('/v1/account/name')
->groups(['api', 'account'])
->label('event', 'account.update.name')
->label('scope', 'account')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'account')
->label('sdk.method', 'updateName')
->label('sdk.description', '/docs/references/account/update-name.md')
@@ -816,7 +1011,7 @@ App::patch('/v1/account/password')
->groups(['api', 'account'])
->label('event', 'account.update.password')
->label('scope', 'account')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'account')
->label('sdk.method', 'updatePassword')
->label('sdk.description', '/docs/references/account/update-password.md')
@@ -824,7 +1019,7 @@ App::patch('/v1/account/password')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_USER)
->param('password', '', new Password(), 'New user password. Must be between 6 to 32 chars.')
->param('oldPassword', '', new Password(), 'Old user password. Must be between 6 to 32 chars.')
->param('oldPassword', '', new Password(), 'Old user password. Must be between 6 to 32 chars.', true)
->inject('response')
->inject('user')
->inject('projectDB')
@@ -835,12 +1030,14 @@ App::patch('/v1/account/password')
/** @var Appwrite\Database\Database $projectDB */
/** @var Appwrite\Event\Event $audits */
if (!Auth::passwordVerify($oldPassword, $user->getAttribute('password'))) { // Double check user password
// Check old password only if its an existing user.
if ($user->getAttribute('passwordUpdate') !== 0 && !Auth::passwordVerify($oldPassword, $user->getAttribute('password'))) { // Double check user password
throw new Exception('Invalid credentials', 401);
}
$user = $projectDB->updateDocument(\array_merge($user->getArrayCopy(), [
'password' => Auth::passwordHash($password),
'passwordUpdate' => \time(),
]));
if (false === $user) {
@@ -861,7 +1058,7 @@ App::patch('/v1/account/email')
->groups(['api', 'account'])
->label('event', 'account.update.email')
->label('scope', 'account')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'account')
->label('sdk.method', 'updateEmail')
->label('sdk.description', '/docs/references/account/update-email.md')
@@ -880,7 +1077,12 @@ App::patch('/v1/account/email')
/** @var Appwrite\Database\Database $projectDB */
/** @var Appwrite\Event\Event $audits */
if (!Auth::passwordVerify($password, $user->getAttribute('password'))) { // Double check user password
$isAnonymousUser = is_null($user->getAttribute('email')) && is_null($user->getAttribute('password')); // Check if request is from an anonymous account for converting
if (
!$isAnonymousUser &&
!Auth::passwordVerify($password, $user->getAttribute('password'))
) { // Double check user password
throw new Exception('Invalid credentials', 401);
}
@@ -898,10 +1100,14 @@ App::patch('/v1/account/email')
// TODO after this user needs to confirm mail again
$user = $projectDB->updateDocument(\array_merge($user->getArrayCopy(), [
'email' => $email,
'emailVerification' => false,
]));
$user = $projectDB->updateDocument(\array_merge(
$user->getArrayCopy(),
($isAnonymousUser ? [ 'password' => Auth::passwordHash($password) ] : []),
[
'email' => $email,
'emailVerification' => false,
]
));
if (false === $user) {
throw new Exception('Failed saving user to DB', 500);
@@ -921,13 +1127,13 @@ App::patch('/v1/account/prefs')
->groups(['api', 'account'])
->label('event', 'account.update.prefs')
->label('scope', 'account')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'account')
->label('sdk.method', 'updatePrefs')
->label('sdk.description', '/docs/references/account/update-prefs.md')
->label('sdk.response.code', Response::STATUS_CODE_OK)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_ANY)
->label('sdk.response.model', Response::MODEL_USER)
->param('prefs', [], new Assoc(), 'Prefs key-value JSON object.')
->inject('response')
->inject('user')
@@ -960,7 +1166,7 @@ App::delete('/v1/account')
->groups(['api', 'account'])
->label('event', 'account.delete')
->label('scope', 'account')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'account')
->label('sdk.method', 'delete')
->label('sdk.description', '/docs/references/account/delete.md')
@@ -1005,7 +1211,7 @@ App::delete('/v1/account')
;
$events
->setParam('payload', $response->output($user, Response::MODEL_USER))
->setParam('eventData', $response->output($user, Response::MODEL_USER))
;
if (!Config::getParam('domainVerification')) {
@@ -1026,7 +1232,7 @@ App::delete('/v1/account/sessions/:sessionId')
->groups(['api', 'account'])
->label('scope', 'account')
->label('event', 'account.sessions.delete')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'account')
->label('sdk.method', 'deleteSession')
->label('sdk.description', '/docs/references/account/delete-session.md')
@@ -1050,14 +1256,16 @@ App::delete('/v1/account/sessions/:sessionId')
$protocol = $request->getProtocol();
$sessionId = ($sessionId === 'current')
? Auth::tokenVerify($user->getAttribute('tokens'), Auth::TOKEN_TYPE_LOGIN, Auth::$secret)
? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret)
: $sessionId;
$tokens = $user->getAttribute('tokens', []);
$sessions = $user->getAttribute('sessions', []);
foreach ($tokens as $token) { /* @var $token Document */
if (($sessionId == $token->getId()) && Auth::TOKEN_TYPE_LOGIN == $token->getAttribute('type')) {
if (!$projectDB->deleteDocument($token->getId())) {
foreach ($sessions as $session) {
/** @var Document $session */
if (($sessionId == $session->getId())) {
if (!$projectDB->deleteDocument($session->getId())) {
throw new Exception('Failed to remove token from DB', 500);
}
@@ -1067,16 +1275,16 @@ App::delete('/v1/account/sessions/:sessionId')
->setParam('resource', '/user/'.$user->getId())
;
if (!Config::getParam('domainVerification')) {
$response
->addHeader('X-Fallback-Cookies', \json_encode([]))
;
}
$session->setAttribute('current', false);
$token->setAttribute('current', false);
if ($token->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too
$token->setAttribute('current', true);
if ($session->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too
$session->setAttribute('current', true);
if (!Config::getParam('domainVerification')) {
$response
->addHeader('X-Fallback-Cookies', \json_encode([]))
;
}
$response
->addCookie(Auth::$cookieName.'_legacy', '', \time() - 3600, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, null)
@@ -1085,7 +1293,7 @@ App::delete('/v1/account/sessions/:sessionId')
}
$events
->setParam('payload', $response->output($token, Response::MODEL_SESSION))
->setParam('eventData', $response->output($session, Response::MODEL_SESSION))
;
return $response->noContent();
@@ -1100,7 +1308,7 @@ App::delete('/v1/account/sessions')
->groups(['api', 'account'])
->label('scope', 'account')
->label('event', 'account.sessions.delete')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'account')
->label('sdk.method', 'deleteSessions')
->label('sdk.description', '/docs/references/account/delete-sessions.md')
@@ -1122,10 +1330,12 @@ App::delete('/v1/account/sessions')
/** @var Appwrite\Event\Event $events */
$protocol = $request->getProtocol();
$tokens = $user->getAttribute('tokens', []);
$sessions = $user->getAttribute('sessions', []);
foreach ($tokens as $token) { /* @var $token Document */
if (!$projectDB->deleteDocument($token->getId())) {
foreach ($sessions as $session) {
/** @var Document $session */
if (!$projectDB->deleteDocument($session->getId())) {
throw new Exception('Failed to remove token from DB', 500);
}
@@ -1141,10 +1351,10 @@ App::delete('/v1/account/sessions')
;
}
$token->setAttribute('current', false);
$session->setAttribute('current', false);
if ($token->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too
$token->setAttribute('current', true);
if ($session->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too
$session->setAttribute('current', true);
$response
->addCookie(Auth::$cookieName.'_legacy', '', \time() - 3600, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, null)
->addCookie(Auth::$cookieName, '', \time() - 3600, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, Config::getParam('cookieSamesite'))
@@ -1153,9 +1363,9 @@ App::delete('/v1/account/sessions')
}
$events
->setParam('payload', $response->output(new Document([
'sum' => count($tokens),
'sessions' => $tokens
->setParam('eventData', $response->output(new Document([
'sum' => count($sessions),
'sessions' => $sessions
]), Response::MODEL_SESSION_LIST))
;
@@ -1167,7 +1377,7 @@ App::post('/v1/account/recovery')
->groups(['api', 'account'])
->label('scope', 'public')
->label('event', 'account.recovery.create')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'account')
->label('sdk.method', 'createRecovery')
->label('sdk.description', '/docs/references/account/create-recovery.md')
@@ -1196,7 +1406,7 @@ App::post('/v1/account/recovery')
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Event\Event $events */
$isPreviliggedUser = Auth::isPreviliggedUser(Authorization::$roles);
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles);
$isAppUser = Auth::isAppUser(Authorization::$roles);
$profile = $projectDB->getCollectionFirst([ // Get user by email address
@@ -1278,7 +1488,7 @@ App::post('/v1/account/recovery')
;
$events
->setParam('payload',
->setParam('eventData',
$response->output($recovery->setAttribute('secret', $secret),
Response::MODEL_TOKEN
))
@@ -1286,7 +1496,7 @@ App::post('/v1/account/recovery')
$recovery // Hide secret for clients, sp
->setAttribute('secret',
($isPreviliggedUser || $isAppUser) ? $secret : '');
($isPrivilegedUser || $isAppUser) ? $secret : '');
$audits
->setParam('userId', $profile->getId())
@@ -1305,7 +1515,7 @@ App::put('/v1/account/recovery')
->groups(['api', 'account'])
->label('scope', 'public')
->label('event', 'account.recovery.update')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'account')
->label('sdk.method', 'updateRecovery')
->label('sdk.description', '/docs/references/account/update-recovery.md')
@@ -1384,7 +1594,7 @@ App::post('/v1/account/verification')
->groups(['api', 'account'])
->label('scope', 'account')
->label('event', 'account.verification.create')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'account')
->label('sdk.method', 'createVerification')
->label('sdk.description', '/docs/references/account/create-verification.md')
@@ -1414,7 +1624,7 @@ App::post('/v1/account/verification')
/** @var Appwrite\Event\Event $events */
/** @var Appwrite\Event\Event $mails */
$isPreviliggedUser = Auth::isPreviliggedUser(Authorization::$roles);
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles);
$isAppUser = Auth::isAppUser(Authorization::$roles);
$verificationSecret = Auth::tokenGenerator();
@@ -1481,7 +1691,7 @@ App::post('/v1/account/verification')
;
$events
->setParam('payload',
->setParam('eventData',
$response->output($verification->setAttribute('secret', $verificationSecret),
Response::MODEL_TOKEN
))
@@ -1489,7 +1699,7 @@ App::post('/v1/account/verification')
$verification // Hide secret for clients, sp
->setAttribute('secret',
($isPreviliggedUser || $isAppUser) ? $verificationSecret : '');
($isPrivilegedUser || $isAppUser) ? $verificationSecret : '');
$audits
->setParam('userId', $user->getId())
@@ -1508,7 +1718,7 @@ App::put('/v1/account/verification')
->groups(['api', 'account'])
->label('scope', 'public')
->label('event', 'account.verification.update')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'account')
->label('sdk.method', 'updateVerification')
->label('sdk.description', '/docs/references/account/update-verification.md')
+9 -9
View File
@@ -14,7 +14,7 @@ use Utopia\Validator\Boolean;
use Utopia\Validator\HexColor;
use Utopia\Validator\Range;
use Utopia\Validator\Text;
use Utopia\Validator\URL;
use Appwrite\Network\Validator\URL;
use Utopia\Validator\WhiteList;
$avatarCallback = function ($type, $code, $width, $height, $quality, $response) {
@@ -38,7 +38,7 @@ $avatarCallback = function ($type, $code, $width, $height, $quality, $response)
$output = 'png';
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT'; // 45 days cache
$key = \md5('/v1/avatars/:type/:code-' . $code . $width . $height . $quality . $output);
$key = \md5('/v1/avatars/'.$type.'/:code-' . $code . $width . $height . $quality . $output);
$path = $set[$code];
$type = 'png';
@@ -83,7 +83,7 @@ App::get('/v1/avatars/credit-cards/:code')
->desc('Get Credit Card Icon')
->groups(['api', 'avatars'])
->label('scope', 'avatars.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'avatars')
->label('sdk.method', 'getCreditCard')
->label('sdk.methodType', 'location')
@@ -103,7 +103,7 @@ App::get('/v1/avatars/browsers/:code')
->desc('Get Browser Icon')
->groups(['api', 'avatars'])
->label('scope', 'avatars.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'avatars')
->label('sdk.method', 'getBrowser')
->label('sdk.methodType', 'location')
@@ -123,7 +123,7 @@ App::get('/v1/avatars/flags/:code')
->desc('Get Country Flag')
->groups(['api', 'avatars'])
->label('scope', 'avatars.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'avatars')
->label('sdk.method', 'getFlag')
->label('sdk.methodType', 'location')
@@ -143,7 +143,7 @@ App::get('/v1/avatars/image')
->desc('Get Image from URL')
->groups(['api', 'avatars'])
->label('scope', 'avatars.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'avatars')
->label('sdk.method', 'getImage')
->label('sdk.methodType', 'location')
@@ -212,7 +212,7 @@ App::get('/v1/avatars/favicon')
->desc('Get Favicon')
->groups(['api', 'avatars'])
->label('scope', 'avatars.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'avatars')
->label('sdk.method', 'getFavicon')
->label('sdk.methodType', 'location')
@@ -365,7 +365,7 @@ App::get('/v1/avatars/qr')
->desc('Get QR Code')
->groups(['api', 'avatars'])
->label('scope', 'avatars.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'avatars')
->label('sdk.method', 'getQR')
->label('sdk.methodType', 'location')
@@ -408,7 +408,7 @@ App::get('/v1/avatars/initials')
->desc('Get User Initials')
->groups(['api', 'avatars'])
->label('scope', 'avatars.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'avatars')
->label('sdk.method', 'getInitials')
->label('sdk.methodType', 'location')
+35 -31
View File
@@ -24,7 +24,7 @@ App::post('/v1/database/collections')
->label('event', 'database.collections.create')
->label('scope', 'collections.write')
->label('sdk.namespace', 'database')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.method', 'createCollection')
->label('sdk.description', '/docs/references/database/create-collection.md')
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
@@ -96,7 +96,7 @@ App::get('/v1/database/collections')
->groups(['api', 'database'])
->label('scope', 'collections.read')
->label('sdk.namespace', 'database')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.method', 'listCollections')
->label('sdk.description', '/docs/references/database/list-collections.md')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -133,7 +133,7 @@ App::get('/v1/database/collections/:collectionId')
->groups(['api', 'database'])
->label('scope', 'collections.read')
->label('sdk.namespace', 'database')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.method', 'getCollection')
->label('sdk.description', '/docs/references/database/get-collection.md')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -161,7 +161,7 @@ App::put('/v1/database/collections/:collectionId')
->label('scope', 'collections.write')
->label('event', 'database.collections.update')
->label('sdk.namespace', 'database')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.method', 'updateCollection')
->label('sdk.description', '/docs/references/database/update-collection.md')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -169,8 +169,8 @@ App::put('/v1/database/collections/:collectionId')
->label('sdk.response.model', Response::MODEL_COLLECTION)
->param('collectionId', '', new UID(), 'Collection unique ID.')
->param('name', null, new Text(128), 'Collection name. Max length: 128 chars.')
->param('read', [], new ArrayList(new Text(64)), 'An array of strings with read permissions. By default no user is granted with any read permissions. [learn more about permissions(/docs/permissions) and get a full list of available permissions.')
->param('write', [], new ArrayList(new Text(64)), 'An array of strings with write permissions. By default no user is granted with any write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
->param('read', null, new ArrayList(new Text(64)), 'An array of strings with read permissions. By default inherits the existing read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
->param('write', null, new ArrayList(new Text(64)), 'An array of strings with write permissions. By default inherits the existing write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
->param('rules', [], function ($projectDB) { return new ArrayList(new Collection($projectDB, [Database::SYSTEM_COLLECTION_RULES], ['$collection' => Database::SYSTEM_COLLECTION_RULES, '$permissions' => ['read' => [], 'write' => []]])); }, 'Array of [rule objects](/docs/rules). Each rule define a collection field name, data type and validation.', true, ['projectDB'])
->inject('response')
->inject('projectDB')
@@ -187,6 +187,8 @@ App::put('/v1/database/collections/:collectionId')
}
$parsedRules = [];
$read = (is_null($read)) ? ($collection->getPermissions()['read'] ?? []) : $read; // By default inherit read permissions
$write = (is_null($write)) ? ($collection->getPermissions()['write'] ?? []) : $write; // By default inherit write permissions
foreach ($rules as &$rule) {
$parsedRules[] = \array_merge([
@@ -236,7 +238,7 @@ App::delete('/v1/database/collections/:collectionId')
->label('scope', 'collections.write')
->label('event', 'database.collections.delete')
->label('sdk.namespace', 'database')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.method', 'deleteCollection')
->label('sdk.description', '/docs/references/database/delete-collection.md')
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
@@ -269,7 +271,7 @@ App::delete('/v1/database/collections/:collectionId')
;
$events
->setParam('payload', $response->output($collection, Response::MODEL_COLLECTION))
->setParam('eventData', $response->output($collection, Response::MODEL_COLLECTION))
;
$audits
@@ -287,25 +289,27 @@ App::post('/v1/database/collections/:collectionId/documents')
->label('event', 'database.documents.create')
->label('scope', 'documents.write')
->label('sdk.namespace', 'database')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.method', 'createDocument')
->label('sdk.description', '/docs/references/database/create-document.md')
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_ANY)
->label('sdk.response.model', Response::MODEL_DOCUMENT)
->param('collectionId', null, new UID(), 'Collection unique ID. You can create a new collection with validation rules using the Database service [server integration](/docs/server/database#createCollection).')
->param('data', [], new JSON(), 'Document data as JSON object.')
->param('read', [], new ArrayList(new Text(64)), 'An array of strings with read permissions. By default no user is granted with any read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
->param('write', [], new ArrayList(new Text(64)), 'An array of strings with write permissions. By default no user is granted with any write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
->param('read', null, new ArrayList(new Text(64)), 'An array of strings with read permissions. By default only the current user is granted with read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
->param('write', null, new ArrayList(new Text(64)), 'An array of strings with write permissions. By default only the current user is granted with write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
->param('parentDocument', '', new UID(), 'Parent document unique ID. Use when you want your new document to be a child of a parent document.', true)
->param('parentProperty', '', new Key(), 'Parent document property name. Use when you want your new document to be a child of a parent document.', true)
->param('parentPropertyType', Document::SET_TYPE_ASSIGN, new WhiteList([Document::SET_TYPE_ASSIGN, Document::SET_TYPE_APPEND, Document::SET_TYPE_PREPEND], true), 'Parent document property connection type. You can set this value to **assign**, **append** or **prepend**, default value is assign. Use when you want your new document to be a child of a parent document.', true)
->inject('response')
->inject('projectDB')
->inject('user')
->inject('audits')
->action(function ($collectionId, $data, $read, $write, $parentDocument, $parentProperty, $parentPropertyType, $response, $projectDB, $audits) {
->action(function ($collectionId, $data, $read, $write, $parentDocument, $parentProperty, $parentPropertyType, $response, $projectDB, $user, $audits) {
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Database $projectDB */
/** @var Appwrite\Database\Document $user */
/** @var Appwrite\Event\Event $audits */
$data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array
@@ -326,8 +330,8 @@ App::post('/v1/database/collections/:collectionId/documents')
$data['$collection'] = $collectionId; // Adding this param to make API easier for developers
$data['$permissions'] = [
'read' => $read,
'write' => $write,
'read' => (is_null($read) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $read ?? [], // By default set read permissions for user
'write' => (is_null($write) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $write ?? [], // By default set write permissions for user
];
// Read parent document + validate not 404 + validate read / write permission like patch method
@@ -397,7 +401,7 @@ App::post('/v1/database/collections/:collectionId/documents')
$response
->setStatusCode(Response::STATUS_CODE_CREATED)
->dynamic($data, Response::MODEL_ANY)
->dynamic($data, Response::MODEL_DOCUMENT)
;
});
@@ -406,7 +410,7 @@ App::get('/v1/database/collections/:collectionId/documents')
->groups(['api', 'database'])
->label('scope', 'documents.read')
->label('sdk.namespace', 'database')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.method', 'listDocuments')
->label('sdk.description', '/docs/references/database/list-documents.md')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -469,12 +473,12 @@ App::get('/v1/database/collections/:collectionId/documents/:documentId')
->groups(['api', 'database'])
->label('scope', 'documents.read')
->label('sdk.namespace', 'database')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.method', 'getDocument')
->label('sdk.description', '/docs/references/database/get-document.md')
->label('sdk.response.code', Response::STATUS_CODE_OK)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_ANY)
->label('sdk.response.model', Response::MODEL_DOCUMENT)
->param('collectionId', null, new UID(), 'Collection unique ID. You can create a new collection with validation rules using the Database service [server integration](/docs/server/database#createCollection).')
->param('documentId', null, new UID(), 'Document unique ID.')
->inject('response')
@@ -490,7 +494,7 @@ App::get('/v1/database/collections/:collectionId/documents/:documentId')
throw new Exception('No document found', 404);
}
$response->dynamic($document, Response::MODEL_ANY);
$response->dynamic($document, Response::MODEL_DOCUMENT);
});
App::patch('/v1/database/collections/:collectionId/documents/:documentId')
@@ -499,17 +503,17 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId')
->label('event', 'database.documents.update')
->label('scope', 'documents.write')
->label('sdk.namespace', 'database')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.method', 'updateDocument')
->label('sdk.description', '/docs/references/database/update-document.md')
->label('sdk.response.code', Response::STATUS_CODE_OK)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_ANY)
->label('sdk.response.model', Response::MODEL_DOCUMENT)
->param('collectionId', null, new UID(), 'Collection unique ID. You can create a new collection with validation rules using the Database service [server integration](/docs/server/database#createCollection).')
->param('documentId', null, new UID(), 'Document unique ID.')
->param('data', [], new JSON(), 'Document data as JSON object.')
->param('read', [], new ArrayList(new Text(64)), 'An array of strings with read permissions. By default no user is granted with any read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
->param('write', [], new ArrayList(new Text(64)), 'An array of strings with write permissions. By default no user is granted with any write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
->param('read', null, new ArrayList(new Text(64)), 'An array of strings with read permissions. By default inherits the existing read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
->param('write', null, new ArrayList(new Text(64)), 'An array of strings with write permissions. By default inherits the existing write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
->inject('response')
->inject('projectDB')
->inject('audits')
@@ -522,7 +526,7 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId')
$document = $projectDB->getDocument($documentId, false);
$data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array
if (!\is_array($data)) {
throw new Exception('Data param should be a valid JSON object', 400);
}
@@ -539,8 +543,8 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId')
$data['$collection'] = $collection->getId(); // Make sure user don't switch collectionID
$data['$id'] = $document->getId(); // Make sure user don't switch document unique ID
$data['$permissions']['read'] = $read;
$data['$permissions']['write'] = $write;
$data['$permissions']['read'] = (is_null($read)) ? ($document->getPermissions()['read'] ?? []) : $read; // By default inherit read permissions
$data['$permissions']['write'] = (is_null($write)) ? ($document->getPermissions()['write'] ?? []) : $write; // By default inherit write permissions
if (empty($data)) {
throw new Exception('Missing payload', 400);
@@ -562,7 +566,7 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId')
->setParam('data', $data->getArrayCopy())
;
$response->dynamic($data, Response::MODEL_ANY);
$response->dynamic($data, Response::MODEL_DOCUMENT);
});
App::delete('/v1/database/collections/:collectionId/documents/:documentId')
@@ -571,7 +575,7 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId')
->label('scope', 'documents.write')
->label('event', 'database.documents.delete')
->label('sdk.namespace', 'database')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.method', 'deleteDocument')
->label('sdk.description', '/docs/references/database/delete-document.md')
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
@@ -610,9 +614,9 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId')
}
$events
->setParam('payload', $response->output($document, Response::MODEL_ANY))
->setParam('eventData', $response->output($document, Response::MODEL_DOCUMENT))
;
$audits
->setParam('event', 'database.documents.delete')
->setParam('resource', 'database/document/'.$document->getId())
+62 -19
View File
@@ -1,5 +1,7 @@
<?php
use Ahc\Jwt\JWT;
use Appwrite\Auth\Auth;
use Appwrite\Database\Database;
use Appwrite\Database\Document;
use Appwrite\Database\Validator\Authorization;
@@ -27,7 +29,8 @@ App::post('/v1/functions')
->groups(['api', 'functions'])
->desc('Create Function')
->label('scope', 'functions.write')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('event', 'functions.create')
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'create')
->label('sdk.description', '/docs/references/functions/create-function.md')
@@ -36,7 +39,7 @@ 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('environments')), true), 'Execution enviornment.')
->param('env', '', new WhiteList(array_keys(Config::getParam('runtimes')), true), 'Execution enviornment.')
->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)
@@ -80,7 +83,7 @@ App::get('/v1/functions')
->groups(['api', 'functions'])
->desc('List Functions')
->label('scope', 'functions.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'list')
->label('sdk.description', '/docs/references/functions/list-functions.md')
@@ -117,7 +120,7 @@ App::get('/v1/functions/:functionId')
->groups(['api', 'functions'])
->desc('Get Function')
->label('scope', 'functions.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'get')
->label('sdk.description', '/docs/references/functions/get-function.md')
@@ -144,7 +147,7 @@ App::get('/v1/functions/:functionId/usage')
->desc('Get Function Usage')
->groups(['api', 'functions'])
->label('scope', 'functions.read')
->label('sdk.platform', [APP_PLATFORM_CONSOLE])
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'getUsage')
->param('functionId', '', new UID(), 'Function unique ID.')
@@ -265,7 +268,8 @@ App::put('/v1/functions/:functionId')
->groups(['api', 'functions'])
->desc('Update Function')
->label('scope', 'functions.write')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('event', 'functions.update')
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'update')
->label('sdk.description', '/docs/references/functions/update-function.md')
@@ -317,6 +321,7 @@ App::put('/v1/functions/:functionId')
if ($next && $schedule !== $original) {
ResqueScheduler::enqueueAt($next, 'v1-functions', 'FunctionsV1', [
'projectId' => $project->getId(),
'webhooks' => $project->getAttribute('webhooks', []),
'functionId' => $function->getId(),
'executionId' => null,
'trigger' => 'schedule',
@@ -330,7 +335,8 @@ App::patch('/v1/functions/:functionId/tag')
->groups(['api', 'functions'])
->desc('Update Function Tag')
->label('scope', 'functions.write')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('event', 'functions.tags.update')
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'updateTag')
->label('sdk.description', '/docs/references/functions/update-function-tag.md')
@@ -370,6 +376,7 @@ App::patch('/v1/functions/:functionId/tag')
if ($next) { // Init first schedule
ResqueScheduler::enqueueAt($next, 'v1-functions', 'FunctionsV1', [
'projectId' => $project->getId(),
'webhooks' => $project->getAttribute('webhooks', []),
'functionId' => $function->getId(),
'executionId' => null,
'trigger' => 'schedule',
@@ -387,7 +394,8 @@ App::delete('/v1/functions/:functionId')
->groups(['api', 'functions'])
->desc('Delete Function')
->label('scope', 'functions.write')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('event', 'functions.delete')
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'delete')
->label('sdk.description', '/docs/references/functions/delete-function.md')
@@ -424,7 +432,8 @@ App::post('/v1/functions/:functionId/tags')
->groups(['api', 'functions'])
->desc('Create Tag')
->label('scope', 'functions.write')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('event', 'functions.tags.create')
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'createTag')
->label('sdk.description', '/docs/references/functions/create-tag.md')
@@ -435,7 +444,7 @@ App::post('/v1/functions/:functionId/tags')
->label('sdk.response.model', Response::MODEL_TAG)
->param('functionId', '', new UID(), 'Function unique ID.')
->param('command', '', new Text('1028'), 'Code execution command.')
->param('code', null, new File(), 'Gzip file with your code package. When used with the Appwrite CLI, pass the path to your code directory, and the CLI will automatically package your code. Use a path that is within the current directory.', false)
->param('code', [], new File(), 'Gzip file with your code package. When used with the Appwrite CLI, pass the path to your code directory, and the CLI will automatically package your code. Use a path that is within the current directory.', false)
->inject('request')
->inject('response')
->inject('projectDB')
@@ -518,7 +527,7 @@ App::get('/v1/functions/:functionId/tags')
->groups(['api', 'functions'])
->desc('List Tags')
->label('scope', 'functions.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'listTags')
->label('sdk.description', '/docs/references/functions/list-tags.md')
@@ -563,7 +572,7 @@ App::get('/v1/functions/:functionId/tags/:tagId')
->groups(['api', 'functions'])
->desc('Get Tag')
->label('scope', 'functions.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'getTag')
->label('sdk.description', '/docs/references/functions/get-tag.md')
@@ -601,7 +610,8 @@ App::delete('/v1/functions/:functionId/tags/:tagId')
->groups(['api', 'functions'])
->desc('Delete Tag')
->label('scope', 'functions.write')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('event', 'functions.tags.delete')
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'deleteTag')
->label('sdk.description', '/docs/references/functions/delete-tag.md')
@@ -662,7 +672,8 @@ App::post('/v1/functions/:functionId/executions')
->groups(['api', 'functions'])
->desc('Create Execution')
->label('scope', 'execution.write')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('event', 'functions.executions.create')
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'createExecution')
->label('sdk.description', '/docs/references/functions/create-execution.md')
@@ -672,14 +683,17 @@ App::post('/v1/functions/:functionId/executions')
->label('abuse-limit', 60)
->label('abuse-time', 60)
->param('functionId', '', new UID(), 'Function unique ID.')
->param('data', '', new Text(8192), 'String of custom data to send to function.', true)
// ->param('async', 1, new Range(0, 1), 'Execute code asynchronously. Pass 1 for true, 0 for false. Default value is 1.', true)
->inject('response')
->inject('project')
->inject('projectDB')
->action(function ($functionId, /*$async,*/ $response, $project, $projectDB) {
->inject('user')
->action(function ($functionId, $data, /*$async,*/ $response, $project, $projectDB, $user) {
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */
/** @var Appwrite\Database\Database $projectDB */
/** @var Appwrite\Database\Document $user */
Authorization::disable();
@@ -712,7 +726,7 @@ App::post('/v1/functions/:functionId/executions')
$execution = $projectDB->createDocument([
'$collection' => Database::SYSTEM_COLLECTION_EXECUTIONS,
'$permissions' => [
'read' => $function->getPermissions()['execute'] ?? [],
'read' => (!empty($user->getId())) ? ['user:' . $user->getId()] : [],
'write' => [],
],
'dateCreated' => time(),
@@ -730,12 +744,37 @@ App::post('/v1/functions/:functionId/executions')
if (false === $execution) {
throw new Exception('Failed saving execution to DB', 500);
}
$jwt = ''; // initialize
if (!empty($user->getId())) { // If userId exists, generate a JWT for function
$tokens = $user->getAttribute('tokens', []);
$session = 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;
}
}
if(!$session->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(),
]);
}
}
Resque::enqueue('v1-functions', 'FunctionsV1', [
'projectId' => $project->getId(),
'webhooks' => $project->getAttribute('webhooks', []),
'functionId' => $function->getId(),
'executionId' => $execution->getId(),
'trigger' => 'http',
'data' => $data,
'userId' => $user->getId(),
'jwt' => $jwt,
]);
$response
@@ -748,7 +787,7 @@ App::get('/v1/functions/:functionId/executions')
->groups(['api', 'functions'])
->desc('List Executions')
->label('scope', 'execution.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'listExecutions')
->label('sdk.description', '/docs/references/functions/list-executions.md')
@@ -766,7 +805,9 @@ App::get('/v1/functions/:functionId/executions')
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Database $projectDB */
Authorization::disable();
$function = $projectDB->getDocument($functionId);
Authorization::reset();
if (empty($function->getId()) || Database::SYSTEM_COLLECTION_FUNCTIONS != $function->getCollection()) {
throw new Exception('Function not found', 404);
@@ -793,7 +834,7 @@ App::get('/v1/functions/:functionId/executions/:executionId')
->groups(['api', 'functions'])
->desc('Get Execution')
->label('scope', 'execution.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'getExecution')
->label('sdk.description', '/docs/references/functions/get-execution.md')
@@ -808,7 +849,9 @@ App::get('/v1/functions/:functionId/executions/:executionId')
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Database $projectDB */
Authorization::disable();
$function = $projectDB->getDocument($functionId);
Authorization::reset();
if (empty($function->getId()) || Database::SYSTEM_COLLECTION_FUNCTIONS != $function->getCollection()) {
throw new Exception('Function not found', 404);
+30 -20
View File
@@ -6,12 +6,13 @@ 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')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'health')
->label('sdk.method', 'get')
->label('sdk.description', '/docs/references/health/get.md')
@@ -37,7 +38,7 @@ App::get('/v1/health/db')
->desc('Get DB')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'health')
->label('sdk.method', 'getDB')
->label('sdk.description', '/docs/references/health/get-db.md')
@@ -56,7 +57,7 @@ App::get('/v1/health/cache')
->desc('Get Cache')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'health')
->label('sdk.method', 'getCache')
->label('sdk.description', '/docs/references/health/get-cache.md')
@@ -74,7 +75,7 @@ App::get('/v1/health/time')
->desc('Get Time')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'health')
->label('sdk.method', 'getTime')
->label('sdk.description', '/docs/references/health/get-time.md')
@@ -123,7 +124,7 @@ App::get('/v1/health/queue/webhooks')
->desc('Get Webhooks Queue')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'health')
->label('sdk.method', 'getQueueWebhooks')
->label('sdk.description', '/docs/references/health/get-queue-webhooks.md')
@@ -138,7 +139,7 @@ App::get('/v1/health/queue/tasks')
->desc('Get Tasks Queue')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'health')
->label('sdk.method', 'getQueueTasks')
->label('sdk.description', '/docs/references/health/get-queue-tasks.md')
@@ -153,7 +154,7 @@ App::get('/v1/health/queue/logs')
->desc('Get Logs Queue')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'health')
->label('sdk.method', 'getQueueLogs')
->label('sdk.description', '/docs/references/health/get-queue-logs.md')
@@ -168,7 +169,7 @@ App::get('/v1/health/queue/usage')
->desc('Get Usage Queue')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'health')
->label('sdk.method', 'getQueueUsage')
->label('sdk.description', '/docs/references/health/get-queue-usage.md')
@@ -183,7 +184,7 @@ App::get('/v1/health/queue/certificates')
->desc('Get Certificate Queue')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'health')
->label('sdk.method', 'getQueueCertificates')
->label('sdk.description', '/docs/references/health/get-queue-certificates.md')
@@ -198,7 +199,7 @@ App::get('/v1/health/queue/functions')
->desc('Get Functions Queue')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'health')
->label('sdk.method', 'getQueueFunctions')
->label('sdk.description', '/docs/references/health/get-queue-functions.md')
@@ -213,7 +214,7 @@ App::get('/v1/health/storage/local')
->desc('Get Local Storage')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'health')
->label('sdk.method', 'getStorageLocal')
->label('sdk.description', '/docs/references/health/get-storage-local.md')
@@ -245,7 +246,7 @@ App::get('/v1/health/anti-virus')
->desc('Get Anti virus')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'health')
->label('sdk.method', 'getAntiVirus')
->label('sdk.description', '/docs/references/health/get-storage-anti-virus.md')
@@ -254,23 +255,32 @@ App::get('/v1/health/anti-virus')
/** @var Appwrite\Utopia\Response $response */
if (App::getEnv('_APP_STORAGE_ANTIVIRUS') === 'disabled') { // Check if scans are enabled
throw new Exception('Anitvirus is disabled');
return $response->json([
'status' => 'disabled',
'version' => '',
]);
}
$antiVirus = new Network(App::getEnv('_APP_STORAGE_ANTIVIRUS_HOST', 'clamav'),
(int) App::getEnv('_APP_STORAGE_ANTIVIRUS_PORT', 3310));
$response->json([
'status' => (@$antiVirus->ping()) ? 'online' : 'offline',
'version' => @$antiVirus->version(),
]);
try {
$response->json([
'status' => (@$antiVirus->ping()) ? 'online' : 'offline',
'version' => @$antiVirus->version(),
]);
} catch( RuntimeException $e) {
$response->json([
'status' => 'offline',
'version' => '',
]);
}
});
App::get('/v1/health/stats') // Currently only used internally
->desc('Get System Stats')
->groups(['api', 'health'])
->label('scope', 'god')
// ->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('scope', 'root')
// ->label('sdk.auth', [APP_AUTH_TYPE_KEY])
// ->label('sdk.namespace', 'health')
// ->label('sdk.method', 'getStats')
->label('docs', false)
+7 -7
View File
@@ -9,7 +9,7 @@ App::get('/v1/locale')
->desc('Get User Locale')
->groups(['api', 'locale'])
->label('scope', 'locale.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'locale')
->label('sdk.method', 'get')
->label('sdk.description', '/docs/references/locale/get-locale.md')
@@ -74,7 +74,7 @@ App::get('/v1/locale/countries')
->desc('List Countries')
->groups(['api', 'locale'])
->label('scope', 'locale.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'locale')
->label('sdk.method', 'getCountries')
->label('sdk.description', '/docs/references/locale/get-countries.md')
@@ -106,7 +106,7 @@ App::get('/v1/locale/countries/eu')
->desc('List EU Countries')
->groups(['api', 'locale'])
->label('scope', 'locale.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'locale')
->label('sdk.method', 'getCountriesEU')
->label('sdk.description', '/docs/references/locale/get-countries-eu.md')
@@ -141,7 +141,7 @@ App::get('/v1/locale/countries/phones')
->desc('List Countries Phone Codes')
->groups(['api', 'locale'])
->label('scope', 'locale.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'locale')
->label('sdk.method', 'getCountriesPhones')
->label('sdk.description', '/docs/references/locale/get-countries-phones.md')
@@ -177,7 +177,7 @@ App::get('/v1/locale/continents')
->desc('List Continents')
->groups(['api', 'locale'])
->label('scope', 'locale.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'locale')
->label('sdk.method', 'getContinents')
->label('sdk.description', '/docs/references/locale/get-continents.md')
@@ -208,7 +208,7 @@ App::get('/v1/locale/currencies')
->desc('List Currencies')
->groups(['api', 'locale'])
->label('scope', 'locale.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'locale')
->label('sdk.method', 'getCurrencies')
->label('sdk.description', '/docs/references/locale/get-currencies.md')
@@ -233,7 +233,7 @@ App::get('/v1/locale/languages')
->desc('List Languages')
->groups(['api', 'locale'])
->label('scope', 'locale.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'locale')
->label('sdk.method', 'getLanguages')
->label('sdk.description', '/docs/references/locale/get-languages.md')
+108 -1
View File
@@ -6,8 +6,9 @@ use Utopia\Validator\ArrayList;
use Utopia\Validator\Boolean;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
use Utopia\Validator\URL;
use Appwrite\Network\Validator\URL;
use Utopia\Validator\Range;
use Utopia\Validator\Integer;
use Utopia\Config\Config;
use Utopia\Domains\Domain;
use Appwrite\Auth\Auth;
@@ -24,6 +25,7 @@ App::post('/v1/projects')
->desc('Create Project')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'create')
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
@@ -96,6 +98,7 @@ App::get('/v1/projects')
->desc('List Projects')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'list')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -131,6 +134,7 @@ App::get('/v1/projects/:projectId')
->desc('Get Project')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'get')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -156,6 +160,7 @@ App::get('/v1/projects/:projectId/usage')
->desc('Get Project')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'getUsage')
->param('projectId', '', new UID(), 'Project unique ID.')
@@ -356,6 +361,7 @@ App::patch('/v1/projects/:projectId')
->desc('Update Project')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'update')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -408,6 +414,7 @@ App::patch('/v1/projects/:projectId/oauth2')
->desc('Update Project OAuth2')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updateOAuth2')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -441,10 +448,85 @@ App::patch('/v1/projects/:projectId/oauth2')
$response->dynamic($project, Response::MODEL_PROJECT);
});
App::patch('/v1/projects/:projectId/auth/limit')
->desc('Update Project users limit')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updateAuthLimit')
->label('sdk.response.code', Response::STATUS_CODE_OK)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_PROJECT)
->param('projectId', '', new UID(), 'Project unique ID.')
->param('limit', false, new Integer(true), 'Set the max number of users allowed in this project. Use 0 for unlimited.')
->inject('response')
->inject('consoleDB')
->action(function ($projectId, $limit, $response, $consoleDB) {
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Database $consoleDB */
$project = $consoleDB->getDocument($projectId);
if (empty($project->getId()) || Database::SYSTEM_COLLECTION_PROJECTS != $project->getCollection()) {
throw new Exception('Project not found', 404);
}
if (false === $consoleDB->updateDocument(
\array_merge($project->getArrayCopy(), [
'usersAuthLimit' => $limit,
]))
) {
throw new Exception('Failed saving project to DB', 500);
};
$response->dynamic($project, Response::MODEL_PROJECT);
});
App::patch('/v1/projects/:projectId/auth/:method')
->desc('Update Project auth method status. Use this endpoint to enable or disable a given auth method for this project.')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updateAuthStatus')
->label('sdk.response.code', Response::STATUS_CODE_OK)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_PROJECT)
->param('projectId', '', new UID(), 'Project unique ID.')
->param('method', '', new WhiteList(\array_keys(Config::getParam('auth')), true), 'Auth Method. Possible values: '.implode(',', \array_keys(Config::getParam('auth'))), false)
->param('status', false, new Boolean(true), 'Set the status of this auth method.')
->inject('response')
->inject('consoleDB')
->action(function ($projectId, $method, $status, $response, $consoleDB) {
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Database $consoleDB */
$project = $consoleDB->getDocument($projectId);
$auth = Config::getParam('auth')[$method] ?? [];
$authKey = $auth['key'] ?? '';
$status = ($status === '1' || $status === 'true' || $status === 1 || $status === true);
if (empty($project->getId()) || Database::SYSTEM_COLLECTION_PROJECTS != $project->getCollection()) {
throw new Exception('Project not found', 404);
}
if (false === $consoleDB->updateDocument(
\array_merge($project->getArrayCopy(), [
$authKey => $status,
]))
) {
throw new Exception('Failed saving project to DB', 500);
};
$response->dynamic($project, Response::MODEL_PROJECT);
});
App::delete('/v1/projects/:projectId')
->desc('Delete Project')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'delete')
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
@@ -510,6 +592,7 @@ App::post('/v1/projects/:projectId/webhooks')
->desc('Create Webhook')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'createWebhook')
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
@@ -572,6 +655,7 @@ App::get('/v1/projects/:projectId/webhooks')
->desc('List Webhooks')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'listWebhooks')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -602,6 +686,7 @@ App::get('/v1/projects/:projectId/webhooks/:webhookId')
->desc('Get Webhook')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'getWebhook')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -634,6 +719,7 @@ App::put('/v1/projects/:projectId/webhooks/:webhookId')
->desc('Update Webhook')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updateWebhook')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -687,6 +773,7 @@ App::delete('/v1/projects/:projectId/webhooks/:webhookId')
->desc('Delete Webhook')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'deleteWebhook')
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
@@ -724,6 +811,7 @@ App::post('/v1/projects/:projectId/keys')
->desc('Create Key')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'createKey')
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
@@ -777,6 +865,7 @@ App::get('/v1/projects/:projectId/keys')
->desc('List Keys')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'listKeys')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -807,6 +896,7 @@ App::get('/v1/projects/:projectId/keys/:keyId')
->desc('Get Key')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'getKey')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -836,6 +926,7 @@ App::put('/v1/projects/:projectId/keys/:keyId')
->desc('Update Key')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updateKey')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -879,6 +970,7 @@ App::delete('/v1/projects/:projectId/keys/:keyId')
->desc('Delete Key')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'deleteKey')
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
@@ -916,6 +1008,7 @@ App::post('/v1/projects/:projectId/tasks')
->desc('Create Task')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'createTask')
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
@@ -996,6 +1089,7 @@ App::get('/v1/projects/:projectId/tasks')
->desc('List Tasks')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'listTasks')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -1027,6 +1121,7 @@ App::get('/v1/projects/:projectId/tasks/:taskId')
->desc('Get Task')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'getTask')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -1059,6 +1154,7 @@ App::put('/v1/projects/:projectId/tasks/:taskId')
->desc('Update Task')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updateTask')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -1127,6 +1223,7 @@ App::delete('/v1/projects/:projectId/tasks/:taskId')
->desc('Delete Task')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'deleteTask')
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
@@ -1164,6 +1261,7 @@ App::post('/v1/projects/:projectId/platforms')
->desc('Create Platform')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'createPlatform')
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
@@ -1224,6 +1322,7 @@ App::get('/v1/projects/:projectId/platforms')
->desc('List Platforms')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'listPlatforms')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -1254,6 +1353,7 @@ App::get('/v1/projects/:projectId/platforms/:platformId')
->desc('Get Platform')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'getPlatform')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -1286,6 +1386,7 @@ App::put('/v1/projects/:projectId/platforms/:platformId')
->desc('Update Platform')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updatePlatform')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -1334,6 +1435,7 @@ App::delete('/v1/projects/:projectId/platforms/:platformId')
->desc('Delete Platform')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'deletePlatform')
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
@@ -1371,6 +1473,7 @@ App::post('/v1/projects/:projectId/domains')
->desc('Create Domain')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'createDomain')
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
@@ -1440,6 +1543,7 @@ App::get('/v1/projects/:projectId/domains')
->desc('List Domains')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'listDomains')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -1470,6 +1574,7 @@ App::get('/v1/projects/:projectId/domains/:domainId')
->desc('Get Domain')
->groups(['api', 'projects'])
->label('scope', 'projects.read')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'getDomain')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -1502,6 +1607,7 @@ App::patch('/v1/projects/:projectId/domains/:domainId/verification')
->desc('Update Domain Verification Status')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'updateDomainVerification')
->label('sdk.response.code', Response::STATUS_CODE_OK)
@@ -1565,6 +1671,7 @@ App::delete('/v1/projects/:projectId/domains/:domainId')
->desc('Delete Domain')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'deleteDomain')
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
+45 -20
View File
@@ -22,13 +22,14 @@ 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')
->groups(['api', 'storage'])
->label('scope', 'files.write')
->label('event', 'storage.files.create')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'storage')
->label('sdk.method', 'createFile')
->label('sdk.description', '/docs/references/storage/create-file.md')
@@ -38,17 +39,19 @@ App::post('/v1/storage/files')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_FILE)
->param('file', [], new File(), 'Binary file.', false)
->param('read', [], new ArrayList(new Text(64)), 'An array of strings with read permissions. By default no user is granted with any read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
->param('write', [], new ArrayList(new Text(64)), 'An array of strings with write permissions. By default no user is granted with any write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
->param('read', null, new ArrayList(new Text(64)), 'An array of strings with read permissions. By default only the current user is granted with read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
->param('write', null, new ArrayList(new Text(64)), 'An array of strings with write permissions. By default only the current user is granted with write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
->inject('request')
->inject('response')
->inject('projectDB')
->inject('user')
->inject('audits')
->inject('usage')
->action(function ($file, $read, $write, $request, $response, $projectDB, $audits, $usage) {
->action(function ($file, $read, $write, $request, $response, $projectDB, $user, $audits, $usage) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Database $projectDB */
/** @var Appwrite\Database\Document $user */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Event\Event $usage */
@@ -113,7 +116,7 @@ App::post('/v1/storage/files')
$iv = OpenSSL::randomPseudoBytes(OpenSSL::cipherIVLength(OpenSSL::CIPHER_AES_128_GCM));
$data = OpenSSL::encrypt($data, OpenSSL::CIPHER_AES_128_GCM, $key, 0, $iv, $tag);
if (!$device->write($path, $data)) {
if (!$device->write($path, $data, $mimeType)) {
throw new Exception('Failed to save file', 500);
}
@@ -122,8 +125,8 @@ App::post('/v1/storage/files')
$file = $projectDB->createDocument([
'$collection' => Database::SYSTEM_COLLECTION_FILES,
'$permissions' => [
'read' => $read,
'write' => $write,
'read' => (is_null($read) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $read ?? [], // By default set read permissions for user
'write' => (is_null($write) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $write ?? [], // By default set write permissions for user
],
'dateCreated' => \time(),
'folderId' => '',
@@ -165,7 +168,7 @@ App::get('/v1/storage/files')
->desc('List Files')
->groups(['api', 'storage'])
->label('scope', 'files.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'storage')
->label('sdk.method', 'listFiles')
->label('sdk.description', '/docs/references/storage/list-files.md')
@@ -202,7 +205,7 @@ App::get('/v1/storage/files/:fileId')
->desc('Get File')
->groups(['api', 'storage'])
->label('scope', 'files.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'storage')
->label('sdk.method', 'getFile')
->label('sdk.description', '/docs/references/storage/get-file.md')
@@ -229,7 +232,7 @@ App::get('/v1/storage/files/:fileId/preview')
->desc('Get File Preview')
->groups(['api', 'storage'])
->label('scope', 'files.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'storage')
->label('sdk.method', 'getFilePreview')
->label('sdk.description', '/docs/references/storage/get-file-preview.md')
@@ -240,13 +243,18 @@ App::get('/v1/storage/files/:fileId/preview')
->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('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)
->param('borderRadius', 0, new Range(0, 4000), 'Preview image border radius in pixels. Pass an integer between 0 to 4000.', true)
->param('opacity', 1, new Range(0,1, Range::TYPE_FLOAT), 'Preview image opacity. Only works with images having an alpha channel (like png). Pass a number between 0 to 1.', true)
->param('rotation', 0, new Range(0,360), 'Preview image rotation in degrees. Pass an integer between 0 and 360.', true)
->param('background', '', new HexColor(), 'Preview image background color. Only works with transparent images (png). Use a valid HEX color, no # is needed for prefix.', true)
->param('output', '', new WhiteList(\array_keys(Config::getParam('storage-outputs')), true), 'Output format type (jpeg, jpg, png, gif and webp).', true)
->inject('request')
->inject('response')
->inject('project')
->inject('projectDB')
->action(function ($fileId, $width, $height, $quality, $background, $output, $request, $response, $project, $projectDB) {
->action(function ($fileId, $width, $height, $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 */
@@ -271,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.$background.$storage.$output);
$key = \md5($fileId.$width.$height.$quality.$borderWidth.$borderColor.$borderRadius.$opacity.$rotation.$background.$storage.$output);
$file = $projectDB->getDocument($fileId);
@@ -291,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.$background.$storage.$output);
$key = \md5($path.$width.$height.$quality.$borderWidth.$borderColor.$borderRadius.$opacity.$rotation.$background.$storage.$output);
}
$compressor = new GZIP();
@@ -335,11 +343,28 @@ App::get('/v1/storage/files/:fileId/preview')
$image = new Image($source);
$image->crop((int) $width, (int) $height);
if (!empty($opacity) || $opacity==0) {
$image->setOpacity($opacity);
}
if (!empty($background)) {
$image->setBackground('#'.$background);
}
if (!empty($borderWidth) ) {
$image->setBorder($borderWidth, '#'.$borderColor);
}
if (!empty($borderRadius)) {
$image->setBorderRadius($borderRadius);
}
if (!empty($rotation)) {
$image->setRotation($rotation);
}
$output = (empty($output)) ? $type : $output;
$data = $image->output($output, $quality);
@@ -360,7 +385,7 @@ App::get('/v1/storage/files/:fileId/download')
->desc('Get File for Download')
->groups(['api', 'storage'])
->label('scope', 'files.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'storage')
->label('sdk.method', 'getFileDownload')
->label('sdk.description', '/docs/references/storage/get-file-download.md')
@@ -418,7 +443,7 @@ App::get('/v1/storage/files/:fileId/view')
->desc('Get File for View')
->groups(['api', 'storage'])
->label('scope', 'files.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'storage')
->label('sdk.method', 'getFileView')
->label('sdk.description', '/docs/references/storage/get-file-view.md')
@@ -487,7 +512,7 @@ App::put('/v1/storage/files/:fileId')
->groups(['api', 'storage'])
->label('scope', 'files.write')
->label('event', 'storage.files.update')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'storage')
->label('sdk.method', 'updateFile')
->label('sdk.description', '/docs/references/storage/update-file.md')
@@ -536,7 +561,7 @@ App::delete('/v1/storage/files/:fileId')
->groups(['api', 'storage'])
->label('scope', 'files.write')
->label('event', 'storage.files.delete')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'storage')
->label('sdk.method', 'deleteFile')
->label('sdk.description', '/docs/references/storage/delete-file.md')
@@ -579,7 +604,7 @@ App::delete('/v1/storage/files/:fileId')
;
$events
->setParam('payload', $response->output($file, Response::MODEL_FILE))
->setParam('eventData', $response->output($file, Response::MODEL_FILE))
;
$response->noContent();
@@ -588,8 +613,8 @@ App::delete('/v1/storage/files/:fileId')
// App::get('/v1/storage/files/:fileId/scan')
// ->desc('Scan Storage')
// ->groups(['api', 'storage'])
// ->label('scope', 'god')
// ->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
// ->label('scope', 'root')
// ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
// ->label('sdk.namespace', 'storage')
// ->label('sdk.method', 'getFileScan')
// ->label('sdk.hide', true)
+131 -43
View File
@@ -3,9 +3,9 @@
use Utopia\App;
use Utopia\Exception;
use Utopia\Config\Config;
use Utopia\Validator\Email;
use Appwrite\Network\Validator\Email;
use Utopia\Validator\Text;
use Utopia\Validator\Host;
use Appwrite\Network\Validator\Host;
use Utopia\Validator\Range;
use Utopia\Validator\ArrayList;
use Utopia\Validator\WhiteList;
@@ -25,7 +25,7 @@ App::post('/v1/teams')
->groups(['api', 'teams'])
->label('event', 'teams.create')
->label('scope', 'teams.write')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'teams')
->label('sdk.method', 'create')
->label('sdk.description', '/docs/references/teams/create-team.md')
@@ -44,7 +44,7 @@ App::post('/v1/teams')
Authorization::disable();
$isPreviliggedUser = Auth::isPreviliggedUser(Authorization::$roles);
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles);
$isAppUser = Auth::isAppUser(Authorization::$roles);
$team = $projectDB->createDocument([
@@ -54,7 +54,7 @@ App::post('/v1/teams')
'write' => ['team:{self}/owner'],
],
'name' => $name,
'sum' => ($isPreviliggedUser || $isAppUser) ? 0 : 1,
'sum' => ($isPrivilegedUser || $isAppUser) ? 0 : 1,
'dateCreated' => \time(),
]);
@@ -64,7 +64,7 @@ App::post('/v1/teams')
throw new Exception('Failed saving team to DB', 500);
}
if (!$isPreviliggedUser && !$isAppUser) { // Don't add user on server mode
if (!$isPrivilegedUser && !$isAppUser) { // Don't add user on server mode
$membership = new Document([
'$collection' => Database::SYSTEM_COLLECTION_MEMBERSHIPS,
'$permissions' => [
@@ -100,7 +100,7 @@ App::get('/v1/teams')
->desc('List Teams')
->groups(['api', 'teams'])
->label('scope', 'teams.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'teams')
->label('sdk.method', 'list')
->label('sdk.description', '/docs/references/teams/list-teams.md')
@@ -137,7 +137,7 @@ App::get('/v1/teams/:teamId')
->desc('Get Team')
->groups(['api', 'teams'])
->label('scope', 'teams.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'teams')
->label('sdk.method', 'get')
->label('sdk.description', '/docs/references/teams/get-team.md')
@@ -165,7 +165,7 @@ App::put('/v1/teams/:teamId')
->groups(['api', 'teams'])
->label('event', 'teams.update')
->label('scope', 'teams.write')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'teams')
->label('sdk.method', 'update')
->label('sdk.description', '/docs/references/teams/update-team.md')
@@ -202,7 +202,7 @@ App::delete('/v1/teams/:teamId')
->groups(['api', 'teams'])
->label('event', 'teams.delete')
->label('scope', 'teams.write')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'teams')
->label('sdk.method', 'delete')
->label('sdk.description', '/docs/references/teams/delete-team.md')
@@ -243,7 +243,7 @@ App::delete('/v1/teams/:teamId')
}
$events
->setParam('payload', $response->output($team, Response::MODEL_TEAM))
->setParam('eventData', $response->output($team, Response::MODEL_TEAM))
;
$response->noContent();
@@ -251,16 +251,18 @@ App::delete('/v1/teams/:teamId')
App::post('/v1/teams/:teamId/memberships')
->desc('Create Team Membership')
->groups(['api', 'teams'])
->groups(['api', 'teams', 'auth'])
->label('event', 'teams.memberships.create')
->label('scope', 'teams.write')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('auth.type', 'invites')
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'teams')
->label('sdk.method', 'createMembership')
->label('sdk.description', '/docs/references/teams/create-team-membership.md')
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_MEMBERSHIP)
->label('abuse-limit', 10)
->param('teamId', '', new UID(), 'Team unique ID.')
->param('email', '', new Email(), 'New team member email.')
->param('name', '', new Text(128), 'New team member name. Max length: 128 chars.', true)
@@ -281,7 +283,7 @@ App::post('/v1/teams/:teamId/memberships')
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Event\Event $mails */
$isPreviliggedUser = Auth::isPreviliggedUser(Authorization::$roles);
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles);
$isAppUser = Auth::isAppUser(Authorization::$roles);
$name = (empty($name)) ? $email : $name;
@@ -292,7 +294,7 @@ App::post('/v1/teams/:teamId/memberships')
}
$memberships = $projectDB->getCollection([
'limit' => 50,
'limit' => 2000,
'offset' => 0,
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_MEMBERSHIPS,
@@ -310,6 +312,22 @@ App::post('/v1/teams/:teamId/memberships')
if (empty($invitee)) { // Create new user if no user with same email found
$limit = $project->getAttribute('usersAuthLimit', 0);
if ($limit !== 0 && $project->getId() !== 'console') { // check users limit, console invites are allways allowed.
$projectDB->getCollection([ // Count users
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_USERS,
],
]);
$sum = $projectDB->getSum();
if($sum >= $limit) {
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501);
}
}
Authorization::disable();
try {
@@ -323,10 +341,16 @@ App::post('/v1/teams/:teamId/memberships')
'emailVerification' => false,
'status' => Auth::USER_STATUS_UNACTIVATED,
'password' => Auth::passwordHash(Auth::passwordGenerator()),
'passwordUpdate' => \time(),
/**
* Set the password update time to 0 for users created using
* team invite and OAuth to allow password updates without an
* old password
*/
'passwordUpdate' => 0,
'registration' => \time(),
'reset' => false,
'name' => $name,
'sessions' => [],
'tokens' => [],
], ['email' => $email]);
} catch (Duplicate $th) {
@@ -352,7 +376,7 @@ App::post('/v1/teams/:teamId/memberships')
}
}
if (!$isOwner && !$isPreviliggedUser && !$isAppUser) { // Not owner, not admin, not app (server)
if (!$isOwner && !$isPrivilegedUser && !$isAppUser) { // Not owner, not admin, not app (server)
throw new Exception('User is not allowed to send invitations for this team', 401);
}
@@ -368,12 +392,12 @@ App::post('/v1/teams/:teamId/memberships')
'teamId' => $team->getId(),
'roles' => $roles,
'invited' => \time(),
'joined' => ($isPreviliggedUser || $isAppUser) ? \time() : 0,
'confirm' => ($isPreviliggedUser || $isAppUser),
'joined' => ($isPrivilegedUser || $isAppUser) ? \time() : 0,
'confirm' => ($isPrivilegedUser || $isAppUser),
'secret' => Auth::hash($secret),
]);
if ($isPreviliggedUser || $isAppUser) { // Allow admin to create membership
if ($isPrivilegedUser || $isAppUser) { // Allow admin to create membership
Authorization::disable();
$membership = $projectDB->createDocument($membership->getArrayCopy());
@@ -400,7 +424,7 @@ App::post('/v1/teams/:teamId/memberships')
}
$url = Template::parseURL($url);
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['inviteId' => $membership->getId(), 'teamId' => $team->getId(), 'userId' => $invitee->getId(), 'secret' => $secret, 'teamId' => $teamId]);
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['membershipId' => $membership->getId(), 'teamId' => $team->getId(), 'userId' => $invitee->getId(), 'secret' => $secret, 'teamId' => $teamId]);
$url = Template::unParseURL($url);
$body = new Template(__DIR__.'/../../config/locale/templates/email-base.tpl');
@@ -425,9 +449,9 @@ App::post('/v1/teams/:teamId/memberships')
->setParam('{{text-cta}}', '#ffffff')
;
if (!$isPreviliggedUser && !$isAppUser) { // No need in comfirmation when in admin or app mode
if (!$isPrivilegedUser && !$isAppUser) { // No need of confirmation when in admin or app mode
$mails
->setParam('event', 'teams.membership.create')
->setParam('event', 'teams.memberships.create')
->setParam('from', ($project->getId() === 'console') ? '' : \sprintf($locale->getText('account.emails.team'), $project->getAttribute('name')))
->setParam('recipient', $email)
->setParam('name', $name)
@@ -439,7 +463,7 @@ App::post('/v1/teams/:teamId/memberships')
$audits
->setParam('userId', $invitee->getId())
->setParam('event', 'teams.membership.create')
->setParam('event', 'teams.memberships.create')
->setParam('resource', 'teams/'.$teamId)
;
@@ -452,11 +476,74 @@ App::post('/v1/teams/:teamId/memberships')
;
});
App::patch('/v1/teams/:teamId/memberships/:membershipId')
->desc('Update Membership Roles')
->groups(['api', 'teams'])
->label('event', 'teams.memberships.update')
->label('scope', 'teams.write')
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'teams')
->label('sdk.method', 'updateMembershipRoles')
->label('sdk.description', '/docs/references/teams/update-team-membership-roles.md')
->label('sdk.response.code', Response::STATUS_CODE_OK)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_MEMBERSHIP)
->param('teamId', '', new UID(), 'Team unique ID.')
->param('membershipId', '', new UID(), 'Membership ID.')
->param('roles', [], new ArrayList(new Key()), 'Array of strings. Use this param to set the user roles in the team. A role can be any string. Learn more about [roles and permissions](/docs/permissions). Max length for each role is 32 chars.')
->inject('request')
->inject('response')
->inject('user')
->inject('projectDB')
->inject('audits')
->action(function ($teamId, $membershipId, $roles, $request, $response, $user, $projectDB,$audits) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $user */
/** @var Appwrite\Database\Database $projectDB */
/** @var Appwrite\Event\Event $audits */
$team = $projectDB->getDocument($teamId);
if (empty($team->getId()) || Database::SYSTEM_COLLECTION_TEAMS != $team->getCollection()) {
throw new Exception('Team not found', 404);
}
$membership = $projectDB->getDocument($membershipId);
if (empty($membership->getId()) || Database::SYSTEM_COLLECTION_MEMBERSHIPS != $membership->getCollection()) {
throw new Exception('Membership not found', 404);
}
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles);
$isAppUser = Auth::isAppUser(Authorization::$roles);
$isOwner = Authorization::isRole('team:'.$team->getId().'/owner');;
if (!$isOwner && !$isPrivilegedUser && !$isAppUser) { // Not owner, not admin, not app (server)
throw new Exception('User is not allowed to modify roles', 401);
}
// Update the roles
$membership->setAttribute('roles', $roles);
$membership = $projectDB->updateDocument($membership->getArrayCopy());
if (false === $membership) {
throw new Exception('Failed updating membership', 500);
}
$audits
->setParam('userId', $user->getId())
->setParam('event', 'teams.memberships.update')
->setParam('resource', 'teams/'.$teamId)
;
$response->dynamic(new Document($membership->getArrayCopy()), Response::MODEL_MEMBERSHIP);
});
App::get('/v1/teams/:teamId/memberships')
->desc('Get Team Memberships')
->groups(['api', 'teams'])
->label('scope', 'teams.read')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'teams')
->label('sdk.method', 'getMemberships')
->label('sdk.description', '/docs/references/teams/get-team-members.md')
@@ -505,12 +592,12 @@ App::get('/v1/teams/:teamId/memberships')
$response->dynamic(new Document(['sum' => $projectDB->getSum(), 'memberships' => $users]), Response::MODEL_MEMBERSHIP_LIST);
});
App::patch('/v1/teams/:teamId/memberships/:inviteId/status')
App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
->desc('Update Team Membership Status')
->groups(['api', 'teams'])
->label('event', 'teams.memberships.update.status')
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'teams')
->label('sdk.method', 'updateMembershipStatus')
->label('sdk.description', '/docs/references/teams/update-team-membership-status.md')
@@ -518,7 +605,7 @@ App::patch('/v1/teams/:teamId/memberships/:inviteId/status')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_MEMBERSHIP)
->param('teamId', '', new UID(), 'Team unique ID.')
->param('inviteId', '', new UID(), 'Invite unique ID.')
->param('membershipId', '', new UID(), 'Membership ID.')
->param('userId', '', new UID(), 'User unique ID.')
->param('secret', '', new Text(256), 'Secret key.')
->inject('request')
@@ -527,7 +614,7 @@ App::patch('/v1/teams/:teamId/memberships/:inviteId/status')
->inject('projectDB')
->inject('geodb')
->inject('audits')
->action(function ($teamId, $inviteId, $userId, $secret, $request, $response, $user, $projectDB, $geodb, $audits) {
->action(function ($teamId, $membershipId, $userId, $secret, $request, $response, $user, $projectDB, $geodb, $audits) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $user */
@@ -536,7 +623,7 @@ App::patch('/v1/teams/:teamId/memberships/:inviteId/status')
/** @var Appwrite\Event\Event $audits */
$protocol = $request->getProtocol();
$membership = $projectDB->getDocument($inviteId);
$membership = $projectDB->getDocument($membershipId);
if (empty($membership->getId()) || Database::SYSTEM_COLLECTION_MEMBERSHIPS != $membership->getCollection()) {
throw new Exception('Invite not found', 404);
@@ -561,7 +648,7 @@ App::patch('/v1/teams/:teamId/memberships/:inviteId/status')
}
if ($userId != $membership->getAttribute('userId')) {
throw new Exception('Invite not belong to current user ('.$user->getAttribute('email').')', 401);
throw new Exception('Invite does not belong to current user ('.$user->getAttribute('email').')', 401);
}
if (empty($user->getId())) {
@@ -575,7 +662,7 @@ App::patch('/v1/teams/:teamId/memberships/:inviteId/status')
}
if ($membership->getAttribute('userId') !== $user->getId()) {
throw new Exception('Invite not belong to current user ('.$user->getAttribute('email').')', 401);
throw new Exception('Invite does not belong to current user ('.$user->getAttribute('email').')', 401);
}
$membership // Attach user to team
@@ -595,10 +682,11 @@ App::patch('/v1/teams/:teamId/memberships/:inviteId/status')
$expiry = \time() + Auth::TOKEN_EXPIRATION_LOGIN_LONG;
$secret = Auth::tokenGenerator();
$session = new Document(array_merge([
'$collection' => Database::SYSTEM_COLLECTION_TOKENS,
'$collection' => Database::SYSTEM_COLLECTION_SESSIONS,
'$permissions' => ['read' => ['user:'.$user->getId()], 'write' => ['user:'.$user->getId()]],
'userId' => $user->getId(),
'type' => Auth::TOKEN_TYPE_LOGIN,
'provider' => Auth::SESSION_PROVIDER_EMAIL,
'providerUid' => $user->getAttribute('email'),
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
'expire' => $expiry,
'userAgent' => $request->getUserAgent('UNKNOWN'),
@@ -606,7 +694,7 @@ App::patch('/v1/teams/:teamId/memberships/:inviteId/status')
'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--',
], $detector->getOS(), $detector->getClient(), $detector->getDevice()));
$user->setAttribute('tokens', $session, Document::SET_TYPE_APPEND);
$user->setAttribute('sessions', $session, Document::SET_TYPE_APPEND);
Authorization::setRole('user:'.$userId);
@@ -630,7 +718,7 @@ App::patch('/v1/teams/:teamId/memberships/:inviteId/status')
$audits
->setParam('userId', $user->getId())
->setParam('event', 'teams.membership.update')
->setParam('event', 'teams.memberships.update.status')
->setParam('resource', 'teams/'.$teamId)
;
@@ -651,30 +739,30 @@ App::patch('/v1/teams/:teamId/memberships/:inviteId/status')
])), Response::MODEL_MEMBERSHIP);
});
App::delete('/v1/teams/:teamId/memberships/:inviteId')
App::delete('/v1/teams/:teamId/memberships/:membershipId')
->desc('Delete Team Membership')
->groups(['api', 'teams'])
->label('event', 'teams.memberships.delete')
->label('scope', 'teams.write')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'teams')
->label('sdk.method', 'deleteMembership')
->label('sdk.description', '/docs/references/teams/delete-team-membership.md')
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
->label('sdk.response.model', Response::MODEL_NONE)
->param('teamId', '', new UID(), 'Team unique ID.')
->param('inviteId', '', new UID(), 'Invite unique ID.')
->param('membershipId', '', new UID(), 'Membership ID.')
->inject('response')
->inject('projectDB')
->inject('audits')
->inject('events')
->action(function ($teamId, $inviteId, $response, $projectDB, $audits, $events) {
->action(function ($teamId, $membershipId, $response, $projectDB, $audits, $events) {
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Database $projectDB */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Event\Event $events */
$membership = $projectDB->getDocument($inviteId);
$membership = $projectDB->getDocument($membershipId);
if (empty($membership->getId()) || Database::SYSTEM_COLLECTION_MEMBERSHIPS != $membership->getCollection()) {
throw new Exception('Invite not found', 404);
@@ -706,12 +794,12 @@ App::delete('/v1/teams/:teamId/memberships/:inviteId')
$audits
->setParam('userId', $membership->getAttribute('userId'))
->setParam('event', 'teams.membership.delete')
->setParam('event', 'teams.memberships.delete')
->setParam('resource', 'teams/'.$teamId)
;
$events
->setParam('payload', $response->output($membership, Response::MODEL_MEMBERSHIP))
->setParam('eventData', $response->output($membership, Response::MODEL_MEMBERSHIP))
;
$response->noContent();
+41 -39
View File
@@ -2,9 +2,10 @@
use Utopia\App;
use Utopia\Exception;
use Utopia\Validator;
use Utopia\Validator\Assoc;
use Utopia\Validator\WhiteList;
use Utopia\Validator\Email;
use Appwrite\Network\Validator\Email;
use Utopia\Validator\Text;
use Utopia\Validator\Range;
use Utopia\Audit\Audit;
@@ -23,7 +24,7 @@ App::post('/v1/users')
->groups(['api', 'users'])
->label('event', 'users.create')
->label('scope', 'users.write')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'users')
->label('sdk.method', 'create')
->label('sdk.description', '/docs/references/users/create-user.md')
@@ -81,7 +82,7 @@ App::get('/v1/users')
->desc('List Users')
->groups(['api', 'users'])
->label('scope', 'users.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'users')
->label('sdk.method', 'list')
->label('sdk.description', '/docs/references/users/list-users.md')
@@ -118,7 +119,7 @@ App::get('/v1/users/:userId')
->desc('Get User')
->groups(['api', 'users'])
->label('scope', 'users.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'users')
->label('sdk.method', 'get')
->label('sdk.description', '/docs/references/users/get-user.md')
@@ -145,13 +146,13 @@ App::get('/v1/users/:userId/prefs')
->desc('Get User Preferences')
->groups(['api', 'users'])
->label('scope', 'users.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'users')
->label('sdk.method', 'getPrefs')
->label('sdk.description', '/docs/references/users/get-user-prefs.md')
->label('sdk.response.code', Response::STATUS_CODE_OK)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_ANY)
->label('sdk.response.model', Response::MODEL_PREFERENCES)
->param('userId', '', new UID(), 'User unique ID.')
->inject('response')
->inject('projectDB')
@@ -167,14 +168,14 @@ App::get('/v1/users/:userId/prefs')
$prefs = $user->getAttribute('prefs', new \stdClass());
$response->dynamic(new Document($prefs), Response::MODEL_ANY);
$response->dynamic(new Document($prefs), Response::MODEL_PREFERENCES);
});
App::get('/v1/users/:userId/sessions')
->desc('Get User Sessions')
->groups(['api', 'users'])
->label('scope', 'users.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'users')
->label('sdk.method', 'getSessions')
->label('sdk.description', '/docs/references/users/get-user-sessions.md')
@@ -196,21 +197,18 @@ App::get('/v1/users/:userId/sessions')
throw new Exception('User not found', 404);
}
$tokens = $user->getAttribute('tokens', []);
$sessions = [];
$sessions = $user->getAttribute('sessions', []);
$countries = $locale->getText('countries');
foreach ($tokens as $token) { /* @var $token Document */
if (Auth::TOKEN_TYPE_LOGIN != $token->getAttribute('type')) {
continue;
}
foreach ($sessions as $key => $session) {
/** @var Document $session */
$token->setAttribute('countryName', (isset($countries[strtoupper($token->getAttribute('countryCode'))]))
? $countries[strtoupper($token->getAttribute('countryCode'))]
$session->setAttribute('countryName', (isset($countries[strtoupper($session->getAttribute('countryCode'))]))
? $countries[strtoupper($session->getAttribute('countryCode'))]
: $locale->getText('locale.country.unknown'));
$token->setAttribute('current', false);
$session->setAttribute('current', false);
$sessions[] = $token;
$sessions[$key] = $session;
}
$response->dynamic(new Document([
@@ -223,7 +221,7 @@ App::get('/v1/users/:userId/logs')
->desc('Get User Logs')
->groups(['api', 'users'])
->label('scope', 'users.read')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'users')
->label('sdk.method', 'getLogs')
->label('sdk.description', '/docs/references/users/get-user-logs.md')
@@ -338,7 +336,7 @@ App::patch('/v1/users/:userId/status')
->groups(['api', 'users'])
->label('event', 'users.update.status')
->label('scope', 'users.write')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'users')
->label('sdk.method', 'updateStatus')
->label('sdk.description', '/docs/references/users/update-user-status.md')
@@ -346,7 +344,7 @@ App::patch('/v1/users/:userId/status')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_USER)
->param('userId', '', new UID(), 'User unique ID.')
->param('status', '', new WhiteList([Auth::USER_STATUS_ACTIVATED, Auth::USER_STATUS_BLOCKED, Auth::USER_STATUS_UNACTIVATED], true), 'User Status code. To activate the user pass '.Auth::USER_STATUS_ACTIVATED.', to block the user pass '.Auth::USER_STATUS_BLOCKED.' and for disabling the user pass '.Auth::USER_STATUS_UNACTIVATED)
->param('status', '', new WhiteList([Auth::USER_STATUS_ACTIVATED, Auth::USER_STATUS_BLOCKED, Auth::USER_STATUS_UNACTIVATED], true, Validator::TYPE_INTEGER), 'User Status code. To activate the user pass '.Auth::USER_STATUS_ACTIVATED.', to block the user pass '.Auth::USER_STATUS_BLOCKED.' and for disabling the user pass '.Auth::USER_STATUS_UNACTIVATED)
->inject('response')
->inject('projectDB')
->action(function ($userId, $status, $response, $projectDB) {
@@ -375,13 +373,13 @@ App::patch('/v1/users/:userId/prefs')
->groups(['api', 'users'])
->label('event', 'users.update.prefs')
->label('scope', 'users.write')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'users')
->label('sdk.method', 'updatePrefs')
->label('sdk.description', '/docs/references/users/update-user-prefs.md')
->label('sdk.response.code', Response::STATUS_CODE_OK)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_ANY)
->label('sdk.response.model', Response::MODEL_PREFERENCES)
->param('userId', '', new UID(), 'User unique ID.')
->param('prefs', '', new Assoc(), 'Prefs key-value JSON object.')
->inject('response')
@@ -404,7 +402,7 @@ App::patch('/v1/users/:userId/prefs')
throw new Exception('Failed saving user to DB', 500);
}
$response->dynamic(new Document($prefs), Response::MODEL_ANY);
$response->dynamic(new Document($prefs), Response::MODEL_PREFERENCES);
});
App::delete('/v1/users/:userId/sessions/:sessionId')
@@ -412,7 +410,7 @@ App::delete('/v1/users/:userId/sessions/:sessionId')
->groups(['api', 'users'])
->label('event', 'users.sessions.delete')
->label('scope', 'users.write')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'users')
->label('sdk.method', 'deleteSession')
->label('sdk.description', '/docs/references/users/delete-user-session.md')
@@ -434,16 +432,18 @@ App::delete('/v1/users/:userId/sessions/:sessionId')
throw new Exception('User not found', 404);
}
$tokens = $user->getAttribute('tokens', []);
$sessions = $user->getAttribute('sessions', []);
foreach ($tokens as $token) { /* @var $token Document */
if ($sessionId == $token->getId()) {
if (!$projectDB->deleteDocument($token->getId())) {
foreach ($sessions as $session) {
/** @var Document $session */
if ($sessionId == $session->getId()) {
if (!$projectDB->deleteDocument($session->getId())) {
throw new Exception('Failed to remove token from DB', 500);
}
$events
->setParam('payload', $response->output($user, Response::MODEL_USER))
->setParam('eventData', $response->output($user, Response::MODEL_USER))
;
}
}
@@ -457,7 +457,7 @@ App::delete('/v1/users/:userId/sessions')
->groups(['api', 'users'])
->label('event', 'users.sessions.delete')
->label('scope', 'users.write')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'users')
->label('sdk.method', 'deleteSessions')
->label('sdk.description', '/docs/references/users/delete-user-sessions.md')
@@ -478,16 +478,18 @@ App::delete('/v1/users/:userId/sessions')
throw new Exception('User not found', 404);
}
$tokens = $user->getAttribute('tokens', []);
$sessions = $user->getAttribute('sessions', []);
foreach ($tokens as $token) { /* @var $token Document */
if (!$projectDB->deleteDocument($token->getId())) {
foreach ($sessions as $session) {
/** @var Document $session */
if (!$projectDB->deleteDocument($session->getId())) {
throw new Exception('Failed to remove token from DB', 500);
}
}
$events
->setParam('payload', $response->output($user, Response::MODEL_USER))
->setParam('eventData', $response->output($user, Response::MODEL_USER))
;
// TODO : Response filter implementation
@@ -499,10 +501,10 @@ App::delete('/v1/users/:userId')
->groups(['api', 'users'])
->label('event', 'users.delete')
->label('scope', 'users.write')
->label('sdk.platform', [APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'users')
->label('sdk.method', 'deleteUser')
->label('sdk.description', '/docs/references/users/delete-user.md')
->label('sdk.method', 'delete')
->label('sdk.description', '/docs/references/users/delete.md')
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
->label('sdk.response.model', Response::MODEL_NONE)
->param('userId', '', function () {return new UID();}, 'User unique ID.')
@@ -547,7 +549,7 @@ App::delete('/v1/users/:userId')
;
$events
->setParam('payload', $response->output($user, Response::MODEL_USER))
->setParam('eventData', $response->output($user, Response::MODEL_USER))
;
// TODO : Response filter implementation
+59 -8
View File
@@ -14,24 +14,69 @@ use Appwrite\Database\Database;
use Appwrite\Database\Document;
use Appwrite\Database\Validator\Authorization;
use Appwrite\Network\Validator\Origin;
use Utopia\Storage\Device\Local;
use Utopia\Storage\Storage;
use Appwrite\Utopia\Response\Filters\V06;
use Appwrite\Utopia\Response\Filters\V07;
use Utopia\CLI\Console;
Config::setParam('domainVerification', false);
Config::setParam('cookieDomain', 'localhost');
Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE);
App::init(function ($utopia, $request, $response, $console, $project, $user, $locale, $clients) {
App::init(function ($utopia, $request, $response, $console, $project, $consoleDB, $user, $locale, $clients) {
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Database $consoleDB */
/** @var Appwrite\Database\Document $console */
/** @var Appwrite\Database\Document $project */
/** @var Appwrite\Database\Document $user */
/** @var Utopia\Locale\Locale $locale */
/** @var bool $mode */
/** @var array $clients */
$domain = $request->getHostname();
$domains = Config::getParam('domains', []);
if (!array_key_exists($domain, $domains)) {
$domain = new Domain(!empty($domain) ? $domain : '');
if (empty($domain->get()) || !$domain->isKnown() || $domain->isTest()) {
$domains[$domain->get()] = false;
Console::warning($domain->get() . ' is not a publicly accessible domain. Skipping SSL certificate generation.');
} else {
Authorization::disable();
$dbDomain = $consoleDB->getCollectionFirst([
'limit' => 1,
'offset' => 0,
'filters' => [
'$collection=' . Database::SYSTEM_COLLECTION_CERTIFICATES,
'domain=' . $domain->get(),
],
]);
if (empty($dbDomain)) {
$dbDomain = [
'$collection' => Database::SYSTEM_COLLECTION_CERTIFICATES,
'$permissions' => [
'read' => [],
'write' => [],
],
'domain' => $domain->get(),
];
$dbDomain = $consoleDB->createDocument($dbDomain);
Authorization::enable();
Console::info('Issuing a TLS certificate for the master domain (' . $domain->get() . ') in a few seconds...'); // TODO move this to installation script
Resque::enqueue('v1-certificates', 'CertificatesV1', [
'document' => $dbDomain,
'domain' => $domain->get(),
'validateTarget' => false,
'validateCNAME' => false,
]);
}
$domains[$domain->get()] = true;
}
Config::setParam('domains', $domains);
}
$localeParam = (string)$request->getParam('locale', $request->getHeader('x-appwrite-locale', ''));
@@ -41,7 +86,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $user, $lo
$route = $utopia->match($request);
if (!empty($route->getLabel('sdk.platform', [])) && empty($project->getId()) && ($route->getLabel('scope', '') !== 'public')) {
if (!empty($route->getLabel('sdk.auth', [])) && empty($project->getId()) && ($route->getLabel('scope', '') !== 'public')) {
throw new Exception('Missing or unknown project ID', 400);
}
@@ -92,6 +137,9 @@ App::init(function ($utopia, $request, $response, $console, $project, $user, $lo
case version_compare ($responseFormat , '0.6.2', '<=') :
Response::setFilter(new V06());
break;
case version_compare ($responseFormat , '0.7.2', '<=') :
Response::setFilter(new V07());
break;
default:
Response::setFilter(null);
}
@@ -208,7 +256,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $user, $lo
}
}, $user->getAttribute('memberships', []));
// TDOO Check if user is god
// TDOO Check if user is root
if (!\in_array($scope, $scopes)) {
if (empty($project->getId()) || Database::SYSTEM_COLLECTION_PROJECTS !== $project->getCollection()) { // Check if permission is denied because project is missing
@@ -226,7 +274,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $user, $lo
throw new Exception('Password reset is required', 412);
}
}, ['utopia', 'request', 'response', 'console', 'project', 'user', 'locale', 'clients']);
}, ['utopia', 'request', 'response', 'console', 'project', 'consoleDB', 'user', 'locale', 'clients']);
App::options(function ($request, $response) {
/** @var Utopia\Swoole\Request $request */
@@ -256,6 +304,8 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) {
$template = ($route) ? $route->getLabel('error', null) : null;
if (php_sapi_name() === 'cli') {
Console::error('[Error] Timestamp: '.date('c', time()));
if($route) {
Console::error('[Error] Method: '.$route->getMethod());
Console::error('[Error] URL: '.$route->getURL());
@@ -269,7 +319,7 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) {
$version = App::getEnv('_APP_VERSION', 'UNKNOWN');
switch ($error->getCode()) {
switch ($error->getCode()) { // Don't show 500 errors!
case 400: // Error allowed publicly
case 401: // Error allowed publicly
case 402: // Error allowed publicly
@@ -278,6 +328,7 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) {
case 409: // Error allowed publicly
case 412: // Error allowed publicly
case 429: // Error allowed publicly
case 501: // Error allowed publicly
$code = $error->getCode();
$message = $error->getMessage();
break;
@@ -421,4 +472,4 @@ include_once __DIR__ . '/shared/web.php';
foreach (Config::getParam('services', []) as $service) {
include_once $service['controller'];
}
}
+47 -26
View File
@@ -3,19 +3,19 @@
global $utopia, $request, $response;
use Appwrite\Database\Document;
use Appwrite\Network\Validator\Host;
use Appwrite\Utopia\Response;
use Utopia\App;
use Utopia\Validator\Numeric;
use Utopia\Validator\Text;
use Utopia\Validator\ArrayList;
use Utopia\Validator\Host;
use Utopia\Storage\Validator\File;
App::get('/v1/mock/tests/foo')
->desc('Get Foo')
->groups(['mock'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'foo')
->label('sdk.method', 'get')
->label('sdk.description', 'Mock a get request.')
@@ -33,7 +33,7 @@ App::post('/v1/mock/tests/foo')
->desc('Post Foo')
->groups(['mock'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'foo')
->label('sdk.method', 'post')
->label('sdk.description', 'Mock a post request.')
@@ -51,7 +51,7 @@ App::patch('/v1/mock/tests/foo')
->desc('Patch Foo')
->groups(['mock'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'foo')
->label('sdk.method', 'patch')
->label('sdk.description', 'Mock a patch request.')
@@ -69,7 +69,7 @@ App::put('/v1/mock/tests/foo')
->desc('Put Foo')
->groups(['mock'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'foo')
->label('sdk.method', 'put')
->label('sdk.description', 'Mock a put request.')
@@ -87,7 +87,7 @@ App::delete('/v1/mock/tests/foo')
->desc('Delete Foo')
->groups(['mock'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'foo')
->label('sdk.method', 'delete')
->label('sdk.description', 'Mock a delete request.')
@@ -105,7 +105,7 @@ App::get('/v1/mock/tests/bar')
->desc('Get Bar')
->groups(['mock'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'bar')
->label('sdk.method', 'get')
->label('sdk.description', 'Mock a get request.')
@@ -123,7 +123,7 @@ App::post('/v1/mock/tests/bar')
->desc('Post Bar')
->groups(['mock'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'bar')
->label('sdk.method', 'post')
->label('sdk.description', 'Mock a post request.')
@@ -141,7 +141,7 @@ App::patch('/v1/mock/tests/bar')
->desc('Patch Bar')
->groups(['mock'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'bar')
->label('sdk.method', 'patch')
->label('sdk.description', 'Mock a patch request.')
@@ -159,7 +159,7 @@ App::put('/v1/mock/tests/bar')
->desc('Put Bar')
->groups(['mock'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'bar')
->label('sdk.method', 'put')
->label('sdk.description', 'Mock a put request.')
@@ -177,7 +177,7 @@ App::delete('/v1/mock/tests/bar')
->desc('Delete Bar')
->groups(['mock'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'bar')
->label('sdk.method', 'delete')
->label('sdk.description', 'Mock a delete request.')
@@ -195,7 +195,7 @@ App::post('/v1/mock/tests/general/upload')
->desc('Upload File')
->groups(['mock'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'general')
->label('sdk.method', 'upload')
->label('sdk.description', 'Mock a file upload request.')
@@ -240,7 +240,7 @@ App::get('/v1/mock/tests/general/redirect')
->desc('Redirect')
->groups(['mock'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'general')
->label('sdk.method', 'redirect')
->label('sdk.description', 'Mock a redirect request.')
@@ -258,7 +258,7 @@ App::get('/v1/mock/tests/general/redirect/done')
->desc('Redirected')
->groups(['mock'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'general')
->label('sdk.method', 'redirected')
->label('sdk.description', 'Mock a redirected request.')
@@ -273,7 +273,7 @@ App::get('/v1/mock/tests/general/set-cookie')
->desc('Set Cookie')
->groups(['mock'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'general')
->label('sdk.method', 'setCookie')
->label('sdk.description', 'Mock a set cookie request.')
@@ -292,7 +292,7 @@ App::get('/v1/mock/tests/general/get-cookie')
->desc('Get Cookie')
->groups(['mock'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'general')
->label('sdk.method', 'getCookie')
->label('sdk.description', 'Mock a cookie response.')
@@ -313,10 +313,10 @@ App::get('/v1/mock/tests/general/empty')
->desc('Empty Response')
->groups(['mock'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'general')
->label('sdk.method', 'empty')
->label('sdk.description', 'Mock a an empty response.')
->label('sdk.description', 'Mock an empty response.')
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
->label('sdk.response.model', Response::MODEL_NONE)
->label('sdk.mock', true)
@@ -331,10 +331,10 @@ App::get('/v1/mock/tests/general/400-error')
->desc('400 Error')
->groups(['mock'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'general')
->label('sdk.method', 'error400')
->label('sdk.description', 'Mock a an 400 failed request.')
->label('sdk.description', 'Mock a 400 failed request.')
->label('sdk.response.code', Response::STATUS_CODE_BAD_REQUEST)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_ERROR)
@@ -347,10 +347,10 @@ App::get('/v1/mock/tests/general/500-error')
->desc('500 Error')
->groups(['mock'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'general')
->label('sdk.method', 'error500')
->label('sdk.description', 'Mock a an 500 failed request.')
->label('sdk.description', 'Mock a 500 failed request.')
->label('sdk.response.code', Response::STATUS_CODE_INTERNAL_SERVER_ERROR)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_ERROR)
@@ -359,6 +359,27 @@ App::get('/v1/mock/tests/general/500-error')
throw new Exception('Mock 500 error', 500);
});
App::get('/v1/mock/tests/general/502-error')
->desc('502 Error')
->groups(['mock'])
->label('scope', 'public')
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
->label('sdk.namespace', 'general')
->label('sdk.method', 'error502')
->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.mock', true)
->inject('response')
->action(function ($response) {
/** @var Appwrite\Utopia\Response $response */
$response
->setStatusCode(502)
->text('This is a text error')
;
});
App::get('/v1/mock/tests/general/oauth2')
->desc('OAuth Login')
->groups(['mock'])
@@ -370,7 +391,7 @@ App::get('/v1/mock/tests/general/oauth2')
->param('scope', '', new Text(100), 'OAuth2 scope list.')
->param('state', '', new Text(1024), 'OAuth2 state.')
->inject('response')
->action(function ($clientId, $redirectURI, $scope, $state, $response) {
->action(function ($client_id, $redirectURI, $scope, $state, $response) {
/** @var Appwrite\Utopia\Response $response */
$response->redirect($redirectURI.'?'.\http_build_query(['code' => 'abcdef', 'state' => $state]));
@@ -387,14 +408,14 @@ App::get('/v1/mock/tests/general/oauth2/token')
->param('client_secret', '', new Text(100), 'OAuth2 scope list.')
->param('code', '', new Text(100), 'OAuth2 state.')
->inject('response')
->action(function ($clientId, $redirectURI, $clientSecret, $code, $response) {
->action(function ($client_id, $redirectURI, $client_secret, $code, $response) {
/** @var Appwrite\Utopia\Response $response */
if ($clientId != '1') {
if ($client_id != '1') {
throw new Exception('Invalid client ID');
}
if ($clientSecret != '123456') {
if ($client_secret != '123456') {
throw new Exception('Invalid client secret');
}
+64 -6
View File
@@ -48,7 +48,9 @@ App::init(function ($utopia, $request, $response, $project, $user, $register, $e
//TODO make sure we get array here
foreach ($request->getParams() as $key => $value) { // Set request params as potential abuse keys
$timeLimit->setParam('{param-'.$key.'}', (\is_array($value)) ? \json_encode($value) : $value);
if(!empty($value)) {
$timeLimit->setParam('{param-'.$key.'}', (\is_array($value)) ? \json_encode($value) : $value);
}
}
$abuse = new Abuse($timeLimit);
@@ -61,12 +63,12 @@ App::init(function ($utopia, $request, $response, $project, $user, $register, $e
;
}
$isPreviliggedUser = Auth::isPreviliggedUser(Authorization::$roles);
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles);
$isAppUser = Auth::isAppUser(Authorization::$roles);
if (($abuse->check() // Route is rate-limited
&& App::getEnv('_APP_OPTIONS_ABUSE', 'enabled') !== 'disabled') // Abuse is not diabled
&& (!$isAppUser && !$isPreviliggedUser)) // User is not an admin or API key
&& (!$isAppUser && !$isPrivilegedUser)) // User is not an admin or API key
{
throw new Exception('Too many requests', 429);
}
@@ -76,9 +78,10 @@ App::init(function ($utopia, $request, $response, $project, $user, $register, $e
*/
$events
->setParam('projectId', $project->getId())
->setParam('webhooks', $project->getAttribute('webhooks', []))
->setParam('userId', $user->getId())
->setParam('event', $route->getLabel('event', ''))
->setParam('payload', [])
->setParam('eventData', [])
->setParam('functionId', null)
->setParam('executionId', null)
->setParam('trigger', 'event')
@@ -110,6 +113,61 @@ App::init(function ($utopia, $request, $response, $project, $user, $register, $e
}, ['utopia', 'request', 'response', 'project', 'user', 'register', 'events', 'audits', 'usage', 'deletes'], 'api');
App::init(function ($utopia, $request, $response, $project, $user) {
/** @var Utopia\App $utopia */
/** @var Utopia\Swoole\Request $request */
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $project */
/** @var Appwrite\Database\Document $user */
/** @var Utopia\Registry\Registry $register */
/** @var Appwrite\Event\Event $events */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Event\Event $usage */
/** @var Appwrite\Event\Event $deletes */
/** @var Appwrite\Event\Event $functions */
$route = $utopia->match($request);
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles);
$isAppUser = Auth::isAppUser(Authorization::$roles);
if($isAppUser || $isPrivilegedUser) { // Skip limits for app and console devs
return;
}
switch ($route->getLabel('auth.type', '')) {
case 'emailPassword':
if($project->getAttribute('usersAuthEmailPassword', true) === false) {
throw new Exception('Email / Password authentication is disabled for this project', 501);
}
break;
case 'anonymous':
if($project->getAttribute('usersAuthAnonymous', true) === false) {
throw new Exception('Anonymous authentication is disabled for this project', 501);
}
break;
case 'invites':
if($project->getAttribute('usersAuthInvites', true) === false) {
throw new Exception('Invites authentication is disabled for this project', 501);
}
break;
case 'jwt':
if($project->getAttribute('usersAuthJWT', true) === false) {
throw new Exception('JWT authentication is disabled for this project', 501);
}
break;
default:
throw new Exception('Unsupported authentication route');
break;
}
}, ['utopia', 'request', 'response', 'project', 'user'], 'auth');
App::shutdown(function ($utopia, $request, $response, $project, $events, $audits, $usage, $deletes, $mode) {
/** @var Utopia\App $utopia */
/** @var Utopia\Swoole\Request $request */
@@ -123,8 +181,8 @@ App::shutdown(function ($utopia, $request, $response, $project, $events, $audits
/** @var bool $mode */
if (!empty($events->getParam('event'))) {
if(empty($events->getParam('payload'))) {
$events->setParam('payload', $response->getPayload());
if(empty($events->getParam('eventData'))) {
$events->setParam('eventData', $response->getPayload());
}
$webhooks = clone $events;
+1 -1
View File
@@ -32,7 +32,7 @@ App::init(function ($utopia, $request, $response, $layout) {
['type' => 'developer', 'label' => 'Developer'],
['type' => 'admin', 'label' => 'Admin'],
])
->setParam('environments', Config::getParam('environments'))
->setParam('runtimes', Config::getParam('runtimes'))
->setParam('mode', App::getMode())
;
+5 -2
View File
@@ -323,7 +323,10 @@ App::get('/console/users')
$page = new View(__DIR__.'/../../views/console/users/index.phtml');
$page->setParam('providers', Config::getParam('providers'));
$page
->setParam('auth', Config::getParam('auth'))
->setParam('providers', Config::getParam('providers'))
;
$layout
->setParam('title', APP_NAME.' - Users')
@@ -370,7 +373,7 @@ App::get('/console/functions')
$page = new View(__DIR__.'/../../views/console/functions/index.phtml');
$page
->setParam('environments', Config::getParam('environments'))
->setParam('runtimes', Config::getParam('runtimes'))
;
$layout
+94 -11
View File
@@ -1,5 +1,6 @@
<?php
use Appwrite\Database\Database;
use Appwrite\Specification\Format\OpenAPI3;
use Appwrite\Specification\Format\Swagger2;
use Appwrite\Specification\Specification;
@@ -42,10 +43,38 @@ App::get('/')
->label('permission', 'public')
->label('scope', 'home')
->inject('response')
->action(function ($response) {
->inject('consoleDB')
->inject('project')
->action(function ($response, $consoleDB, $project) {
/** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Database $consoleDB */
/** @var Appwrite\Database\Document $project */
$response->redirect('/auth/signin');
$response
->addHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
->addHeader('Expires', 0)
->addHeader('Pragma', 'no-cache')
;
if ('console' === $project->getId() || $project->isEmpty()) {
$whitlistRoot = App::getEnv('_APP_CONSOLE_WHITELIST_ROOT', 'enabled');
if($whitlistRoot !== 'disabled') {
$consoleDB->getCollection([ // Count users
'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_USERS,
],
]);
$sum = $consoleDB->getSum();
if($sum !== 0) {
return $response->redirect('/auth/signin');
}
}
}
$response->redirect('/auth/signup');
});
App::get('/auth/signin')
@@ -58,6 +87,10 @@ App::get('/auth/signin')
$page = new View(__DIR__.'/../../views/home/auth/signin.phtml');
$page
->setParam('root', App::getEnv('_APP_CONSOLE_WHITELIST_ROOT', 'enabled'))
;
$layout
->setParam('title', 'Sign In - '.APP_NAME)
->setParam('body', $page);
@@ -72,6 +105,10 @@ App::get('/auth/signup')
/** @var Utopia\View $layout */
$page = new View(__DIR__.'/../../views/home/auth/signup.phtml');
$page
->setParam('root', App::getEnv('_APP_CONSOLE_WHITELIST_ROOT', 'enabled'))
;
$layout
->setParam('title', 'Sign Up - '.APP_NAME)
->setParam('body', $page);
@@ -87,6 +124,10 @@ App::get('/auth/recovery')
$page = new View(__DIR__.'/../../views/home/auth/recovery.phtml');
$page
->setParam('smtpEnabled', (!empty(App::getEnv('_APP_SMTP_HOST'))))
;
$layout
->setParam('title', 'Password Recovery - '.APP_NAME)
->setParam('body', $page);
@@ -214,6 +255,12 @@ App::get('/specs/:format')
'console' => APP_PLATFORM_CONSOLE,
];
$authCounts = [
'client' => 1,
'server' => 2,
'console' => 1,
];
$routes = [];
$models = [];
$services = [];
@@ -226,6 +273,12 @@ App::get('/specs/:format')
'description' => 'Your project ID',
'in' => 'header',
],
'JWT' => [
'type' => 'apiKey',
'name' => 'X-Appwrite-JWT',
'description' => 'Your secret JSON Web Token',
'in' => 'header',
],
'Locale' => [
'type' => 'apiKey',
'name' => 'X-Appwrite-Locale',
@@ -246,6 +299,12 @@ App::get('/specs/:format')
'description' => 'Your secret API key',
'in' => 'header',
],
'JWT' => [
'type' => 'apiKey',
'name' => 'X-Appwrite-JWT',
'description' => 'Your secret JSON Web Token',
'in' => 'header',
],
'Locale' => [
'type' => 'apiKey',
'name' => 'X-Appwrite-Locale',
@@ -266,6 +325,12 @@ App::get('/specs/:format')
'description' => 'Your secret API key',
'in' => 'header',
],
'JWT' => [
'type' => 'apiKey',
'name' => 'X-Appwrite-JWT',
'description' => 'Your secret JSON Web Token',
'in' => 'header',
],
'Locale' => [
'type' => 'apiKey',
'name' => 'X-Appwrite-Locale',
@@ -281,14 +346,32 @@ App::get('/specs/:format')
],
];
$security = [
APP_PLATFORM_CLIENT => ['Project' => []],
APP_PLATFORM_SERVER => ['Project' => [], 'Key' => []],
APP_PLATFORM_CONSOLE => ['Project' => [], 'Key' => []],
];
foreach ($utopia->getRoutes() as $key => $method) {
foreach ($method as $route) { /** @var \Utopia\Route $route */
$routeSecurity = $route->getLabel('sdk.auth', []);
$sdkPlatofrms = [];
foreach ($routeSecurity as $value) {
switch ($value) {
case APP_AUTH_TYPE_SESSION:
$sdkPlatofrms[] = APP_PLATFORM_CLIENT;
break;
case APP_AUTH_TYPE_KEY:
$sdkPlatofrms[] = APP_PLATFORM_SERVER;
break;
case APP_AUTH_TYPE_JWT:
$sdkPlatofrms[] = APP_PLATFORM_SERVER;
break;
case APP_AUTH_TYPE_ADMIN:
$sdkPlatofrms[] = APP_PLATFORM_CONSOLE;
break;
}
}
if(empty($routeSecurity)) {
$sdkPlatofrms[] = APP_PLATFORM_CLIENT;
}
if (!$route->getLabel('docs', true)) {
continue;
}
@@ -305,7 +388,7 @@ App::get('/specs/:format')
continue;
}
if ($platform !== APP_PLATFORM_CONSOLE && !\in_array($platforms[$platform], $route->getLabel('sdk.platform', []))) {
if ($platform !== APP_PLATFORM_CONSOLE && !\in_array($platforms[$platform], $sdkPlatofrms)) {
continue;
}
@@ -342,11 +425,11 @@ App::get('/specs/:format')
switch ($format) {
case 'swagger2':
$format = new Swagger2($utopia, $services, $routes, $models, $keys[$platform], $security[$platform]);
$format = new Swagger2($utopia, $services, $routes, $models, $keys[$platform], $authCounts[$platform] ?? 0);
break;
case 'open-api3':
$format = new OpenAPI3($utopia, $services, $routes, $models, $keys[$platform], $security[$platform]);
$format = new OpenAPI3($utopia, $services, $routes, $models, $keys[$platform], $authCounts[$platform] ?? 0);
break;
default:
+3 -12
View File
@@ -12,6 +12,8 @@ use Swoole\Http\Request as SwooleRequest;
use Swoole\Http\Response as SwooleResponse;
use Utopia\App;
use Utopia\CLI\Console;
use Utopia\Config\Config;
use Utopia\Domains\Domain;
// xdebug_start_trace('/tmp/trace');
@@ -33,6 +35,7 @@ $http
'http_compression' => true,
'http_compression_level' => 6,
'package_max_length' => $payloadSize,
'buffer_output_size' => $payloadSize,
])
;
@@ -65,18 +68,6 @@ Files::load(__DIR__ . '/../public');
include __DIR__ . '/controllers/general.php';
$domain = App::getEnv('_APP_DOMAIN', '');
Console::info('Issuing a TLS certificate for the master domain ('.$domain.') in 30 seconds.
Make sure your domain points to your server IP or restart your Appwrite server to try again.'); // TODO move this to installation script
ResqueScheduler::enqueueAt(\time() + 30, 'v1-certificates', 'CertificatesV1', [
'document' => [],
'domain' => $domain,
'validateTarget' => false,
'validateCNAME' => false,
]);
$http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swooleResponse) {
$request = new Request($swooleRequest);
$response = new Response($swooleResponse);
+14 -6
View File
@@ -39,8 +39,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 = 144;
const APP_VERSION_STABLE = '0.7.1';
const APP_CACHE_BUSTER = 146;
const APP_VERSION_STABLE = '0.8.0';
const APP_STORAGE_UPLOADS = '/storage/uploads';
const APP_STORAGE_FUNCTIONS = '/storage/functions';
const APP_STORAGE_CACHE = '/storage/cache';
@@ -53,6 +53,7 @@ const APP_SOCIAL_LINKEDIN = 'https://www.linkedin.com/company/appwrite';
const APP_SOCIAL_INSTAGRAM = 'https://www.instagram.com/appwrite.io';
const APP_SOCIAL_GITHUB = 'https://github.com/appwrite';
const APP_SOCIAL_DISCORD = 'https://appwrite.io/discord';
const APP_SOCIAL_DISCORD_CHANNEL = '564160730845151244';
const APP_SOCIAL_DEV = 'https://dev.to/appwrite';
const APP_SOCIAL_STACKSHARE = 'https://stackshare.io/appwrite';
// Deletion Types
@@ -61,6 +62,11 @@ const DELETE_TYPE_EXECUTIONS = 'executions';
const DELETE_TYPE_AUDIT = 'audit';
const DELETE_TYPE_ABUSE = 'abuse';
const DELETE_TYPE_CERTIFICATES = 'certificates';
// Auth Types
const APP_AUTH_TYPE_SESSION = 'Session';
const APP_AUTH_TYPE_JWT = 'JWT';
const APP_AUTH_TYPE_KEY = 'Key';
const APP_AUTH_TYPE_ADMIN = 'Admin';
$register = new Registry();
@@ -70,10 +76,11 @@ App::setMode(App::getEnv('_APP_ENV', App::MODE_TYPE_PRODUCTION));
* ENV vars
*/
Config::load('events', __DIR__.'/config/events.php');
Config::load('auth', __DIR__.'/config/auth.php');
Config::load('providers', __DIR__.'/config/providers.php');
Config::load('platforms', __DIR__.'/config/platforms.php');
Config::load('collections', __DIR__.'/config/collections.php');
Config::load('environments', __DIR__.'/config/environments.php');
Config::load('runtimes', __DIR__.'/config/runtimes.php');
Config::load('roles', __DIR__.'/config/roles.php'); // User roles and scopes
Config::load('scopes', __DIR__.'/config/scopes.php'); // User roles and scopes
Config::load('services', __DIR__.'/config/services.php'); // List of services
@@ -163,8 +170,9 @@ $register->set('influxdb', function () { // Register DB connection
if (empty($host) || empty($port)) {
return;
}
$driver = new InfluxDB\Driver\Curl("http://{$host}:{$port}");
$client = new InfluxDB\Client($host, $port, '', '', false, false, 5);
$client->setDriver($driver);
return $client;
});
@@ -313,7 +321,7 @@ App::setResource('layout', function($locale) {
}, ['locale']);
App::setResource('locale', function() {
return new Locale('en');
return new Locale(App::getEnv('_APP_LOCALE', 'en'));
});
// Queues
@@ -419,7 +427,7 @@ App::setResource('user', function($mode, $project, $console, $request, $response
if (empty($user->getId()) // Check a document has been found in the DB
|| Database::SYSTEM_COLLECTION_USERS !== $user->getCollection() // Validate returned document is really a user document
|| !Auth::tokenVerify($user->getAttribute('tokens', []), Auth::TOKEN_TYPE_LOGIN, Auth::$secret)) { // Validate user has valid login token
|| !Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret)) { // Validate user has valid login token
$user = new Document(['$id' => '', '$collection' => Database::SYSTEM_COLLECTION_USERS]);
}
+3 -3
View File
@@ -61,12 +61,12 @@ $cli
Console::log('🟢 Abuse protection is enabled');
}
$authWhitelistRoot = App::getEnv('_APP_CONSOLE_WHITELIST_ROOT', null);
$authWhitelistEmails = App::getEnv('_APP_CONSOLE_WHITELIST_EMAILS', null);
$authWhitelistIPs = App::getEnv('_APP_CONSOLE_WHITELIST_IPS', null);
$authWhitelistDomains = App::getEnv('_APP_CONSOLE_WHITELIST_DOMAINS', null);
if(empty($authWhitelistEmails)
&& empty($authWhitelistDomains)
if(empty($authWhitelistRoot)
&& empty($authWhitelistEmails)
&& empty($authWhitelistIPs)
) {
Console::log('🔴 Console access limits are disabled');
+40 -6
View File
@@ -2,17 +2,24 @@
global $cli;
use Appwrite\Auth\Auth;
use Appwrite\Docker\Compose;
use Appwrite\Docker\Env;
use Utopia\Analytics\GoogleAnalytics;
use Utopia\CLI\Console;
use Utopia\Config\Config;
use Utopia\View;
use Utopia\Validator\Text;
$cli
->task('install')
->desc('Install Appwrite')
->action(function () {
->param('httpPort', '', new Text(4), 'Server HTTP port', true)
->param('httpsPort', '', new Text(4), 'Server HTTPS port', true)
->param('organization', 'appwrite', new Text(0), 'Docker Registry organization', true)
->param('image', 'appwrite', new Text(0), 'Main appwrite docker image', true)
->param('interactive','Y', new Text(1), 'Run an interactive session', true)
->action(function ($httpPort, $httpsPort, $organization, $image, $interactive) {
/**
* 1. Start - DONE
* 2. Check for older setup and get older version - DONE
@@ -60,6 +67,9 @@ $cli
$data = @file_get_contents($path.'/docker-compose.yml');
if($data !== false) {
$time = \time();
Console::info('Compose file found, creating backup: docker-compose.yml.'.$time.'.backup');
file_put_contents($path.'/docker-compose.yml.'.$time.'.backup',$data);
$compose = new Compose($data);
$appwrite = $compose->getService('appwrite');
$oldVersion = ($appwrite) ? $appwrite->getImageVersion() : null;
@@ -85,6 +95,8 @@ $cli
$data = @file_get_contents($path.'/.env');
if($data !== false) { // Fetch all env vars from previous .env file
Console::info('Env file found, creating backup: .env.'.$time.'.backup');
file_put_contents($path.'/.env.'.$time.'.backup',$data);
$env = new Env($data);
foreach ($env->list() as $key => $value) {
@@ -108,16 +120,36 @@ $cli
}
}
$httpPort = Console::confirm('Choose your server HTTP port: (default: '.$defaultHTTPPort.')');
$httpPort = ($httpPort) ? $httpPort : $defaultHTTPPort;
if(empty($httpPort)) {
$httpPort = Console::confirm('Choose your server HTTP port: (default: '.$defaultHTTPPort.')');
$httpPort = ($httpPort) ? $httpPort : $defaultHTTPPort;
}
$httpsPort = Console::confirm('Choose your server HTTPS port: (default: '.$defaultHTTPSPort.')');
$httpsPort = ($httpsPort) ? $httpsPort : $defaultHTTPSPort;
if(empty($httpsPort)) {
$httpsPort = Console::confirm('Choose your server HTTPS port: (default: '.$defaultHTTPSPort.')');
$httpsPort = ($httpsPort) ? $httpsPort : $defaultHTTPSPort;
}
$input = [];
foreach($vars as $key => $var) {
if(!$var['required']) {
if(!empty($var['filter']) && ($interactive !== 'Y' || !Console::isInteractive())) {
if($data && $var['default'] !== null) {
$input[$var['name']] = $var['default'];
continue;
}
if($var['filter'] === 'token') {
$input[$var['name']] = Auth::tokenGenerator();
continue;
}
if($var['filter'] === 'password') {
$input[$var['name']] = Auth::passwordGenerator();
continue;
}
}
if(!$var['required'] || !Console::isInteractive() || $interactive !== 'Y') {
$input[$var['name']] = $var['default'];
continue;
}
@@ -136,6 +168,8 @@ $cli
->setParam('httpPort', $httpPort)
->setParam('httpsPort', $httpsPort)
->setParam('version', APP_VERSION_STABLE)
->setParam('organization', $organization)
->setParam('image', $image)
;
$templateForEnv
+1 -1
View File
@@ -36,7 +36,7 @@ $cli
$projects = [$console];
$count = 0;
$migration = new Version\V06($register->get('db')); //TODO: remove hardcoded version and move to dynamic migration
$migration = new Version\V07($register->get('db')); //TODO: remove hardcoded version and move to dynamic migration
while ($sum > 0) {
foreach ($projects as $project) {
+10 -17
View File
@@ -21,20 +21,6 @@ use Appwrite\SDK\Language\Swift;
$cli
->task('sdks')
->action(function () {
function getSSLPage($url)
{
$ch = \curl_init();
\curl_setopt($ch, CURLOPT_HEADER, false);
\curl_setopt($ch, CURLOPT_URL, $url);
\curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
\curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
\curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = \curl_exec($ch);
\curl_close($ch);
return $result;
}
$platforms = Config::getParam('platforms');
$selected = \strtolower(Console::confirm('Choose SDK ("*" for all):'));
$version = Console::confirm('Choose an Appwrite version');
@@ -42,7 +28,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'])) {
if(!in_array($version, ['0.6.x', '0.7.x', '0.8.x'])) {
throw new Exception('Unknown version given');
}
@@ -67,6 +53,8 @@ $cli
$target = \realpath(__DIR__.'/..').'/sdks/git/'.$language['key'].'/';
$readme = \realpath(__DIR__ . '/../../docs/sdks/'.$language['key'].'/README.md');
$readme = ($readme) ? \file_get_contents($readme) : '';
$gettingStarted = \realpath(__DIR__ . '/../../docs/sdks/'.$language['key'].'/GETTING_STARTED.md');
$gettingStarted = ($gettingStarted) ? \file_get_contents($gettingStarted) : '';
$examples = \realpath(__DIR__ . '/../../docs/sdks/'.$language['key'].'/EXAMPLES.md');
$examples = ($examples) ? \file_get_contents($examples) : '';
$changelog = \realpath(__DIR__ . '/../../docs/sdks/'.$language['key'].'/CHANGELOG.md');
@@ -141,8 +129,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
case 'dart':
$config = new Dart();
$config->setPackageName('dart_appwrite');
$warning = $warning."\n\n > This is the Dart SDK for integrating with Appwrite from your Dart server-side code.
If you're looking for the Flutter SDK you should check [appwrite/sdk-for-flutter](https://github.com/appwrite/sdk-for-flutter)";
$warning = $warning."\n\n > This is the Dart SDK for integrating with Appwrite from your Dart server-side code. If you're looking for the Flutter SDK you should check [appwrite/sdk-for-flutter](https://github.com/appwrite/sdk-for-flutter)";
break;
case 'go':
$config = new Go();
@@ -187,8 +174,14 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
->setShareVia('appwrite_io')
->setWarning($warning)
->setReadme($readme)
->setGettingStarted($gettingStarted)
->setChangelog($changelog)
->setExamples($examples)
->setTwitter(APP_SOCIAL_TWITTER_HANDLE)
->setDiscord(APP_SOCIAL_DISCORD_CHANNEL, APP_SOCIAL_DISCORD)
->setDefaultHeaders([
'X-Appwrite-Response-Format' => '0.8.0',
])
;
try {
+10 -4
View File
@@ -193,8 +193,8 @@
</div>
</div>
</li>
<li data-state="/console/account/devices">
<h2>Devices</h2>
<li data-state="/console/account/sessions">
<h2>Sessions</h2>
<div class="box margin-bottom"
data-service="account.getSessions"
@@ -250,7 +250,13 @@
</form>
</span>
<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 trans pull-start margin-end" />
<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" />
<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" />
</div>
</div>
<span data-ls-if="(!{{log.clientName}})">Unknown</span>
<span data-ls-if="({{log.clientName}})" 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>
@@ -283,7 +289,7 @@
data-failure-param-alert-text="Logout from All Sessions Failed"
data-failure-param-alert-classname="error">
<input type="hidden" name="id" value="0">
<button class="danger">Logout from all devices</button>
<button class="danger">Logout from all sessions</button>
</form>
</li>
<li data-state="/console/account/activity">
+9 -1
View File
@@ -1,6 +1,6 @@
<?php
$home = $this->getParam('home', '');
$version = $this->getParam('version', '').'.'.APP_CACHE_BUSTER;
$version = $this->getParam('version', '') . '.' . APP_CACHE_BUSTER;
?>
<footer class="clear margin-top-large">
<ul class="copyright pull-start">
@@ -12,6 +12,14 @@ $version = $this->getParam('version', '').'.'.APP_CACHE_BUSTER;
data-analytics-label="GitHub Link"
href="https://github.com/appwrite/appwrite" target="_blank" rel="noopener"><i class="icon-github-circled"></i> GitHub</a>
</li>
<li>
<a class="link-animation-enabled"
data-analytics
data-analytics-event="click"
data-analytics-category="console/footer"
data-analytics-label="Discord Link"
href="https://appwrite.io/discord" target="_blank" rel="noopener"><i class="icon-discord"></i> Discord</a>
</li>
<li>
<a class="link-animation-enabled"
data-analytics
+6 -5
View File
@@ -36,9 +36,6 @@ $maxCells = 10;
<div class="zone xl">
<ul class="phases clear" data-ui-phases data-selected="{{router.params.tab}}">
<li data-state="/console/database/collection?id={{router.params.id}}&project={{router.params.project}}">
<a data-ls-if="{{project-collection.rules.length}} > 0" data-ls-attrs="href=/console/database/document?collection={{router.params.id}}&project={{router.params.project}}&buster={{project-collection.dateUpdated}}" class="button fly round text-align-center">
<i class="icon-plus"></i>
</a>
<h2>Documents</h2>
@@ -135,7 +132,7 @@ $maxCells = 10;
</div>
</div>
<div class="clear text-align-center paging">
<div class="pull-end text-align-center paging">
<form
data-service="database.listDocuments"
data-event="submit"
@@ -166,6 +163,10 @@ $maxCells = 10;
<button name="offset" data-paging-next data-offset="{{router.params.offset}}" data-sum="{{project-documents.sum}}" class="margin-start round small" aria-label="Next"><i class="icon-right-open"></i></button>
</form>
</div>
<a data-ls-if="{{project-collection.rules.length}} > 0" data-ls-attrs="href=/console/database/document?collection={{router.params.id}}&project={{router.params.project}}&buster={{project-collection.dateUpdated}}" class="button">
Add Document
</a>
</div>
</li>
<li data-state="/console/database/collection/settings?id={{router.params.id}}&project={{router.params.project}}">
@@ -520,7 +521,7 @@ $maxCells = 10;
<div data-ls-loop="project-collections.collections" data-ls-as="project" data-ls-key="$index2" class="tiles cell-3 margin-bottom-negative">
<div class="margin-bottom" data-ls-if="{{project.$id}} != {{router.params.id}}">
<input type="radio" name="list" data-ls-attrs="value={{project.$id}},id={{project.$id}}" data-ls-bind="{{rule.list|firstElement}}" data-cast-to="array" required />
<input type="radio" data-ls-attrs="value={{project.$id}},id=[{{rule.$id}}].{{project.$id}},name=[{{rule.$id}}].list" data-ls-bind="{{rule.list|firstElement}}" data-cast-to="array" required />
<label data-ls-attrs="for={{project.$id}}"data-ls-bind="{{project.name}}"></label>
</div>
</div>
+36 -35
View File
@@ -12,40 +12,6 @@
<li data-state="/console/database?project={{router.params.project}}">
<h2>Collections</h2>
<div data-ui-modal class="box modal close" data-button-text="" data-button-class="fly round" data-button-icon="icon-plus">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h1>New Collection</h1>
<form
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Create Database Collection"
data-service="database.createCollection"
data-event="submit"
data-scope="sdk"
data-success="alert,reset,redirect,trigger"
data-success-param-alert-text="Collection created successfully"
data-success-param-redirect-url="/console/database/collection/settings?id={{serviceData.$id}}&project={{router.params.project}}"
data-success-param-trigger-events="database.createCollection"
data-failure="alert"
data-failure-param-alert-text="Failed to create collection"
data-failure-param-alert-classname="error">
<label for="user-name">Name</label>
<input type="text" class="full-width" id="collection-name" name="name" required autocomplete="off" maxlength="128" />
<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([])); ?>" />
<hr />
<button type="submit">Create</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</form>
</div>
<div class="margin-top"
data-service="database.listCollections"
data-event="load,database.createCollection,database.updateCollection,database.deleteCollection"
@@ -76,7 +42,7 @@
</ul>
</div>
<div class="clear text-align-center paging">
<div class="pull-end text-align-center paging">
<form
data-service="database.listCollections"
data-event="submit"
@@ -105,6 +71,41 @@
<button name="offset" data-paging-next data-offset="{{router.params.offset}}" data-sum="{{project-collections.sum}}" class="margin-start round small" aria-label="Next"><i class="icon-right-open"></i></button>
</form>
</div>
<div data-ui-modal class="modal close box sticky-footer" data-button-text="Add Collection">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h1>New Collection</h1>
<form
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Create Database Collection"
data-service="database.createCollection"
data-event="submit"
data-scope="sdk"
data-success="alert,reset,redirect,trigger"
data-success-param-alert-text="Collection created successfully"
data-success-param-redirect-url="/console/database/collection/settings?id={{serviceData.$id}}&project={{router.params.project}}"
data-success-param-trigger-events="database.createCollection"
data-failure="alert"
data-failure-param-alert-text="Failed to create collection"
data-failure-param-alert-classname="error">
<label for="user-name">Name</label>
<input type="text" class="full-width" id="collection-name" name="name" required autocomplete="off" maxlength="128" />
<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([])); ?>" />
<hr />
<button type="submit">Create</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</form>
</div>
</li>
<!-- <li data-state="/console/database/usage?project={{router.params.project}}">
<h2>Usage</h2>
+29 -19
View File
@@ -46,28 +46,13 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled',true);
<div class="box margin-bottom-large">
<div class="text-align-center">
<img src="" data-ls-attrs="src=/images/environments/{{project-function.env|envLogo}}" alt="Function Env." class="avatar huge margin-top-negative-xxl" />
<img src="" data-ls-attrs="src=/images/runtimes/{{project-function.env|envLogo}}" alt="Function Env." 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>
<form data-ls-if="{{project-function.tag}} !== ''" name="functions.createExecution" class="margin-top"
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Create Function Execution"
data-service="functions.createExecution"
data-event="submit"
data-param-function-id="{{router.params.id}}"
data-success="alert,trigger"
data-success-param-alert-text="Function executed successfully"
data-success-param-trigger-events="functions.createExecution"
data-failure="alert"
data-failure-param-alert-text="Failed to execute function"
data-failure-param-alert-classname="error">
<button style="vertical-align: top;">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>
</form>
<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>
</div>
</div>
</div>
@@ -575,6 +560,31 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled',true);
</div>
</div>
<div data-ui-modal class="modal close box sticky-footer" data-button-hide="on" data-open-event="execute-now">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h1 class="margin-bottom">Execute Function</h1>
<form data-ls-if="{{project-function.tag}} !== ''" name="functions.createExecution" class="margin-top"
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Create Function Execution"
data-service="functions.createExecution"
data-event="submit"
data-param-function-id="{{router.params.id}}"
data-success="alert,trigger"
data-success-param-alert-text="Function executed successfully"
data-success-param-trigger-events="functions.createExecution"
data-failure="alert"
data-failure-param-alert-text="Failed to execute function"
data-failure-param-alert-classname="error">
<label for="execution-data">Custom Data</label>
<textarea id="execution-data" name="data" autocomplete="off" class="margin-bottom" placeholder="Data string (optional)"></textarea>
<button type="submit" style="vertical-align: top;">Execute Now</button>
</form>
</div>
<div data-ui-modal class="modal close box sticky-footer" data-button-hide="on" data-open-event="deploy-tag">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
+5 -5
View File
@@ -1,5 +1,5 @@
<?php
$environments = $this->getParam('environments', []);
$runtimes = $this->getParam('runtimes', []);
?>
<div class="cover">
<h1 class="zone xl margin-bottom-large">
@@ -40,7 +40,7 @@ $environments = $this->getParam('environments', []);
<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/environments/{{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.env|envLogo}}?v=<?php echo APP_CACHE_BUSTER; ?>" alt="Function Env." 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>
@@ -109,10 +109,10 @@ $environments = $this->getParam('environments', []);
<label for="name">Name</label>
<input type="text" id="name" name="name" required autocomplete="off" class="margin-bottom" maxlength="128" />
<label for="env">Environment</label>
<label for="env">Runtimes</label>
<select name="env" id="env" required class="margin-bottom-xl">
<?php foreach($environments as $key => $environment): ?>
<option value="<?php echo $this->escape($key); ?>"><?php echo $this->escape($environment['name']); ?> <?php echo $this->escape($environment['version']); ?></option>
<?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>
+1 -1
View File
@@ -93,7 +93,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled',true);
<div class="chart-metric">
<div class="value margin-bottom-small"><span class="sum" data-ls-bind="{{usage.requests.total|statsTotal}}">N/A</span></div>
<div class="metric margin-bottom-small">Requests <span class="tooltip" data-tooltip="Total number of API requests last 30 days"><i class="icon-info-circled"></i></span></div>
<div class="metric margin-bottom-small">Requests <span class="tooltip" data-tooltip="Total number of API requests"><i class="icon-info-circled"></i></span></div>
</div>
</div>
<div class="col span-3">
+2 -2
View File
@@ -415,7 +415,7 @@ $smtpEnabled = $this->getParam('smtpEnabled', false);
data-failure-param-alert-classname="error">
<input name="teamId" data-ls-attrs="id=leave-teamId-{{member.$id}}" type="hidden" data-ls-bind="{{console-project.teamId}}">
<input name="inviteId" data-ls-attrs="id=leave-inviteId-{{member.$id}}" type="hidden" data-ls-bind="{{member.$id}}">
<input name="membershipId" data-ls-attrs="id=leave-membershipId-{{member.$id}}" type="hidden" data-ls-bind="{{member.$id}}">
<button class="danger">Leave</button>
</form>
@@ -437,7 +437,7 @@ $smtpEnabled = $this->getParam('smtpEnabled', false);
data-failure-param-alert-classname="error">
<input name="teamId" data-ls-attrs="id=resend-teamId-{{member.$id}}" type="hidden" data-ls-bind="{{console-project.teamId}}">
<input name="inviteId" data-ls-attrs="id=resend-inviteId-{{member.$id}}" type="hidden" data-ls-bind="{{member.$id}}">
<input name="membershipId" data-ls-attrs="id=resend-membershipId-{{member.$id}}" type="hidden" data-ls-bind="{{member.$id}}">
<button class="reverse">Resend</button>
</form>
+56 -45
View File
@@ -17,48 +17,6 @@ $fileLimitHuman = $this->getParam('fileLimitHuman', 0);
<li data-state="/console/database?project={{router.params.project}}">
<h2 class="margin-bottom">Files</h2>
<div data-ui-modal class="box modal sticky-footer close" data-button-text="" data-button-class="fly round" data-button-icon="icon-plus">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h1>Upload File</h1>
<form
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Create Storage File"
data-service="storage.createFile"
data-event="submit"
data-scope="sdk"
data-loading="Uploading File..."
data-success="alert,trigger,reset"
data-success-param-alert-text="File uploaded successfully"
data-success-param-trigger-events="storage.createFile"
data-failure="alert"
data-failure-param-alert-text="Failed to upload file"
data-failure-param-alert-classname="error">
<input type="hidden" name="folderId" id="files-folderId" data-cast-to="integer" value="1">
<label for="file-read">File</label>
<input type="file" name="file" id="file-file" size="1" required>
<div class="text-fade text-size-xs margin-top-negative-small margin-bottom">(Max file size allowed: <?php echo $fileLimitHuman; ?>)</div>
<label for="file-read">Read Access (<a data-ls-attrs="href={{env.HOME}}/docs/permissions" target="_blank" rel="noopener">Learn more</a>)</label>
<input type="hidden" id="file-read" name="read" data-forms-tags data-cast-to="json" value="<?php echo htmlentities(json_encode(['*'])); ?>" placeholder="User ID, Team ID or Role" />
<div class="text-fade text-size-xs margin-top-negative-small margin-bottom">Add * for wildcard access</div>
<label for="file-write">Write Access (<a data-ls-attrs="href={{env.HOME}}/docs/permissions" target="_blank" rel="noopener">Learn more</a>)</label>
<input type="hidden" id="file-write" name="write" data-forms-tags data-cast-to="json" value="" placeholder="User ID, Team ID or Role" />
<div class="text-fade text-size-xs margin-top-negative-small margin-bottom">Add * for wildcard access</div>
<footer>
<button type="submit">Create</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</footer>
</form>
</div>
<form class="box padding-small margin-bottom search"
data-service="storage.listFiles"
data-event="submit"
@@ -176,7 +134,7 @@ $fileLimitHuman = $this->getParam('fileLimitHuman', 0);
<input type="hidden" name="fileId" data-ls-bind="{{file.$id}}" />
</form>
</div>
<div class="col span-4">
<div class="col span-4 text-size-small">
<div class="margin-bottom-small">File Preview</div>
<div class="margin-bottom-small">
@@ -187,9 +145,20 @@ $fileLimitHuman = $this->getParam('fileLimitHuman', 0);
<a href="" data-ls-attrs="href={{env.ENDPOINT}}/v1/storage/files/{{file.$id}}/view?project={{router.params.project}}&mode=admin" target="_blank" rel="noopener"><i class="icon-angle-circled-right margin-start-negative-tiny margin-end-tiny"></i> New Window <i class="icon-link-ext"></i></a>
</div>
<div class="margin-bottom">
<div class="margin-bottom-small">
<a href="" data-ls-attrs="href={{env.ENDPOINT}}/v1/storage/files/{{file.$id}}/download?project={{router.params.project}}&mode=admin" target="_blank" rel="noopener"><i class="icon-angle-circled-right margin-start-negative-tiny margin-end-tiny"></i> Download <i class="icon-link-ext"></i></a>
</div>
<div class="margin-bottom-tiny">
<i class="icon-angle-circled-right margin-start-negative-tiny margin-end-tiny"></i> Type: <span data-ls-bind="{{file.mimeType}}"></span>
</div>
<div class="margin-bottom-tiny">
<i class="icon-angle-circled-right margin-start-negative-tiny margin-end-tiny"></i> Size: <span data-ls-bind="{{file.sizeOriginal|humanFileSize}}"></span>
<span data-ls-bind="{{file.sizeOriginal|humanFileUnit}}"></span>
</div>
<div class="margin-bottom">
<i class="icon-angle-circled-right margin-start-negative-tiny margin-end-tiny"></i> Created at: <span data-ls-bind="{{file.dateCreated|dateText}}"></span>
</div>
</div>
</div>
@@ -215,7 +184,7 @@ $fileLimitHuman = $this->getParam('fileLimitHuman', 0);
</div>
</div>
<div class="clear text-align-center paging">
<div class="pull-end text-align-center paging">
<form
data-service="storage.listFiles"
data-event="submit"
@@ -244,6 +213,48 @@ $fileLimitHuman = $this->getParam('fileLimitHuman', 0);
<button name="offset" data-paging-next data-offset="{{router.params.offset}}" data-sum="{{project-files.sum}}" class="margin-start round small" aria-label="Next"><i class="icon-right-open"></i></button>
</form>
</div>
<div data-ui-modal class="box modal sticky-footer close" data-button-text="Add File">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h1>Upload File</h1>
<form
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Create Storage File"
data-service="storage.createFile"
data-event="submit"
data-scope="sdk"
data-loading="Uploading File..."
data-success="alert,trigger,reset"
data-success-param-alert-text="File uploaded successfully"
data-success-param-trigger-events="storage.createFile"
data-failure="alert"
data-failure-param-alert-text="Failed to upload file"
data-failure-param-alert-classname="error">
<input type="hidden" name="folderId" id="files-folderId" data-cast-to="integer" value="1">
<label for="file-read">File</label>
<input type="file" name="file" id="file-file" size="1" required>
<div class="text-fade text-size-xs margin-top-negative-small margin-bottom">(Max file size allowed: <?php echo $fileLimitHuman; ?>)</div>
<label for="file-read">Read Access (<a data-ls-attrs="href={{env.HOME}}/docs/permissions" target="_blank" rel="noopener">Learn more</a>)</label>
<input type="hidden" id="file-read" name="read" data-forms-tags data-cast-to="json" value="<?php echo htmlentities(json_encode(['*'])); ?>" placeholder="User ID, Team ID or Role" />
<div class="text-fade text-size-xs margin-top-negative-small margin-bottom">Add * for wildcard access</div>
<label for="file-write">Write Access (<a data-ls-attrs="href={{env.HOME}}/docs/permissions" target="_blank" rel="noopener">Learn more</a>)</label>
<input type="hidden" id="file-write" name="write" data-forms-tags data-cast-to="json" value="" placeholder="User ID, Team ID or Role" />
<div class="text-fade text-size-xs margin-top-negative-small margin-bottom">Add * for wildcard access</div>
<footer>
<button type="submit">Create</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</footer>
</form>
</div>
</div>
</li>
</ul>
+170 -73
View File
@@ -1,5 +1,6 @@
<?php
$providers = $this->getParam('providers', []);
$auth = $this->getParam('auth', []);
?>
<div class="cover">
@@ -17,41 +18,6 @@ $providers = $this->getParam('providers', []);
<h2>Users</h2>
<div data-ui-modal class="box modal close" data-button-text="" data-button-class="fly round" data-button-icon="icon-plus">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h1>Create User</h1>
<form
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Create User"
data-service="users.create"
data-event="submit"
data-success="alert,trigger,reset"
data-success-param-alert-text="Created user successfully"
data-success-param-trigger-events="users.create"
data-failure="alert"
data-failure-param-alert-text="Failed to create user"
data-failure-param-alert-classname="error">
<label for="user-name">Name</label>
<input type="text" class="full-width" id="user-name" name="name" required autocomplete="off" maxlength="128" />
<label for="user-email">Email</label>
<input type="email" class="full-width" id="user-email" name="email" required autocomplete="off" />
<label for="user-password">Password</label>
<input type="password" class="full-width" id="user-password" name="password" required pattern=".{6,}" title="Six or more characters" autocomplete="off" />
<hr />
<button type="submit">Create</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</form>
</div>
<form class="box padding-small margin-bottom search"
data-service="users.list"
data-event="submit"
@@ -111,7 +77,8 @@ $providers = $this->getParam('providers', []);
<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}} === ''">-----</span>
<span data-ls-if="{{user.name|escape}} === ''">-----</span>
<span data-ls-if="{{user.email}} === ''">Anonymous User</span>
</a>
</td>
<td data-title="Email: ">
@@ -137,7 +104,7 @@ $providers = $this->getParam('providers', []);
</div>
</div>
<div class="clear text-align-center paging">
<div class="pull-end text-align-center paging">
<form
data-service="users.list"
data-event="submit"
@@ -166,41 +133,47 @@ $providers = $this->getParam('providers', []);
<button name="offset" data-paging-next data-offset="{{router.params.offset}}" data-sum="{{project-users.sum}}" class="margin-start round small" aria-label="Next"><i class="icon-right-open"></i></button>
</form>
</div>
<div data-ui-modal class="box modal close" data-button-text="Add User">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h1>Create User</h1>
<form
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Create User"
data-service="users.create"
data-event="submit"
data-success="alert,trigger,reset"
data-success-param-alert-text="Created user successfully"
data-success-param-trigger-events="users.create"
data-failure="alert"
data-failure-param-alert-text="Failed to create user"
data-failure-param-alert-classname="error">
<label for="user-name">Name</label>
<input type="text" class="full-width" id="user-name" name="name" required autocomplete="off" maxlength="128" />
<label for="user-email">Email</label>
<input type="email" class="full-width" id="user-email" name="email" required autocomplete="off" />
<label for="user-password">Password</label>
<input type="password" class="full-width" id="user-password" name="password" required pattern=".{6,}" title="Six or more characters" autocomplete="off" />
<hr />
<button type="submit">Create</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</form>
</div>
</div>
</li>
<li data-state="/console/users/teams?project={{router.params.project}}">
<h2>Teams</h2>
<div data-ui-modal class="box modal close" data-button-text="" data-button-class="fly round" data-button-icon="icon-plus">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h1>Create Team</h1>
<form
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Create Team"
data-service="teams.create"
data-event="submit"
data-success="alert,trigger,reset"
data-success-param-alert-text="Created team successfully"
data-success-param-trigger-events="filter-teams-changed,teams.create"
data-failure="alert"
data-failure-param-alert-text="Failed to create team"
data-failure-param-alert-classname="error">
<label for="team-name">Name</label>
<input type="text" class="full-width" id="team-name" name="name" required autocomplete="off" maxlength="128" />
<hr />
<button type="submit">Create</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</form>
</div>
<form class="box padding-small margin-bottom search"
data-service="teams.list"
data-event="submit"
@@ -239,7 +212,7 @@ $providers = $this->getParam('providers', []);
</div>
<div data-ls-if="0 != {{project-teams.sum}}">
<div class="margin-bottom-small margin-end-small text-align-end text-size-small"><span data-ls-bind="{{project-teams.sum}}"></span> results found</div>
<div class="margin-bottom-small margin-end-small text-align-end text-size-small"><span data-ls-bind="{{project-teams.sum}}"></span> results found</div>
<div class="box margin-bottom">
<table class="vertical">
@@ -267,7 +240,7 @@ $providers = $this->getParam('providers', []);
</div>
</div>
<div class="clear text-align-center paging">
<div class="pull-end text-align-center paging">
<form
data-service="teams.list"
data-event="submit"
@@ -296,13 +269,131 @@ $providers = $this->getParam('providers', []);
<button name="offset" data-paging-next data-offset="{{router.params.offset}}" data-sum="{{project-teams.sum}}" class="margin-start round small" aria-label="Next"><i class="icon-right-open"></i></button>
</form>
</div>
<div data-ui-modal class="box modal close" data-button-text="Add Team">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h1>Create Team</h1>
<form
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Create Team"
data-service="teams.create"
data-event="submit"
data-success="alert,trigger,reset"
data-success-param-alert-text="Created team successfully"
data-success-param-trigger-events="filter-teams-changed,teams.create"
data-failure="alert"
data-failure-param-alert-text="Failed to create team"
data-failure-param-alert-classname="error">
<label for="team-name">Name</label>
<input type="text" class="full-width" id="team-name" name="name" required autocomplete="off" maxlength="128" />
<hr />
<button type="submit">Create</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</form>
</div>
</div>
</li>
<li data-state="/console/users/providers?project={{router.params.project}}">
<h2>OAuth2 Providers</h2>
<p data-ls-if="{{console-project.usersAuthLimit}} == 0" class="text-fade text-size-small margin-bottom pull-end">Unlimited Users <span class="link" data-ls-ui-trigger="project-update-auth-users-limit">Set Limit</a></p>
<p data-ls-if="{{console-project.usersAuthLimit}} != 0" class="text-fade text-size-small margin-bottom pull-end"><span data-ls-bind="{{console-project.usersAuthLimit|statsTotal}}"></span> Users allowed <span class="link" data-ls-ui-trigger="project-update-auth-users-limit">Change Limit</a></p>
<h2>Settings</h2>
<div class="margin-bottom margin-top-large"
<div data-ui-modal class="modal close" data-button-alias="none" data-open-event="project-update-auth-users-limit">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h1>Max Allowed Users</h1>
<form data-debug="1"
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Update Project Users Limit"
data-service="projects.updateAuthLimit"
data-scope="console"
data-event="submit"
data-param-project-id="{{router.params.project}}"
data-success="alert,trigger"
data-success-param-alert-text="Updated project users limit successfully"
data-success-param-trigger-events="projects.update"
data-failure="alert"
data-failure-param-alert-text="Failed to update project users limit"
data-failure-param-alert-classname="error">
<input name="limit" id="users-limit" type="number" data-ls-bind="{{console-project.usersAuthLimit}}" data-cast-to="numeric" min="0" />
<div class="info row thin margin-bottom margin-top">
<div class="col span-1">
<i class="icon-info-circled text-sign"></i>
</div>
<div class="col span-11">This limit will prevent new users from signing up for your project, no matter what auth method has been used. You will still be able to create users and team memberships from your Appwrite console. For an unlimited amount of users, set the limit to 0.</div>
</div>
<button>Update</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</form>
</div>
<p class="text-fade margin-bottom">Choose auth methods you wish to use.</p>
<ul class="tiles cell-3 margin-bottom-small">
<?php foreach($auth as $index => $method):
$key = $method['key'] ?? '';
$name = $method['name'] ?? '';
$icon = $method['icon'] ?? '';
$docs = $method['docs'] ?? '';
$enabled = $method['enabled'] ?? false;
?>
<li class="">
<div class="box padding-small margin-bottom clear">
<?php if($enabled): ?>
<form
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Update Project Auth Status (<?php echo $this->escape($name); ?>)"
data-service="projects.updateAuthStatus"
data-scope="console"
data-event="change"
data-param-project-id="{{router.params.project}}"
data-success="alert,trigger"
data-success-param-alert-text="Updated project auth status successfully"
data-success-param-trigger-events="projects.update"
data-failure="alert"
data-failure-param-alert-text="Failed to update project auth status settings"
data-failure-param-alert-classname="error">
<input name="method" id="<?php echo $this->escape($key); ?>" type="hidden" autocomplete="off" value="<?php echo $this->escape($index); ?>">
<input name="status" type="hidden" data-forms-switch data-ls-bind="{{console-project.<?php echo $this->escape($key); ?>}}" data-cast-to="boolean" class="pull-end" />
</form>
<?php endif; ?>
<img src="<?php echo $this->escape($icon); ?>?buster=<?php echo APP_CACHE_BUSTER; ?>" alt="Email/Password Logo" class="pull-start provider margin-end" />
<span class="text-size-small"><?php echo $this->escape($name); ?><?php if(!$enabled): ?> <spann class="text-fade text-size-xs">soon</span><?php endif; ?></span>
<?php if($docs): ?>
<p class="margin-bottom-no text-one-liner text-size-small">
<a href="<?php echo $this->escape($docs); ?>" target="_blank" rel="noopener">Docs<i class="icon-link-ext"></i></a>
</p>
<?php endif; ?>
</div>
</li>
<?php endforeach; ?>
</ul>
<h3>OAuth2 Providers</h3>
<div class="margin-bottom margin-top"
data-service="projects.get"
data-event="load,projects.create,projects.update,projects.deleteProject"
data-name="console-project"
@@ -312,6 +403,7 @@ $providers = $this->getParam('providers', []);
<?php foreach ($providers as $provider => $data):
if (isset($data['enabled']) && !$data['enabled']) { continue; }
if (isset($data['mock']) && $data['mock']) { continue; }
$sandbox = $data['sandbox'] ?? false;
$form = $data['form'] ?? false;
$name = $data['name'] ?? 'Unknown';
$beta = $data['beta'] ?? false;
@@ -320,9 +412,10 @@ $providers = $this->getParam('providers', []);
<div data-ui-modal class="modal close" data-button-alias="none" data-open-event="provider-update-<?php echo $provider; ?>">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h1><?php echo $this->escape($name); ?> OAuth2 Settings</h1>
<h1><?php echo $this->escape($name); ?> <?php if($sandbox): ?>Sandbox<?php endif; ?> OAuth2 Settings</h1>
<form
autocomplete="off"
data-analytics
data-analytics-activity
data-analytics-event="submit"
@@ -338,6 +431,10 @@ $providers = $this->getParam('providers', []);
data-failure="alert"
data-failure-param-alert-text="Failed to update project OAuth2 settings"
data-failure-param-alert-classname="error">
<input style="display: none" type="text" /> <?php /** Disabling Chrone Autofill @see https://stackoverflow.com/a/15917221/2299554 */ ?>
<input style="display: none" type="password" /> <?php /** Disabling Chrone Autofill @see https://stackoverflow.com/a/15917221/2299554 */ ?>
<input name="provider" id="provider<?php echo $this->escape(ucfirst($provider)); ?>" type="hidden" autocomplete="off" value="<?php echo $this->escape($provider); ?>">
<?php if(!$form): ?>
@@ -383,10 +480,10 @@ $providers = $this->getParam('providers', []);
<button class="switch pull-end" data-ls-ui-trigger="provider-update-<?php echo $this->escape($provider); ?>"></button>
</span>
<img src="/images/oauth2/<?php echo $this->escape(strtolower($provider)); ?>.png?buster=<?php echo APP_CACHE_BUSTER; ?>" alt="<?php echo $this->escape(ucfirst($provider)); ?> Logo" class="pull-start provider margin-end" />
<img src="/images/users/<?php echo $this->escape(strtolower($provider)); ?>.png?buster=<?php echo APP_CACHE_BUSTER; ?>" alt="<?php echo $this->escape(ucfirst($provider)); ?> Logo" class="pull-start provider margin-end" />
<span class="text-size-small">
<?php echo $this->escape($name); ?> <?php if($beta): ?>(beta)<?php endif; ?>
<?php echo $this->escape($name); ?> <?php if($sandbox): ?><span class="text-size-xs text-fade">sandbox</span><?php endif; ?> <?php if($beta): ?><span class="text-size-xs text-fade">beta</span><?php endif; ?>
</span>
<p class="margin-bottom-no text-one-liner text-size-small">
+1 -1
View File
@@ -105,7 +105,7 @@
data-failure-param-alert-classname="error">
<input name="teamId" data-ls-attrs="id={{member.$id}}" type="hidden" data-ls-bind="{{router.params.id}}">
<input name="inviteId" data-ls-attrs="id=leave-inviteId-{{member.$id}}" type="hidden" data-ls-bind="{{member.$id}}">
<input name="membershipId" data-ls-attrs="id=leave-membershipId-{{member.$id}}" type="hidden" data-ls-bind="{{member.$id}}">
<button class="danger">Remove</button>
</form>
+13 -7
View File
@@ -12,7 +12,8 @@
<br />
<span data-ls-bind="{{user.name}}">&nbsp;</span>
<span data-ls-if="{{user.name}} === ''">Unknown</span>
<span data-ls-if="{{user.name}} === '' && {{user.email}} !== ''">Unknown</span>
<span data-ls-if="{{user.name}} === '' && {{user.email}} === ''">Anonymous User</span>
</h1>
</div>
@@ -109,7 +110,7 @@
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Delete User"
data-service="users.deleteUser"
data-service="users.delete"
data-event="submit"
data-param-user-id="{{router.params.id}}"
data-success="alert,trigger,redirect"
@@ -180,8 +181,8 @@
</div>
</div>
</li>
<li data-state="/console/users/user/devices?id={{router.params.id}}&project={{router.params.project}}">
<h2>Devices</h2>
<li data-state="/console/users/user/sessions?id={{router.params.id}}&project={{router.params.project}}">
<h2>Sessions</h2>
<div
data-service="users.getSessions"
@@ -216,8 +217,13 @@
<input type="hidden" name="sessionId" data-ls-bind="{{session.$id}}">
<button class="danger">Logout</button>
</form>
<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 trans pull-start margin-end" />
<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" />
<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" />
</div>
</div>
<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>
@@ -244,7 +250,7 @@
data-failure-param-alert-text="Failed to logout all sessions"
data-failure-param-alert-classname="error">
<button class="danger">Logout from all devices</button>
<button class="danger">Logout from all sessions</button>
</form>
</div>
</div>
+1 -1
View File
@@ -9,7 +9,7 @@
data-scope="console"
data-event="submit"
data-param-team-id="{{router.params.teamId}}"
data-param-invite-id="{{router.params.inviteId}}"
data-param-membership-id="{{router.params.membershipId}}"
data-param-user-id="{{router.params.userId}}"
data-param-secret="{{router.params.secret}}"
data-success="redirect,alert,trigger"
+10 -1
View File
@@ -1,3 +1,6 @@
<?php
$smtpEnabled = $this->getParam('smtpEnabled', false);
?>
<div class="zone medium">
<h1 class="zone xl margin-bottom-large margin-top">
Password Recovery
@@ -25,7 +28,13 @@
<input name="url" type="hidden" data-ls-bind="{{env.ENDPOINT}}/auth/recovery/reset" />
<button type="submit" class="btn btn-primary"><i class="fa fa-sign-in"></i> Recover</button>
<?php if(!$smtpEnabled): ?>
<div class="box note padding-tiny warning margin-bottom text-align-center">
<i class="icon-warning"></i> SMTP connection is disabled. <a href="https://appwrite.io/docs/email-delivery" target="_blank" rel="noopener">Learn more <i class="icon-link-ext"></i></a>
</div>
<?php endif; ?>
<button type="submit" class="btn btn-primary"<?php if(!$smtpEnabled): ?> disabled<?php endif; ?>><i class="fa fa-sign-in"></i> Recover</button>
</form>
</div>
+4 -1
View File
@@ -1,3 +1,6 @@
<?php
$root = ($this->getParam('root') !== 'disabled');
?>
<div class="zone medium"
data-service="account.get"
data-name="account"
@@ -43,7 +46,7 @@
<br />
<div class="text-line-high-large text-align-center">
<a href="/auth/recovery">Forgot password?</a> or don't have an account? <b><a href="/auth/signup">Sign up now</a></b>
<a href="/auth/recovery">Forgot password?</a><?php if(!$root): ?> or don't have an account? <b><a href="/auth/signup">Sign up now</a></b><?php endif; ?>
</div>
</div>
+26 -2
View File
@@ -1,4 +1,14 @@
<div class="zone medium signup">
<?php
$root = ($this->getParam('root') !== 'disabled');
?>
<div class="zone medium signup"
data-service="account.get"
data-name="account"
data-scope="console"
data-event="load"
data-success="redirect"
data-success-param-redirect-url="/console"
data-success-param-trigger-events="account.get">
<h1 class="zone xl margin-bottom-large margin-top">
Sign Up
</h1>
@@ -9,6 +19,7 @@
<form name="account.create"
data-analytics
data-newsletter
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="home"
@@ -23,6 +34,10 @@
data-failure-param-alert-text="Registration Failed. Please try again later"
data-failure-param-alert-classname="error">
<?php if($root): ?>
<p>Please create your root account</p>
<?php endif; ?>
<label>Name</label>
<input name="name" type="text" autocomplete="name" placeholder="" required maxlength="128">
@@ -39,11 +54,20 @@
By signing up, you agree to the <a data-ls-attrs="href={{env.HOME}}/policy/terms" tabindex="-1" target="_blank" rel="noopener">Terms and Conditions</a> and <a data-ls-attrs="href={{env.HOME}}/policy/privacy" target="_blank" tabindex="-1" rel="noopener">Privacy Policy</a>
</div>
<div class="newsletter margin-top margin-bottom-large">
<div class="pull-start margin-end-small margin-bottom">
<input id="newsletter" type="checkbox" />
</div>
Sign up for our <a data-ls-attrs="href={{env.HOME}}/updates" tabindex="-1" target="_blank" rel="noopener">monthly newsletter</a> <span class="text-fade">(optional)</span>.
</div>
<button type="submit">Sign Up</button>
</form>
</div>
<?php if(!$root): ?>
<div class="zone medium text-align-center">
<a href="/auth/signin">Already have an account?</a>
</div>
</div>
<?PHP endif; ?>
+30 -28
View File
@@ -3,6 +3,8 @@
$httpPort = $this->getParam('httpPort', '');
$httpsPort = $this->getParam('httpsPort', '');
$version = $this->getParam('version', '');
$organization = $this->getParam('organization', '');
$image = $this->getParam('image', '');
?>version: '3'
services:
@@ -32,7 +34,7 @@ services:
- appwrite
appwrite:
image: appwrite/appwrite:<?php echo $version."\n"; ?>
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
container_name: appwrite
restart: unless-stopped
networks:
@@ -52,10 +54,12 @@ services:
depends_on:
- mariadb
- redis
- clamav
# - clamav
- influxdb
environment:
- _APP_ENV
- _APP_LOCALE
- _APP_CONSOLE_WHITELIST_ROOT
- _APP_CONSOLE_WHITELIST_EMAILS
- _APP_CONSOLE_WHITELIST_IPS
- _APP_SYSTEM_EMAIL_NAME
@@ -93,10 +97,10 @@ services:
- _APP_FUNCTIONS_CPUS
- _APP_FUNCTIONS_MEMORY
- _APP_FUNCTIONS_MEMORY_SWAP
- _APP_FUNCTIONS_ENVS
- _APP_FUNCTIONS_RUNTIMES
appwrite-worker-usage:
image: appwrite/appwrite:<?php echo $version."\n"; ?>
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
entrypoint: worker-usage
container_name: appwrite-worker-usage
restart: unless-stopped
@@ -115,7 +119,7 @@ services:
- _APP_STATSD_PORT
appwrite-worker-audits:
image: appwrite/appwrite:<?php echo $version."\n"; ?>
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
entrypoint: worker-audits
container_name: appwrite-worker-audits
restart: unless-stopped
@@ -137,7 +141,7 @@ services:
- _APP_DB_PASS
appwrite-worker-webhooks:
image: appwrite/appwrite:<?php echo $version."\n"; ?>
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
entrypoint: worker-webhooks
container_name: appwrite-worker-webhooks
restart: unless-stopped
@@ -153,14 +157,9 @@ services:
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
appwrite-worker-tasks:
image: appwrite/appwrite:<?php echo $version."\n"; ?>
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
entrypoint: worker-tasks
container_name: appwrite-worker-tasks
restart: unless-stopped
@@ -171,6 +170,7 @@ services:
- mariadb
environment:
- _APP_ENV
- _APP_OPENSSL_KEY_V1
- _APP_SYSTEM_SECURITY_EMAIL_ADDRESS
- _APP_REDIS_HOST
- _APP_REDIS_PORT
@@ -183,7 +183,7 @@ services:
- _APP_DB_PASS
appwrite-worker-deletes:
image: appwrite/appwrite:<?php echo $version."\n"; ?>
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
entrypoint: worker-deletes
container_name: appwrite-worker-deletes
restart: unless-stopped
@@ -209,7 +209,7 @@ services:
- _APP_DB_PASS
appwrite-worker-certificates:
image: appwrite/appwrite:<?php echo $version."\n"; ?>
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
entrypoint: worker-certificates
container_name: appwrite-worker-certificates
restart: unless-stopped
@@ -236,7 +236,7 @@ services:
- _APP_DB_PASS
appwrite-worker-functions:
image: appwrite/appwrite:<?php echo $version."\n"; ?>
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
entrypoint: worker-functions
container_name: appwrite-worker-functions
restart: unless-stopped
@@ -251,6 +251,7 @@ services:
- /tmp:/tmp:rw
environment:
- _APP_ENV
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
@@ -265,10 +266,11 @@ services:
- _APP_FUNCTIONS_CPUS
- _APP_FUNCTIONS_MEMORY
- _APP_FUNCTIONS_MEMORY_SWAP
- _APP_FUNCTIONS_RUNTIMES
- _APP_USAGE_STATS
appwrite-worker-mails:
image: appwrite/appwrite:<?php echo $version."\n"; ?>
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
entrypoint: worker-mails
container_name: appwrite-worker-mails
restart: unless-stopped
@@ -291,7 +293,7 @@ services:
- _APP_SMTP_PASSWORD
appwrite-maintenance:
image: appwrite/appwrite:<?php echo $version."\n"; ?>
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
entrypoint: maintenance
container_name: appwrite-maintenance
restart: unless-stopped
@@ -312,7 +314,7 @@ services:
appwrite-schedule:
image: appwrite/appwrite:<?php echo $version."\n"; ?>
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
entrypoint: schedule
container_name: appwrite-schedule
restart: unless-stopped
@@ -336,7 +338,7 @@ services:
volumes:
- appwrite-mariadb:/var/lib/mysql:rw
environment:
- MYSQL_ROOT_PASSWORD=rootsecretpassword
- MYSQL_ROOT_PASSWORD=${_APP_DB_ROOT_PASS}
- MYSQL_DATABASE=${_APP_DB_SCHEMA}
- MYSQL_USER=${_APP_DB_USER}
- MYSQL_PASSWORD=${_APP_DB_PASS}
@@ -351,17 +353,17 @@ services:
volumes:
- appwrite-redis:/data:rw
clamav:
image: appwrite/clamav:1.2.0
container_name: appwrite-clamav
restart: unless-stopped
networks:
- appwrite
volumes:
- appwrite-uploads:/storage/uploads
# clamav:
# image: appwrite/clamav:1.2.0
# container_name: appwrite-clamav
# restart: unless-stopped
# networks:
# - appwrite
# volumes:
# - appwrite-uploads:/storage/uploads
influxdb:
image: influxdb:1.8-alpine
image: appwrite/influxdb:1.0.0
container_name: appwrite-influxdb
restart: unless-stopped
networks:
+2 -2
View File
@@ -11,7 +11,7 @@ $analytics = $this->getParam('analytics', 'UA-26264668-9');
$mode = $this->getParam('mode', '');
$canonical = $this->getParam('canonical', '');
$locale = $this->getParam('locale', null);
$environments = $this->getParam('environments', null);
$runtimes = $this->getParam('runtimes', null);
if(!empty($platforms)) {
$platforms = array_map(function($platform) {
@@ -78,7 +78,7 @@ if(!empty($platforms)) {
SETUP: '<?php echo $this->escape($this->getParam('setup')); ?>',
API: '/v1',
PROJECT: 'console',
ENVIRONMENTS: <?php echo json_encode($environments); ?>,
RUNTIMES: <?php echo json_encode($runtimes); ?>,
PLATFORMS: <?php echo json_encode($platforms); ?>,
LOCALE: '<?php echo $this->escape($locale->getText('settings.locale')); ?>',
PREFIX: '<?php echo $this->escape($this->getParam('prefix')); ?>',
+1 -1
View File
@@ -124,7 +124,7 @@ class CertificatesV1
." -w ".APP_STORAGE_CERTIFICATES
." -d {$domain->get()}", '', $stdout, $stderr);
if($stderr || $exit !== 0) {
if($exit !== 0) {
throw new Exception('Failed to issue a certificate with message: '.$stderr);
}
+9 -1
View File
@@ -112,13 +112,21 @@ class DeletesV1
protected function deleteUser(Document $document, $projectId)
{
$tokens = $document->getAttribute('tokens', []);
foreach ($tokens as $token) {
if (!$this->getProjectDB($projectId)->deleteDocument($token->getId())) {
throw new Exception('Failed to remove token from DB');
}
}
$sessions = $document->getAttribute('sessions', []);
foreach ($sessions as $session) {
if (!$this->getProjectDB($projectId)->deleteDocument($session->getId())) {
throw new Exception('Failed to remove session from DB');
}
}
// Delete Memberships
$this->deleteByGroup([
'$collection='.Database::SYSTEM_COLLECTION_MEMBERSHIPS,
+56 -25
View File
@@ -14,21 +14,19 @@ use Utopia\Config\Config;
require_once __DIR__.'/../init.php';
Runtime::enableCoroutine(0);
Console::title('Functions V1 Worker');
Runtime::setHookFlags(SWOOLE_HOOK_ALL);
Console::success(APP_NAME.' functions worker v1 has started');
$environments = Config::getParam('environments');
$runtimes = Config::getParam('runtimes');
/**
* Warmup Docker Images
*/
$warmupStart = \microtime(true);
Co\run(function() use ($environments) { // Warmup: make sure images are ready to run fast 🚀
Runtime::enableCoroutine(SWOOLE_HOOK_ALL);
Co\run(function() use ($runtimes) { // Warmup: make sure images are ready to run fast 🚀
$dockerUser = App::getEnv('DOCKERHUB_PULL_USERNAME', null);
$dockerPass = App::getEnv('DOCKERHUB_PULL_PASSWORD', null);
@@ -41,14 +39,14 @@ Co\run(function() use ($environments) { // Warmup: make sure images are ready t
Console::log('Docker Login'. $stdout.$stderr);
}
foreach($environments as $environment) {
go(function() use ($environment) {
foreach($runtimes as $runtime) {
go(function() use ($runtime) {
$stdout = '';
$stderr = '';
Console::info('Warming up '.$environment['name'].' '.$environment['version'].' environment...');
Console::info('Warming up '.$runtime['name'].' '.$runtime['version'].' environment...');
Console::execute('docker pull '.$environment['image'], '', $stdout, $stderr);
Console::execute('docker pull '.$runtime['image'], '', $stdout, $stderr);
if(!empty($stdout)) {
Console::log($stdout);
@@ -143,11 +141,15 @@ class FunctionsV1
$projectId = $this->args['projectId'] ?? '';
$functionId = $this->args['functionId'] ?? '';
$webhooks = $this->args['webhooks'] ?? [];
$executionId = $this->args['executionId'] ?? '';
$trigger = $this->args['trigger'] ?? '';
$event = $this->args['event'] ?? '';
$scheduleOriginal = $this->args['scheduleOriginal'] ?? '';
$payload = (!empty($this->args['payload'])) ? json_encode($this->args['payload']) : '';
$eventData = (!empty($this->args['eventData'])) ? json_encode($this->args['eventData']) : '';
$data = $this->args['data'] ?? '';
$userId = $this->args['userId'] ?? '';
$jwt = $this->args['jwt'] ?? '';
$database = new Database();
$database->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register));
@@ -195,7 +197,7 @@ class FunctionsV1
Console::success('Triggered function: '.$event);
$this->execute('event', $projectId, '', $database, $function, $event, $payload);
$this->execute('event', $projectId, '', $database, $function, $event, $eventData, $data, $webhooks, $userId, $jwt);
}
}
break;
@@ -245,14 +247,14 @@ class FunctionsV1
ResqueScheduler::enqueueAt($next, 'v1-functions', 'FunctionsV1', [
'projectId' => $projectId,
'webhooks' => $webhooks,
'functionId' => $function->getId(),
'executionId' => null,
'trigger' => 'schedule',
'scheduleOriginal' => $function->getAttribute('schedule', ''),
]); // Async task rescheduale
$this->execute($trigger, $projectId, $executionId, $database, $function);
$this->execute($trigger, $projectId, $executionId, $database, $function, /*$event*/'', /*$eventData*/'', $data, $webhooks, $userId, $jwt);
break;
case 'http':
@@ -264,7 +266,7 @@ class FunctionsV1
throw new Exception('Function not found ('.$functionId.')');
}
$this->execute($trigger, $projectId, $executionId, $database, $function);
$this->execute($trigger, $projectId, $executionId, $database, $function, /*$event*/'', /*$eventData*/'', $data, $webhooks, $userId, $jwt);
break;
default:
@@ -282,15 +284,19 @@ class FunctionsV1
* @param Database $database
* @param Database $function
* @param string $event
* @param string $payload
* @param string $eventData
* @param string $data
* @param array $webhooks
* @param string $userId
* @param string $jwt
*
* @return void
*/
public function execute(string $trigger, string $projectId, string $executionId, Database $database, Document $function, string $event = '', string $payload = ''): void
public function execute(string $trigger, string $projectId, string $executionId, Database $database, Document $function, string $event = '', string $eventData = '', string $data = '', array $webhooks = [], string $userId = '', string $jwt = ''): void
{
global $list;
$environments = Config::getParam('environments');
$runtimes = Config::getParam('runtimes');
Authorization::disable();
$tag = $database->getDocument($function->getAttribute('tag', ''));
@@ -324,11 +330,11 @@ class FunctionsV1
Authorization::reset();
$environment = (isset($environments[$function->getAttribute('env', '')]))
? $environments[$function->getAttribute('env', '')]
$runtime = (isset($runtimes[$function->getAttribute('env', '')]))
? $runtimes[$function->getAttribute('env', '')]
: null;
if(\is_null($environment)) {
if(\is_null($runtime)) {
throw new Exception('Environment "'.$function->getAttribute('env', '').' is not supported');
}
@@ -337,10 +343,14 @@ class FunctionsV1
'APPWRITE_FUNCTION_NAME' => $function->getAttribute('name', ''),
'APPWRITE_FUNCTION_TAG' => $tag->getId(),
'APPWRITE_FUNCTION_TRIGGER' => $trigger,
'APPWRITE_FUNCTION_ENV_NAME' => $environment['name'],
'APPWRITE_FUNCTION_ENV_VERSION' => $environment['version'],
'APPWRITE_FUNCTION_RUNTIME_NAME' => $runtime['name'],
'APPWRITE_FUNCTION_RUNTIME_VERSION' => $runtime['version'],
'APPWRITE_FUNCTION_EVENT' => $event,
'APPWRITE_FUNCTION_EVENT_PAYLOAD' => $payload,
'APPWRITE_FUNCTION_EVENT_DATA' => $eventData,
'APPWRITE_FUNCTION_DATA' => $data,
'APPWRITE_FUNCTION_USER_ID' => $userId,
'APPWRITE_FUNCTION_JWT' => $jwt,
'APPWRITE_FUNCTION_PROJECT_ID' => $projectId,
]);
\array_walk($vars, function (&$value, $key) {
@@ -412,7 +422,7 @@ class FunctionsV1
" --volume {$tagPathTargetDir}:/tmp:rw".
" --workdir /usr/local/src".
" ".\implode(" ", $vars).
" {$environment['image']}".
" {$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'"
, '', $stdout, $stderr, 30);
@@ -469,6 +479,27 @@ class FunctionsV1
throw new Exception('Failed saving execution to DB', 500);
}
$executionUpdate = new Event('v1-webhooks', 'WebhooksV1');
$executionUpdate
->setParam('projectId', $projectId)
->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']
]);
$executionUpdate->trigger();
$usage = new Event('v1-usage', 'UsageV1');
$usage
-1
View File
@@ -29,7 +29,6 @@ class MailsV1
return;
}
$event = $this->args['event'];
$from = $this->args['from'];
$recipient = $this->args['recipient'];
$name = $this->args['name'];
+9 -9
View File
@@ -26,20 +26,20 @@ class UsageV1
$statsd = $register->get('statsd', true);
$projectId = $this->args['projectId'];
$projectId = $this->args['projectId'] ?? '';
$storage = $this->args['storage'];
$storage = $this->args['storage'] ?? 0;
$networkRequestSize = $this->args['networkRequestSize'];
$networkResponseSize = $this->args['networkResponseSize'];
$networkRequestSize = $this->args['networkRequestSize'] ?? 0;
$networkResponseSize = $this->args['networkResponseSize'] ?? 0;
$httpMethod = $this->args['httpMethod'];
$httpRequest = $this->args['httpRequest'];
$httpMethod = $this->args['httpMethod'] ?? '';
$httpRequest = $this->args['httpRequest'] ?? 0;
$functionId = $this->args['functionId'];
$functionExecution = $this->args['functionExecution'];
$functionExecutionTime = $this->args['functionExecutionTime'];
$functionStatus = $this->args['functionStatus'];
$functionExecution = $this->args['functionExecution'] ?? 0;
$functionExecutionTime = $this->args['functionExecutionTime'] ?? 0;
$functionStatus = $this->args['functionStatus'] ?? '';
$tags = ",project={$projectId},version=".App::getEnv('_APP_VERSION', 'UNKNOWN').'';
+5 -28
View File
@@ -2,11 +2,6 @@
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;
require_once __DIR__.'/../init.php';
@@ -24,34 +19,16 @@ class WebhooksV1
public function perform()
{
global $register;
$consoleDB = new Database();
$consoleDB->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register));
$consoleDB->setNamespace('app_console'); // Main DB
$consoleDB->setMocks(Config::getParam('collections', []));
$errors = [];
// Event
$projectId = $this->args['projectId'] ?? '';
$webhooks = $this->args['webhooks'] ?? [];
$userId = $this->args['userId'] ?? '';
$event = $this->args['event'] ?? '';
$payload = \json_encode($this->args['payload']);
$eventData = \json_encode($this->args['eventData']);
// Webhook
Authorization::disable();
$project = $consoleDB->getDocument($projectId);
Authorization::reset();
if (\is_null($project->getId()) || Database::SYSTEM_COLLECTION_PROJECTS !== $project->getCollection()) {
throw new Exception('Project Not Found');
}
foreach ($project->getAttribute('webhooks', []) as $webhook) {
foreach ($webhooks as $webhook) {
if (!(isset($webhook['events']) && \is_array($webhook['events']) && \in_array($event, $webhook['events']))) {
continue;
}
@@ -67,7 +44,7 @@ class WebhooksV1
$ch = \curl_init($url);
\curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
\curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
\curl_setopt($ch, CURLOPT_POSTFIELDS, $eventData);
\curl_setopt($ch, CURLOPT_HEADER, 0);
\curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
\curl_setopt($ch, CURLOPT_USERAGENT, \sprintf(APP_USERAGENT,
@@ -79,7 +56,7 @@ class WebhooksV1
CURLOPT_HTTPHEADER,
[
'Content-Type: application/json',
'Content-Length: '.\strlen($payload),
'Content-Length: '.\strlen($eventData),
'X-'.APP_NAME.'-Webhook-Id: '.$id,
'X-'.APP_NAME.'-Webhook-Event: '.$event,
'X-'.APP_NAME.'-Webhook-Name: '.$name,
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/sh
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ]
then
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
else
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/sh
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ]
then
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
else
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/sh
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ]
then
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
else
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/sh
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ]
then
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
else
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/sh
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ]
then
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
else
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/sh
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ]
then
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
else
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/sh
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ]
then
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
else
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/sh
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ]
then
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
else
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/sh
if [ -z "$_APP_REDIS_USER" ] || [ -z "$_APP_REDIS_PASS" ]
if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ]
then
REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
else
+23 -28
View File
@@ -15,10 +15,13 @@
}
},
"autoload-dev": {
"psr-4": {"Tests\\E2E\\": "tests/e2e"}
"psr-4": {
"Tests\\E2E\\": "tests/e2e",
"Appwrite\\Tests\\": "tests/extensions"
}
},
"require": {
"php": ">=7.4.0",
"php": ">=8.0.0",
"ext-curl": "*",
"ext-imagick": "*",
"ext-mbstring": "*",
@@ -32,52 +35,44 @@
"ext-zlib": "*",
"ext-sockets": "*",
"appwrite/php-clamav": "1.0.*",
"appwrite/php-clamav": "1.1.*",
"appwrite/php-runtimes": "0.2.*",
"utopia-php/framework": "0.10.0",
"utopia-php/abuse": "0.3.*",
"utopia-php/analytics": "0.1.*",
"utopia-php/framework": "0.14.*",
"utopia-php/abuse": "0.4.*",
"utopia-php/analytics": "0.2.*",
"utopia-php/audit": "0.5.*",
"utopia-php/cache": "0.2.*",
"utopia-php/cli": "0.10.0",
"utopia-php/cli": "0.11.*",
"utopia-php/config": "0.2.*",
"utopia-php/locale": "0.3.*",
"utopia-php/registry": "0.2.*",
"utopia-php/registry": "0.4.*",
"utopia-php/preloader": "0.2.*",
"utopia-php/domains": "0.2.*",
"utopia-php/domains": "1.1.*",
"utopia-php/swoole": "0.2.*",
"utopia-php/system": "0.4.*",
"utopia-php/storage": "0.4.*",
"utopia-php/image": "0.1.*",
"utopia-php/storage": "0.5.*",
"utopia-php/image": "0.2.*",
"resque/php-resque": "1.3.6",
"matomo/device-detector": "4.1.0",
"matomo/device-detector": "4.2.2",
"dragonmantank/cron-expression": "3.1.0",
"influxdb/influxdb-php": "1.15.2",
"phpmailer/phpmailer": "6.3.0",
"phpmailer/phpmailer": "6.4.1",
"chillerlan/php-qrcode": "4.3.0",
"adhocore/jwt": "1.1.2",
"slickdeals/statsd": "~3.0"
"slickdeals/statsd": "3.0.2"
},
"require-dev": {
"appwrite/sdk-generator": "0.6.3",
"phpunit/phpunit": "9.4.2",
"swoole/ide-helper": "4.5.5",
"vimeo/psalm": "4.1.1"
"appwrite/sdk-generator": "0.10.6",
"swoole/ide-helper": "4.6.6",
"phpunit/phpunit": "9.5.4",
"vimeo/psalm": "4.7.2"
},
"repositories": [
{
"type": "git",
"url": "https://github.com/appwrite/sdk-generator"
}
],
"provide": {
"ext-phpiredis": "*"
},
"minimum-stability": "dev",
"config": {
"platform": {
"php": "7.4"
"php": "8.0"
}
}
}
Generated
+454 -407
View File
File diff suppressed because it is too large Load Diff
+24 -22
View File
@@ -71,10 +71,14 @@ services:
depends_on:
- mariadb
- redis
- clamav
# - clamav
- influxdb
environment:
- _APP_ENV
- _APP_LOCALE
- _APP_CONSOLE_WHITELIST_ROOT
- _APP_CONSOLE_WHITELIST_EMAILS
- _APP_CONSOLE_WHITELIST_IPS
- _APP_SYSTEM_EMAIL_NAME
- _APP_SYSTEM_EMAIL_ADDRESS
- _APP_SYSTEM_SECURITY_EMAIL_ADDRESS
@@ -110,7 +114,7 @@ services:
- _APP_FUNCTIONS_CPUS
- _APP_FUNCTIONS_MEMORY
- _APP_FUNCTIONS_MEMORY_SWAP
- _APP_FUNCTIONS_ENVS
- _APP_FUNCTIONS_RUNTIMES
appwrite-worker-usage:
entrypoint: worker-usage
@@ -180,11 +184,6 @@ services:
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
appwrite-worker-tasks:
entrypoint: worker-tasks
@@ -201,6 +200,7 @@ services:
- mariadb
environment:
- _APP_ENV
- _APP_OPENSSL_KEY_V1
- _APP_SYSTEM_SECURITY_EMAIL_ADDRESS
- _APP_REDIS_HOST
- _APP_REDIS_PORT
@@ -282,12 +282,12 @@ services:
- /tmp:/tmp:rw
- ./app:/usr/src/code/app
- ./src:/usr/src/code/src
- ./docker:/usr/src/code/docker
depends_on:
- redis
- mariadb
environment:
- _APP_ENV
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
@@ -299,6 +299,7 @@ services:
- _APP_DB_PASS
- _APP_FUNCTIONS_TIMEOUT
- _APP_FUNCTIONS_CONTAINERS
- _APP_FUNCTIONS_RUNTIMES
- _APP_FUNCTIONS_CPUS
- _APP_FUNCTIONS_MEMORY
- _APP_FUNCTIONS_MEMORY_SWAP
@@ -413,16 +414,16 @@ services:
volumes:
- appwrite-redis:/data:rw
clamav:
image: appwrite/clamav:1.2.0
container_name: appwrite-clamav
networks:
- appwrite
volumes:
- appwrite-uploads:/storage/uploads
# clamav:
# image: appwrite/clamav:1.2.0
# container_name: appwrite-clamav
# networks:
# - appwrite
# volumes:
# - appwrite-uploads:/storage/uploads
influxdb:
image: influxdb:1.8-alpine
image: appwrite/influxdb:1.0.0
container_name: appwrite-influxdb
networks:
- appwrite
@@ -430,7 +431,7 @@ services:
- appwrite-influxdb:/var/lib/influxdb:rw
telegraf:
image: appwrite/telegraf:1.0.0
image: appwrite/telegraf:1.1.0
container_name: appwrite-telegraf
networks:
- appwrite
@@ -449,16 +450,16 @@ services:
# Webgrind - A nice UI for exploring and debugging code-level stuff
maildev: # used mainly for dev tests
image: djfarrelly/maildev
container_name: appwrite-maildev
image: appwrite/mailcatcher:1.0.0
container_name: appwrite-mailcatcher
ports:
- '9503:80'
- '9503:1080'
networks:
- appwrite
request-catcher: # used mainly for dev tests
image: smarterdm/http-request-catcher
container_name: appwrite-request-catcher
image: appwrite/requestcatcher:1.0.0
container_name: appwrite-requestcatcher
ports:
- '9504:5000'
networks:
@@ -466,6 +467,7 @@ services:
adminer:
image: adminer
container_name: appwrite-adminer
restart: always
ports:
- 9505:8080
-13
View File
@@ -1,13 +0,0 @@
# Appwrite Functions Environments
Docker based enviornments for Appwrite Functions. You can use this Docker images to locally tests your functions by executing them on your local desktop or server.
All the supported enviornments are based on Docker Alpine images.
## Build
Build envs for all supported cloud functions (multicore builds)
```bash
bash ./docker/environments/build.sh
```
-40
View File
@@ -1,40 +0,0 @@
echo 'Starting build...'
echo 'Deno 1.2...'
docker buildx build --platform linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/386,linux/ppc64le -t appwrite/env-deno-1.2:1.0.0 ./docker/environments/deno-1.2/ --push
echo 'Deno 1.5...'
docker buildx build --platform linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/386,linux/ppc64le -t appwrite/env-deno-1.5:1.0.0 ./docker/environments/deno-1.5/ --push
echo 'Deno 1.6...'
docker buildx build --platform linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/386,linux/ppc64le -t appwrite/env-deno-1.6:1.0.0 ./docker/environments/deno-1.6/ --push
echo 'Node 14.5...'
docker buildx build --platform linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le -t appwrite/env-node-14.5:1.0.0 ./docker/environments/node-14.5/ --push
echo 'Node 15.5...'
docker buildx build --platform linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le -t appwrite/env-node-15.5:1.0.0 ./docker/environments/node-15.5/ --push
echo 'PHP 7.4...'
docker buildx build --platform linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/386,linux/ppc64le -t appwrite/env-php-7.4:1.0.0 ./docker/environments/php-7.4/ --push
echo 'PHP 8.0...'
docker buildx build --platform linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/386,linux/ppc64le -t appwrite/env-php-8.0:1.0.0 ./docker/environments/php-8.0/ --push
echo 'Python 3.8...'
docker buildx build --platform linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/386,linux/ppc64le -t appwrite/env-python-3.8:1.0.0 ./docker/environments/python-3.8/ --push
echo 'Ruby 2.7...'
docker buildx build --platform linux/amd64,linux/arm64,linux/386,linux/ppc64le -t appwrite/env-ruby-2.7:1.0.2 ./docker/environments/ruby-2.7/ --push
echo 'Ruby 3.0...'
docker buildx build --platform linux/amd64,linux/arm64,linux/386,linux/ppc64le -t appwrite/env-ruby-3.0:1.0.0 ./docker/environments/ruby-3.0/ --push
echo 'Dart 2.10...'
docker buildx build --platform linux/amd64 -t appwrite/env-dart-2.10:1.0.0 ./docker/environments/dart-2.10/ --push
echo '.NET 3.1...'
docker buildx build --platform linux/amd64,linux/arm64 -t appwrite/env-dotnet-3.1:1.0.0 ./docker/environments/dotnet-3.1/ --push
echo '.NET 5.0...'
docker buildx build --platform linux/amd64,linux/arm64 -t appwrite/env-dotnet-5.0:1.0.0 ./docker/environments/dotnet-5.0/ --push
-9
View File
@@ -1,9 +0,0 @@
FROM google/dart:2.10
LABEL maintainer="team@appwrite.io"
RUN apt-get update -y && apt-get install -y tar
WORKDIR /usr/local/src/
ENV PUB_CACHE=/usr/local/src/.appwrite
-11
View File
@@ -1,11 +0,0 @@
FROM hayd/deno:alpine-1.2.0
LABEL maintainer="team@appwrite.io"
RUN apk add tar
RUN mkdir /usr/local/src
WORKDIR /usr/local/src/
ENV DENO_DIR=/usr/local/src/.appwrite
-11
View File
@@ -1,11 +0,0 @@
FROM hayd/deno:alpine-1.5.0
LABEL maintainer="team@appwrite.io"
RUN apk add tar
RUN mkdir /usr/local/src
WORKDIR /usr/local/src/
ENV DENO_DIR=/usr/local/src/.appwrite
-11
View File
@@ -1,11 +0,0 @@
FROM hayd/deno:alpine-1.6.2
LABEL maintainer="team@appwrite.io"
RUN apk add tar
RUN mkdir /usr/local/src
WORKDIR /usr/local/src/
ENV DENO_DIR=/usr/local/src/.appwrite
@@ -1,7 +0,0 @@
FROM mcr.microsoft.com/dotnet/runtime:3.1-alpine
LABEL maintainer="team@appwrite.io"
RUN apk add tar
WORKDIR /usr/local/src/
@@ -1,7 +0,0 @@
FROM mcr.microsoft.com/dotnet/runtime:5.0-alpine
LABEL maintainer="team@appwrite.io"
RUN apk add tar
WORKDIR /usr/local/src/
-9
View File
@@ -1,9 +0,0 @@
FROM node:14.5-alpine
LABEL maintainer="team@appwrite.io"
RUN apk add tar
RUN mkdir /usr/local/src
WORKDIR /usr/local/src/
-9
View File
@@ -1,9 +0,0 @@
FROM node:15.5-alpine
LABEL maintainer="team@appwrite.io"
RUN apk add tar
RUN mkdir /usr/local/src
WORKDIR /usr/local/src/
-9
View File
@@ -1,9 +0,0 @@
FROM php:7.4-cli-alpine
LABEL maintainer="team@appwrite.io"
RUN apk add tar
RUN mkdir /usr/local/src
WORKDIR /usr/local/src/
-9
View File
@@ -1,9 +0,0 @@
FROM php:8.0-cli-alpine
LABEL maintainer="team@appwrite.io"
RUN apk add tar
RUN mkdir /usr/local/src
WORKDIR /usr/local/src/
-11
View File
@@ -1,11 +0,0 @@
FROM python:3.8-alpine
LABEL maintainer="team@appwrite.io"
RUN apk add tar
RUN mkdir /usr/local/src
WORKDIR /usr/local/src/
ENV PYTHONPATH "${PYTHONPATH}:/usr/local/src/.appwrite"
-12
View File
@@ -1,12 +0,0 @@
FROM ruby:2.7-alpine
LABEL maintainer="team@appwrite.io"
RUN apk add tar
RUN mkdir /usr/local/src
WORKDIR /usr/local/src/
ENV GEM_PATH=/usr/local/src/.appwrite
ENV GEM_SPEC_CACHE=/usr/local/src/.appwrite/specs
-12
View File
@@ -1,12 +0,0 @@
FROM ruby:3.0-alpine
LABEL maintainer="team@appwrite.io"
RUN apk add tar
RUN mkdir /usr/local/src
WORKDIR /usr/local/src/
ENV GEM_PATH=/usr/local/src/.appwrite
ENV GEM_SPEC_CACHE=/usr/local/src/.appwrite/specs
@@ -0,0 +1,15 @@
let sdk = new Appwrite();
sdk
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.updateAuthLimit('[PROJECT_ID]', '');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});
@@ -0,0 +1,15 @@
let sdk = new Appwrite();
sdk
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
;
let promise = sdk.projects.updateAuthStatus('[PROJECT_ID]', 'email-password', false);
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});
@@ -1 +1 @@
appwrite database createCollection --name="[NAME]" "--read[]=" "--write[]=" "--rules[]="
appwrite database createCollection --name="[NAME]" --read="" --write="" --rules=""
@@ -1 +1 @@
appwrite database createDocument --collectionId="[COLLECTION_ID]" --data="{}" "--read[]=" "--write[]=" --parentDocument="[PARENT_DOCUMENT]" --parentProperty="" --parentPropertyType="assign"
appwrite database createDocument --collectionId="[COLLECTION_ID]" --data="{}" --read="" --write="" --parentDocument="[PARENT_DOCUMENT]" --parentProperty="" --parentPropertyType="assign"
@@ -1 +1 @@
appwrite database listDocuments --collectionId="[COLLECTION_ID]" "--filters[]=" --limit="0" --offset="0" --orderField="[ORDER_FIELD]" --orderType="DESC" --orderCast="int" --search="[SEARCH]"
appwrite database listDocuments --collectionId="[COLLECTION_ID]" --filters="" --limit="0" --offset="0" --orderField="[ORDER_FIELD]" --orderType="DESC" --orderCast="int" --search="[SEARCH]"

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