Compare commits

...
Author SHA1 Message Date
fogelito 4d670bb47d Remove use 2025-07-20 12:06:23 +03:00
fogelito a9e53a46a6 formatting 2025-07-20 12:04:55 +03:00
fogelito e2797ab9d4 Disable index array 2025-07-20 11:57:43 +03:00
Steven NguyenandGitHub 8b90acd8c6 Merge pull request #10164 from appwrite/improve-scheme-error
chore: improve invalid scheme error in origin check
2025-07-19 07:16:20 -07:00
Chirag Aggarwal 7fecfc73ca fix: formatting 2025-07-19 10:39:39 +05:30
Chirag Aggarwal c55f039f13 chore: add unit test 2025-07-18 22:23:33 +05:30
Chirag Aggarwal d613237fb4 chore: improve invalid scheme error in origin check 2025-07-18 22:08:43 +05:30
Steven NguyenandGitHub 5742dad1e4 Merge pull request #10161 from appwrite/update-dart-flutter
chore: update dart 16.1.0, flutter 17.0.2 and cli 8.2.2
2025-07-18 08:49:34 -07:00
Chirag Aggarwal ea0654cf5e improve naming 2025-07-18 17:16:01 +05:30
Chirag Aggarwal 99ea9c5d80 chore: update cli to 8.2.2 2025-07-18 17:10:20 +05:30
Chirag Aggarwal 712425c383 fix: version 2025-07-18 15:59:09 +05:30
Chirag Aggarwal 0cc443b47c fix: branch name 2025-07-18 15:56:12 +05:30
Chirag Aggarwal c729a84d51 chore: update dart to 16.1.0 and flutter to 17.0.2 2025-07-18 15:55:11 +05:30
Jake BarnbyandGitHub 33435890dd Merge pull request #10158 from appwrite/fix-redirect-specs
Handle redirect validator in specs + GraphQL type mapper
2025-07-18 12:19:22 +12:00
Jake Barnby 0a5fbb7bc7 Handle redirect validator in specs + GraphQL type mapper 2025-07-18 11:59:32 +12:00
Matej BačoandGitHub 1e61091834 Merge pull request #10157 from appwrite/fix-build-usage-specification
fix: build usage specification
2025-07-17 15:33:38 +02:00
loks0n 94decb26e6 fix: build usage specification 2025-07-17 14:05:05 +01:00
Matej BačoandGitHub a3f9707938 Merge pull request #10155 from appwrite/update-cli-8.2.1
Update cli 8.2.1
2025-07-17 11:55:14 +02:00
Chirag Aggarwal 0a82b6d30d chore: update CLI to 8.2.1 2025-07-17 11:44:30 +05:30
Damodar LohaniandGitHub 0f38bb689f Merge pull request #10138 from appwrite/update-react-native-0.10.1
chore: update react native to 0.10.1 and dotnet to 0.14.0
2025-07-15 10:39:30 +05:45
Steven NguyenandGitHub 00889426de Merge pull request #10150 from appwrite/fix-apple-oauth
fix: prevent injected $user from being shadowed
2025-07-14 21:29:16 -07:00
Steven Nguyen 477682e062 fix: prevent injected $user from being shadowed 2025-07-14 16:05:58 -07:00
Chirag Aggarwal 054b6a995a update dotnet to 0.14.0 2025-07-14 08:54:37 +05:30
Chirag Aggarwal a2ca08023d chore: update composer 2025-07-12 12:18:11 +05:30
Chirag Aggarwal 8a2e0d4970 chore: update react native to 0.10.1 and changelog 2025-07-12 12:04:51 +05:30
Matej BačoandGitHub 51d07832f7 Merge pull request #10136 from appwrite/update-cli-8.2.0
chore: update cli to 8.2.0
2025-07-11 16:39:13 +02:00
Matej BačoandGitHub 8c57d28f8f Merge pull request #10127 from appwrite/chore-speed-up-tests
Chore: speed up tests
2025-07-11 16:21:40 +02:00
Matej Bačo 0bdb64fc77 Fix migration tests 2025-07-11 15:54:53 +02:00
Chirag Aggarwal 32cb5e0a79 chore: update cli to 8.2.0 2025-07-11 16:31:50 +05:30
Matej BačoandGitHub e24671f6f4 Merge pull request #10135 from appwrite/fix-staging-specs
Fix: specs with new env vars
2025-07-11 12:08:21 +02:00
Matej Bačo 9bab764378 Fix specs with new env vars 2025-07-11 11:15:55 +02:00
Steven NguyenandGitHub fd35043dd7 Merge pull request #10119 from appwrite/fix-mobile-oauth2-redirect
fix: update OAuth2 redirect URLs
2025-07-10 16:46:58 -07:00
Steven Nguyen 100aea337f fix: update OAuth2 redirect URLs
1. handle non-standard ports if the request came in on a non-standard port
2. use the _APP_CONSOLE_DOMAIN env var to handle cases where the Console domain may not be the endpoint domain such as on Appwrite Cloud
3. use the _APP_OPTIONS_FORCE_HTTPS env var to determine the protocol to be consistent with the rest of the codebase
2025-07-10 15:51:13 -07:00
Steven NguyenandGitHub 435a319fb6 Merge pull request #10130 from appwrite/fix-oauth2-redirect-validation
fix: success validation in oauth2 redirect
2025-07-10 09:06:43 -07:00
Matej Bačo 18492ab917 Revert unwanted change 2025-07-10 16:16:06 +02:00
Matej Bačo 89d54f847f Speed up build cancellation 2025-07-10 15:52:29 +02:00
Matej Bačo 6dc6ff6ba0 Fix formatting 2025-07-10 14:44:44 +02:00
Matej Bačo 581235f972 Fix more tests 2025-07-10 14:43:56 +02:00
Matej Bačo f02ba4c976 Fix function tests 2025-07-10 14:25:53 +02:00
Matej Bačo eaf9b8b228 Migrate remaining tests to node 2025-07-10 12:55:45 +02:00
Steven Nguyen 11332ed1f9 chore: fix deprecation warning from passing null into json_decode 2025-07-09 22:10:17 -07:00
Steven Nguyen 990e1b91bb fix: omit : and @ if user and pass are empty
So, unparsing should not end up with https://:@appwrite.io just because user and pass are empty strings.
2025-07-09 22:09:18 -07:00
Steven Nguyen f202685450 fix: handle parsing URL that is only a scheme
In react native, a redirect URL may only be a url scheme such as appwrite-callback-myproject://. Since parse_url() fails on this type of URL, we need to add this workaround.
2025-07-09 22:01:38 -07:00
Steven NguyenandGitHub 9b90d8030e Merge pull request #10129 from appwrite/dat-579
Changed the default permission param of upsert document
2025-07-09 20:44:36 -07:00
Steven Nguyen 53086fe975 fix: success validation in oauth2 redirect
We switched to using the Redirect class for validating redirect URLs to cover additional cases like react native expo scheme, but we missed this validation.
2025-07-09 15:11:30 -07:00
ArnabChatterjee20k 1d9aac5a49 updated upsert document test with api key 2025-07-09 23:57:39 +05:30
ArnabChatterjee20k ca61b528b9 reverted the api signature and started handling it internally 2025-07-09 23:49:56 +05:30
ArnabChatterjee20k 50109b833a removed tests for the upsert without permissions for passing the tests 2025-07-09 21:49:07 +05:30
Matej Bačo 5ace34790d Migrate many tests to JS 2025-07-09 16:58:55 +02:00
Matej Bačo 1a3f8bbd48 quality fixes 2025-07-09 14:29:36 +02:00
Matej BačoandGitHub 41fc925103 Merge branch '1.7.x' into chore-speed-up-tests 2025-07-09 13:47:33 +02:00
Matej BačoandGitHub a756e533e8 Merge pull request #10128 from appwrite/reduce-delete-batch-size
Reduce delete batch size
2025-07-09 13:46:03 +02:00
Matej BačoandGitHub 449b9295fd Update src/Appwrite/Platform/Workers/Deletes.php 2025-07-09 13:42:18 +02:00
fogelito 3a298b7a21 Change to 500 2025-07-09 14:32:47 +03:00
ArnabChatterjee20k 13bd2341c0 empty commit to trigger tests 2025-07-09 17:02:44 +05:30
ArnabChatterjee20k c36720e3b0 updated param of permissiosns in upsert and updated tests for upsert without permissions 2025-07-09 16:37:41 +05:30
fogelito 9cc61d89f0 $deleteBatchSize 2025-07-09 14:00:08 +03:00
Matej BačoandGitHub cc1129a7b9 Merge pull request #9952 from appwrite/fix-build-activation-race-condition
Fix build activation race condition
2025-07-09 11:59:40 +02:00
Matej Bačo e42275e0b7 Minify tests 2025-07-09 11:26:05 +02:00
Matej Bačo 26496e68c4 Attempt to simplify code 2025-07-08 14:51:28 +02:00
Khushboo VermaandGitHub f7cbe5b961 Merge branch '1.7.x' into fix-build-activation-race-condition 2025-07-08 17:53:12 +05:30
Khushboo Verma bd63f0cf3d Remove empty check 2025-07-08 17:46:54 +05:30
Khushboo Verma bc9caeaae0 Use ruleId 2025-07-08 17:45:45 +05:30
Khushboo Verma a5a1860ba6 Use createdAt instead of buildStartTime 2025-07-08 17:42:23 +05:30
Khushboo Verma 9d7e218e99 Save result of updateDocument 2025-07-08 17:12:35 +05:30
Matej BačoandGitHub 6d321f6988 Merge pull request #10120 from appwrite/fix-file-tokens
Fix file tokens not working on file-security
2025-07-08 13:41:10 +02:00
Khushboo Verma 61a27bfe55 Simplify auto-activation logic and just update attributes 2025-07-08 16:30:43 +05:30
Darshan 7ca951ed81 remove: {} 2025-07-08 15:43:51 +05:30
Darshan 020814e672 update: inline guest headers. 2025-07-08 15:43:28 +05:30
Darshan 7ea896301f update: test to include preview, view and download with file-security. 2025-07-08 15:42:38 +05:30
Darshan 97d5f0f030 add: e2e. 2025-07-08 15:34:52 +05:30
Darshan 14e52058c7 fix: file tokens not working on file-security. 2025-07-08 13:46:53 +05:30
Khushboo Verma 067b53482f Fix bug 2025-07-08 01:02:55 +05:30
Khushboo Verma 1a286ad3f4 Revert replica changes 2025-07-08 00:53:10 +05:30
Khushboo Verma 80c4982482 Update only specific attribute 2025-07-08 00:51:35 +05:30
Khushboo Verma a23c99ad7a Merge branch 'fix-build-activation-race-condition' of github.com:appwrite/appwrite into fix-build-activation-race-condition 2025-07-07 12:37:06 +05:30
Khushboo Verma ea238bc5ec Fix merge conflicts 2025-07-07 12:36:42 +05:30
Damodar LohaniandGitHub edd7a4ac42 Merge pull request #10088 from appwrite/update-nodejs-17.1.0
Update nodejs 17.1.0
2025-07-07 11:14:25 +05:45
Chirag AggarwalandGitHub f678add130 Merge branch '1.7.x' into update-nodejs-17.1.0 2025-07-07 10:39:56 +05:30
Steven NguyenandGitHub 543b872f60 Merge pull request #10107 from appwrite/fix-origin-validation-extensions
fix: origin validation for web extensions
2025-07-06 14:53:56 -07:00
Chirag Aggarwal 5fffae39d4 chore: update naming and add tests 2025-07-05 17:59:01 +05:30
Chirag Aggarwal 9dcb80649f fix: extension for safari 2025-07-05 10:18:40 +05:30
Chirag Aggarwal 18d30c48d5 fix: add missing check for hostname 2025-07-05 10:15:18 +05:30
Chirag Aggarwal 0fb55f6312 fix: origin validation for web extensions 2025-07-05 07:59:52 +05:30
Matej BačoandGitHub 1cf9963bb6 Merge pull request #10104 from appwrite/chore-fix-site-template-test
Fix site template test
2025-07-04 15:17:09 +02:00
Khushboo Verma 2545977d47 Fix site template test 2025-07-04 17:46:21 +05:30
Torsten DittmannandGitHub dbadfa7bf8 Merge pull request #9650 from appwrite/feat-exp-scheme
feat: exp scheme
2025-07-04 14:09:54 +02:00
Chirag Aggarwal 37c7411405 Trigger Build 2025-07-04 16:51:30 +05:30
Chirag Aggarwal bc8b10a69e fix: origin tests 2025-07-04 16:46:14 +05:30
Chirag Aggarwal 7bbf58d0dd update cli 2025-07-04 15:31:52 +05:30
Chirag AggarwalandGitHub df9ef1ace9 Merge branch '1.7.x' into feat-exp-scheme 2025-07-04 15:22:44 +05:30
Matej BačoandGitHub 32903d9a81 Merge pull request #9999 from appwrite/chore-update-env-var-used-for-domain
Use _APP_CONSOLE_DOMAIN, if not found, then use _APP_DOMAIN
2025-07-04 09:41:42 +02:00
Khushboo VermaandGitHub 131cdefac5 Merge branch '1.7.x' into chore-update-env-var-used-for-domain 2025-07-04 10:40:38 +05:30
Chirag AggarwalandGitHub 231225ee10 Merge branch '1.7.x' into update-nodejs-17.1.0 2025-07-04 09:37:51 +05:30
Jake BarnbyandGitHub d205ac4579 Merge pull request #10099 from appwrite/feat-redis-publisher-scheduler
Add redis publisher to schedule base if available
2025-07-03 18:49:25 +00:00
Jake Barnby 5bb998b02d Add API + CLI stubs 2025-07-03 14:24:40 -04:00
Jake Barnby 7d37f5b066 Lint 2025-07-03 14:18:19 -04:00
Jake Barnby 2a73dddbdb Fix health 2025-07-03 14:09:08 -04:00
Jake Barnby f224c09c10 Use correct publisher in schedule tasks 2025-07-03 14:08:54 -04:00
Jake Barnby 6725b31b65 Add redis publisher to schedule base if available 2025-07-03 13:55:13 -04:00
Chirag AggarwalandGitHub e721a9f11c Merge branch '1.7.x' into feat-exp-scheme 2025-07-03 22:40:46 +05:30
Chirag Aggarwal 72f08e281b chore: make check consistent 2025-07-03 22:39:12 +05:30
Chirag Aggarwal 431a26e151 chore: removing loggin 2025-07-03 22:37:31 +05:30
Chirag Aggarwal 172ba84ec8 chore: add logging 2025-07-03 22:25:46 +05:30
Torsten DittmannandGitHub 7c0216c592 Merge pull request #10098 from appwrite/fix/jwt-auth-db-admin-mode
fix: JWT authentication database selection for admin mode
2025-07-03 18:29:54 +02:00
Chirag Aggarwal b6f11144b8 chore: popular schemes 2025-07-03 21:39:23 +05:30
Ariel WeinbergerandGitHub 199b9f7e6d fix nitpick 2025-07-03 11:06:36 -05:00
Ariel WeinbergerandGitHub d9486f38c4 fix: jwt auth database selection for admin mode
Use dbForPlatform for JWT user lookup in admin mode
2025-07-03 10:54:51 -05:00
Chirag Aggarwal 4747700eae chore: add logging 2025-07-03 21:17:43 +05:30
Chirag Aggarwal 58c2f55d1c fix: revert to main 2025-07-03 18:51:50 +05:30
Chirag Aggarwal 2cf7246c7a fix: changelog 2025-07-03 18:15:50 +05:30
Chirag Aggarwal dd9096fd2b fix: lint 2025-07-03 18:04:28 +05:30
Chirag Aggarwal 60158aec0c chore: update cli to 8.1.1 as well 2025-07-03 18:02:40 +05:30
Chirag Aggarwal bb9a271fa8 chore: add scheme validation 2025-07-03 16:39:41 +05:30
Chirag AggarwalandGitHub ef2dfb6cca Merge branch '1.7.x' into feat-exp-scheme 2025-07-03 16:37:17 +05:30
Chirag Aggarwal f62c3135df add null check for platform 2025-07-03 16:26:56 +05:30
Khushboo VermaandGitHub 642d046d65 Merge branch '1.7.x' into chore-update-env-var-used-for-domain 2025-07-03 00:38:33 +05:30
Jake BarnbyandGitHub d38b25e0b1 Merge pull request #10090 from appwrite/csv-fix
Fix: path and type
2025-07-02 19:04:00 +00:00
Khushboo Verma 9064fcc24e Merge branch 'chore-update-env-var-used-for-domain' of github.com:appwrite/appwrite into chore-update-env-var-used-for-domain 2025-07-03 00:08:58 +05:30
Khushboo Verma 0f37a0e0ef Fix tests 2025-07-03 00:08:29 +05:30
Khushboo Verma 253195698e Merge branch '1.7.x' into chore-update-env-var-used-for-domain 2025-07-03 00:02:51 +05:30
Jake Barnby 55dc965dd6 Update lib 2025-07-02 14:32:05 -04:00
Jake Barnby 2ce3118ba9 Remove path update 2025-07-02 13:36:46 -04:00
Jake Barnby ce8ae2294a Update lock 2025-07-02 12:58:37 -04:00
Jake Barnby b1724e9c9d Update lock 2025-07-02 10:40:35 -04:00
Darshan ed2d12f896 update: full path on appwrite. 2025-07-02 19:55:42 +05:30
Darshan 6f5d3d53c0 bump: for tests. 2025-07-02 19:51:36 +05:30
Darshan 6d792fcb6c revert: lock. 2025-07-02 19:20:30 +05:30
Darshan fc1a9a4e16 fix: path and revert deps. 2025-07-02 19:13:13 +05:30
Darshan 0e50fb7ec5 add: migrations lib logging for errors. 2025-07-02 17:04:26 +05:30
Darshan d34635becb add: logging for errors. 2025-07-02 15:13:42 +05:30
Darshan eb1d4c68ea add: logging. 2025-07-02 14:54:25 +05:30
Darshan beec2e780d Merge branch '1.7.x' into csv-fix 2025-07-02 14:35:38 +05:30
Darshan aa9a82d8ce fix: document attribute type. 2025-07-02 14:32:16 +05:30
Chirag Aggarwal 421510f847 chore: update nodejs to 17.1.0 2025-07-02 11:01:25 +05:30
Jake BarnbyandGitHub 49a5e01a53 Merge pull request #10086 from appwrite/revert-10051-chore-upgrade-utopia-queue
Revert "chore: update composer.json and composer.lock to include appwrite-lab…"
2025-07-01 22:44:59 +00:00
Jake Barnby 1cd69e26f8 Reapply "chore: update composer.json and composer.lock to include appwrite-lab…"
This reverts commit 99ccd64b4c.
2025-07-01 18:24:52 -04:00
Jake BarnbyandGitHub 99ccd64b4c Revert "chore: update composer.json and composer.lock to include appwrite-lab…" 2025-07-01 18:24:05 -04:00
Jake BarnbyandGitHub aa03045382 Merge pull request #10085 from appwrite/fix-tests
Fix tests, for `Cloud`
2025-07-01 14:28:23 +00:00
Darshan 4d0bd1d74f add: delay, retries. 2025-07-01 18:10:19 +05:30
Darshan 385e4e14b8 add: delay, retries. 2025-07-01 17:33:11 +05:30
Matej BačoandGitHub 67bdf8ffdc Merge pull request #10034 from appwrite/fix-push-to-existing-repo
Fix connect to existing repo flow
2025-07-01 12:11:48 +02:00
Khushboo VermaandGitHub 3fa04727c7 Merge branch '1.7.x' into fix-push-to-existing-repo 2025-07-01 14:47:52 +05:30
Khushboo VermaandGitHub 2da811956c Merge branch '1.7.x' into chore-update-env-var-used-for-domain 2025-07-01 12:22:36 +05:30
Khushboo VermaandGitHub 8ef24cb2a9 Merge branch '1.7.x' into fix-build-activation-race-condition 2025-07-01 12:22:17 +05:30
Jake BarnbyandGitHub e561a38524 Merge pull request #10051 from appwrite/chore-upgrade-utopia-queue
chore: update composer.json and composer.lock to include appwrite-lab…
2025-07-01 02:51:31 +00:00
Jake Barnby a1af742c4b Update lock 2025-06-30 22:28:09 -04:00
Jake Barnby 98dccf6d15 Map null on missing default 2025-06-30 22:27:29 -04:00
Jake Barnby 609e1adcf0 Catch 2025-06-30 22:27:18 -04:00
Jake Barnby 72cd501f21 Merge remote-tracking branch 'origin/1.7.x' into chore-upgrade-utopia-queue 2025-06-30 21:01:47 -04:00
Khushboo Verma 58c1e2d6e2 Merge branch '1.7.x' into chore-update-env-var-used-for-domain 2025-07-01 02:29:08 +05:30
Khushboo Verma ddb5c52e7c Resolve merge conflicts 2025-07-01 02:25:38 +05:30
Khushboo Verma 5959457211 Merge branch '1.7.x' into fix-push-to-existing-repo 2025-07-01 01:24:45 +05:30
Steven NguyenandGitHub beb8e17013 Merge pull request #10079 from appwrite/chore-patch-cache-miss
patch: increase cache ttl to ensure hits
2025-06-30 12:04:45 -07:00
Christy JacobandGitHub 448a8df1a2 Merge branch '1.7.x' into chore-patch-cache-miss 2025-06-30 21:12:46 +04:00
Christy Jacob fd7628efe8 refactor: streamline cache handling in App::shutdown() and ensure file modification time updates 2025-06-30 21:03:30 +04:00
Christy Jacob d6326758a8 patch: increase cache ttl to ensure hits 2025-06-30 20:58:00 +04:00
Chirag Aggarwal 2d00052db6 fix: general test 2025-06-30 20:50:29 +05:30
Chirag Aggarwal db56361ad9 fix: add back empty checks 2025-06-30 19:48:05 +05:30
Chirag Aggarwal 843d4d9ea0 chore: use origin validator 2025-06-30 19:29:42 +05:30
Chirag Aggarwal 8a2ccd32b4 fix: remove redundant check 2025-06-30 19:09:15 +05:30
Chirag Aggarwal 39db3a3066 fix: order 2025-06-30 19:07:49 +05:30
Chirag Aggarwal 9242ef85eb fix: order 2025-06-30 19:03:12 +05:30
Chirag Aggarwal 332c82e61e fix: lint 2025-06-30 19:00:54 +05:30
Chirag Aggarwal bfee98ca87 Merge branch '1.7.x' into feat-exp-scheme 2025-06-30 18:38:25 +05:30
Matej BačoandGitHub 36aa22793f Merge pull request #10043 from appwrite/fix-rules-platform-check
Fix: Platform check for Sites with automatic rule
2025-06-30 14:10:14 +02:00
Khushboo Verma ae72688c8e Merge branch '1.7.x' into fix-push-to-existing-repo 2025-06-30 15:45:54 +05:30
Christy Jacob 63a02e11ac Fix default value assignment in Mapper class to handle null cases 2025-06-27 18:42:02 +04:00
Matej Bačo ba7903af55 Merge branch '1.7.x' into fix-rules-platform-check 2025-06-27 12:46:06 +02:00
Christy JacobandGitHub cb19798284 Merge pull request #10070 from appwrite/update-cli-8.1.0
chore: update cli to 8.1.0 and add changelog
2025-06-27 14:26:32 +04:00
Chirag Aggarwal 156daca044 fix: composer 2025-06-27 15:50:32 +05:30
Chirag Aggarwal f056a8ba2f fix: composer 2025-06-27 15:49:08 +05:30
Chirag Aggarwal 151711aba9 Merge branch '1.7.x' into update-cli-8.1.0 2025-06-27 15:48:33 +05:30
Christy Jacob 14a4bb8828 Merge branch 'chore-upgrade-utopia-queue' of github.com:appwrite/appwrite into chore-upgrade-utopia-queue 2025-06-27 13:42:17 +04:00
Christy Jacob a36525373d Merge branch '1.7.x' of github.com:appwrite/appwrite into chore-upgrade-utopia-queue 2025-06-27 13:37:33 +04:00
Chirag Aggarwal 5a48fd6300 chore: update cli to 8.1.0 and add changelog 2025-06-27 11:43:56 +05:30
Chirag AggarwalandGitHub 8027251224 Merge branch '1.7.x' into feat-exp-scheme 2025-06-27 09:21:27 +05:30
Chirag Aggarwal fffdab23f9 chore: update scheme check 2025-06-27 08:29:13 +05:30
Matej BačoandGitHub 718cefdd94 Merge pull request #10066 from appwrite/fix-account-test-flakyness
Fix: flakyness of account tests
2025-06-26 22:18:00 +02:00
Matej Bačo ee225834d9 Fix default param syntax 2025-06-26 21:39:00 +02:00
Matej Bačo 23f350c7d1 Merge branch '1.7.x' into fix-account-test-flakyness 2025-06-26 21:33:09 +02:00
Matej Bačo b12ea0b3b1 Fix merge conflict bug 2025-06-26 21:22:38 +02:00
Matej BačoandGitHub 3a8dafe763 Merge branch '1.7.x' into fix-account-test-flakyness 2025-06-26 21:21:52 +02:00
Matej BačoandGitHub 42a0d64137 Merge pull request #10068 from appwrite/chore-preview-logging
Chore: Preview endpoint logging
2025-06-26 20:53:30 +02:00
Matej Bačo df902d2624 Fix account tests using old token 2025-06-26 20:47:59 +02:00
Matej Bačo a356e86ced Add previe wendpoint logging 2025-06-26 20:17:26 +02:00
Matej Bačo bda9adc52e Fix sms mock endpoint 2025-06-26 20:04:56 +02:00
Matej Bačo 8dcc3c4981 Merge branch '1.7.x' into fix-account-test-flakyness 2025-06-26 19:26:23 +02:00
Christy JacobandGitHub 368f928fa9 Merge pull request #10067 from appwrite/fix-parameter-order
fix: correct parameter order in action function for robots.txt route
2025-06-26 21:05:12 +04:00
Christy Jacob ee2796f870 fix: correct parameter order in action function for robots.txt route 2025-06-26 20:49:52 +04:00
Matej BačoandGitHub d4b53175dc Update tests/e2e/Scopes/Scope.php 2025-06-26 18:33:22 +02:00
Matej Bačo 572ff06f53 Fix robots.txt 5xx error 2025-06-26 18:32:03 +02:00
Matej Bačo 87c100db28 Improve General tests logging 2025-06-26 18:09:07 +02:00
Matej Bačo 918ad8979d Fix flakyness of account tests 2025-06-26 18:07:59 +02:00
Matej BačoandGitHub 2fa3ca27af Merge pull request #10052 from appwrite/fix-logs-order
Fix: logs order
2025-06-26 16:32:35 +02:00
Chirag Aggarwal 1555abcbd6 chore: use lowercase for check 2025-06-26 19:59:58 +05:30
Chirag Aggarwal f8e74d073a chore: fix scheme check, remove logging 2025-06-26 19:48:57 +05:30
Chirag Aggarwal be40f1cbe3 chore: remove check for scheme 2025-06-26 19:44:41 +05:30
Chirag Aggarwal 043cead66b chore: fix logging 2025-06-26 19:32:15 +05:30
Chirag Aggarwal 7e378a3a1e chore: more logging 2025-06-26 19:10:35 +05:30
Chirag Aggarwal e13089b1ce chore: more logging 2025-06-26 19:09:14 +05:30
Chirag Aggarwal 9861f60666 chore: add logging 2025-06-26 18:55:51 +05:30
Chirag Aggarwal 06ce606ac7 Merge branch '1.7.x' into feat-exp-scheme 2025-06-26 18:38:10 +05:30
Christy JacobandGitHub 1dfba85bcc Merge pull request #10054 from appwrite/chore-fix-tasks
refactor: replace Console loop with Swoole Timer for stats resource m…
2025-06-26 15:12:05 +04:00
Christy Jacob 204b00850d Refactor log message documentation in Action class to improve clarity and formatting 2025-06-26 15:09:57 +04:00
Christy JacobGitHubcoderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
5761320bfb Update src/Appwrite/Platform/Action.php
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-06-26 15:05:55 +04:00
Christy Jacob dbc7e5b42d Fix output format flag in benchmark workflow for consistency 2025-06-26 15:05:10 +04:00
Christy JacobandGitHub 22900e3de8 Merge pull request #10061 from appwrite/fix-missing-injections
Add: missing injections
2025-06-26 13:24:08 +04:00
Matej BačoandGitHub e5621f3218 Merge pull request #10062 from appwrite/add-runtimeEntrypoint
chore: add runtimeEntrypoint param
2025-06-26 10:29:21 +02:00
Chirag Aggarwal 276a294391 chore: update createExecution 2025-06-26 13:37:43 +05:30
Chirag Aggarwal 8bf3a8bf5d chore: add runtimeEntrypoint param 2025-06-26 13:29:06 +05:30
Darshan 72956d1995 fix: misaligned param order. 2025-06-26 13:07:11 +05:30
Darshan 038b5d7418 fix: lint. 2025-06-26 12:40:56 +05:30
Darshan 8f5b53d16c revert: composer.lock. 2025-06-26 12:36:37 +05:30
Darshan d2753bd491 add: missing injections. 2025-06-26 12:34:38 +05:30
Jake Barnby 921b2bcc5d Merge remote-tracking branch 'origin/1.7.x' into chore-upgrade-utopia-queue 2025-06-25 18:58:08 -04:00
Jake BarnbyandGitHub e8982e6b11 Merge pull request #10056 from appwrite/feat-update-logging
Add database worker job logging
2025-06-25 17:59:59 -04:00
Jake Barnby 7508a22ddf Lint 2025-06-25 16:49:12 -04:00
Jake Barnby 620266d9d6 Remove heartbeat 2025-06-25 16:40:02 -04:00
Jake Barnby f0ea206f29 Fix bench 2025-06-25 15:56:07 -04:00
Jake Barnby d52d8f7697 Fix API dump 2025-06-25 15:47:57 -04:00
Jake Barnby 255be3babf Ensure heartbeat is cleared on destruct 2025-06-25 14:52:14 -04:00
Jake Barnby e37cea5146 Add more trigger logging 2025-06-25 14:50:29 -04:00
Jake Barnby d7d7fa3096 Add trigger logging 2025-06-25 14:47:23 -04:00
Jake Barnby 92a04535ac Add database worker job logging 2025-06-25 14:35:17 -04:00
Christy Jacob c479a11850 Add logging functionality to Action class with dump method and refactor disableSubqueries to use class filters 2025-06-25 21:56:30 +04:00
Christy Jacob 3cd31e2c06 Add disableSubqueries method to Action class and integrate it into StatsResources initialization 2025-06-25 21:46:15 +04:00
Christy Jacob 5173e03636 Merge branch '1.7.x' of github.com:appwrite/appwrite into chore-fix-tasks 2025-06-25 21:33:30 +04:00
Christy JacobandGitHub 3fae6ae91c Merge pull request #10011 from appwrite/PLA-3018
Override project via custom domains log
2025-06-25 19:49:26 +04:00
shimon 19152f50dc Merge branch '1.7.x' of github.com:appwrite/appwrite into PLA-3018
# Conflicts:
#	.github/workflows/benchmark.yml
2025-06-25 18:48:53 +03:00
Matej BačoandGitHub bfbcd648f1 Merge pull request #9967 from appwrite/feat-use-first-class-callable-syntax
Use ->action(...)) instead of ->callback([$this, 'action']);
2025-06-25 17:13:50 +02:00
Matej BačoandGitHub f07abce6f8 Merge branch '1.7.x' into feat-use-first-class-callable-syntax 2025-06-25 16:46:30 +02:00
Matej BačoandGitHub 975f653e3e Merge pull request #9969 from appwrite/feat-add-branch-url-for-first-git-deployment
Create commit & branch url for first git deployment when site is linked to repo
2025-06-25 16:45:41 +02:00
Matej Bačo c85cfe132e Improve flaky tests logging 2025-06-25 15:53:59 +02:00
Matej Bačo 4fff9b94f8 Fix benchmark param name 2025-06-25 14:45:58 +02:00
Matej Bačo 4b5fa0652a Merge branch '1.7.x' into fix-rules-platform-check 2025-06-25 14:44:52 +02:00
Matej Bačo f1590652cb Improve benchmark logging 2025-06-25 14:30:50 +02:00
Matej Bačo df82340dae Improve code quality 2025-06-25 14:22:55 +02:00
Matej Bačo 56347e42df Fix syntax bug 2025-06-25 14:20:20 +02:00
Matej Bačo 6cb3e35c64 Merge branch '1.7.x' into fix-logs-order 2025-06-25 13:41:49 +02:00
Matej BačoandGitHub 213cbf055a Merge pull request #10053 from appwrite/fix-build-duration
Fix: build duration calculation
2025-06-25 13:41:24 +02:00
Matej BačoandGitHub f394f3de62 Merge pull request #10055 from appwrite/chore-fix-benchmark-ci
chore: fix benchmark CI
2025-06-25 13:36:11 +02:00
Christy Jacob 93651c776e chore: fix benchmark CI 2025-06-25 15:32:19 +04:00
Christy Jacob 347f035105 chore: fix benchmark CI 2025-06-25 15:27:51 +04:00
Matej Bačo b6d4baf4dc Fix tests 2025-06-25 13:14:08 +02:00
Christy Jacob c268b632fb chore: update benchmark command to use JSON output format and adjust timer interval in StatsResources 2025-06-25 14:52:13 +04:00
Christy Jacob 17428ef433 refactor: replace Console loop with Swoole Timer for stats resource management 2025-06-25 14:18:22 +04:00
Matej Bačo 4b1966997b Fix build duration calculation 2025-06-25 10:30:07 +02:00
shimon e712ba5763 Merge branch '1.7.x' of github.com:appwrite/appwrite into PLA-3018 2025-06-25 10:18:07 +03:00
Chirag Aggarwal 1a9664a679 chore: fix benchmark 2025-06-25 11:43:18 +05:30
Chirag Aggarwal 65b5af1b00 chore: fix tests 2025-06-25 11:27:23 +05:30
Chirag Aggarwal 6dda6e1fda chore: remove console log 2025-06-25 11:25:39 +05:30
Chirag Aggarwal c331a3caae chore: minor fixes 2025-06-25 11:00:07 +05:30
Chirag Aggarwal dbc58655b2 Merge branch '1.7.x' into feat-exp-scheme 2025-06-25 07:53:28 +05:30
Christy Jacob b646eb7758 chore: update composer.json and composer.lock to upgrade utopia-php/queue to version 0.12.0 and appwrite-labs/php-amqplib to version 0.1.1 2025-06-25 00:23:21 +04:00
Matej Bačo c04c2d271c Remove logs, fix edge logs missing 2025-06-24 16:03:28 +02:00
Matej Bačo b5bc240c0d Fix ssr separation; add edge debugging logs 2025-06-24 15:56:06 +02:00
Matej Bačo 5dcc508870 Fix logs parsing 2025-06-24 15:38:39 +02:00
Matej Bačo 6996cc28a0 Fix logs order 2025-06-24 14:47:47 +02:00
Christy Jacob fe080153e6 chore: update benchmark workflow to use JSON output format 2025-06-24 15:28:07 +04:00
Christy Jacob 4759407696 chore: update composer.json and composer.lock to include appwrite-labs/php-amqplib and adjust utopia-php/queue version 2025-06-24 14:57:30 +04:00
Steven NguyenandGitHub 030d37fd5f Merge pull request #10036 from appwrite/update-executor
chore: update executor to fix s3 endpoint bug
2025-06-23 19:23:03 -07:00
shimon 213b1ae20e benchmark cli 2025-06-23 20:57:39 +03:00
shimon 4e0faf67f7 benchmark cli 2025-06-23 20:39:52 +03:00
shimon 3059eecbeb benchmark cli 2025-06-23 20:27:12 +03:00
shimon dd8894ad1e Merge remote-tracking branch 'origin/PLA-3018' into PLA-3018 2025-06-23 20:21:25 +03:00
shimon 28f420f10c Merge branch '1.7.x' of github.com:appwrite/appwrite into PLA-3018 2025-06-23 20:20:43 +03:00
54748b7d32 Update app/controllers/general.php
Co-authored-by: Steven Nguyen <1477010+stnguyen90@users.noreply.github.com>
2025-06-23 20:50:59 +04:00
Matej Bačo b69ff36ddb Manual QA fixes 2025-06-23 11:57:06 +02:00
Matej Bačo c1bd493fbe Move refferer to resource; re-use in OPTIONS; re-use in platform check 2025-06-23 11:28:18 +02:00
Steven NguyenandGitHub ffc7f4c7ae Merge pull request #9590 from appwrite/fix-templates
Fix template to use button
2025-06-21 09:33:06 -07:00
Christy JacobandGitHub 53ae307466 Merge pull request #10035 from appwrite/revert-9890-PLA-2762
Revert "worker: Graceful shutdown on SIGTERM"
2025-06-21 12:47:19 +04:00
Steven Nguyen 7238e11bdb fix: pin utopia-php/queue to 0.11.0
With the revert of PLA-2762, we need to pin the utopia-php/queue package to version 0.11.0 to avoid using the graceful shutdown feature that was introduced in version 0.11.1.
2025-06-20 20:31:26 -07:00
Chirag Aggarwal 2ac4d9f901 chore: update executor to fix s3 endpoint bug 2025-06-21 07:59:54 +05:30
Steven NguyenandGitHub 6d55299836 Revert "worker: Graceful shutdown on SIGTERM" 2025-06-20 18:40:04 -07:00
Khushboo Verma 1319bf7ec1 Fix connect to existing repo flow 2025-06-21 01:41:41 +04:00
shimon d8c88fb420 composer 2025-06-19 19:44:33 +03:00
shimon 68fc0f898f set log projectId on the router method 2025-06-19 17:15:43 +03:00
shimon 0f8c5fe292 Merge branch '1.7.x', commit 'c0c30fe767f8c197b8793bf562f57146e5ba15a8' of github.com:appwrite/appwrite into PLA-3018 2025-06-19 12:46:34 +03:00
Khushboo Verma e65ed58ca4 Merge branch 'chore-update-env-var-used-for-domain' of github.com:appwrite/appwrite into chore-update-env-var-used-for-domain 2025-06-18 22:17:11 +05:30
Khushboo Verma 095159d89b Merge branch '1.7.x' into chore-update-env-var-used-for-domain 2025-06-18 22:15:19 +05:30
Christy JacobandGitHub 509392c48b Merge branch '1.7.x' into chore-update-env-var-used-for-domain 2025-06-18 13:44:04 +04:00
Khushboo Verma 520006864d Merge branch '1.7.x' into chore-update-env-var-used-for-domain 2025-06-18 11:07:25 +05:30
Khushboo Verma 5a3e44a36d Replace == with === 2025-06-18 11:06:35 +05:30
Khushboo Verma 22cda269b1 Update console 2025-06-17 18:37:02 +05:30
Khushboo Verma e8e7ee01b4 Merge branch 'fix-github-check-urls' into chore-update-env-var-used-for-domain 2025-06-17 14:01:50 +05:30
Khushboo Verma b7ffd2ca94 Revert some changes 2025-06-17 13:57:21 +05:30
Khushboo Verma 9356fb4cb4 Merge branch '1.7.x' into chore-update-env-var-used-for-domain 2025-06-17 12:16:37 +05:30
Khushboo Verma 41bc8272ff Add env var to docker-compose 2025-06-17 12:15:52 +05:30
Darshan cacf323993 update: fallback font to sans-serif. 2025-06-17 09:15:26 +05:30
DarshanandGitHub 1b768cdb90 Merge branch '1.7.x' into fix-templates 2025-06-16 22:16:16 +05:30
Khushboo Verma ad60ff9972 Update url in general.php 2025-06-16 19:16:20 +05:30
Khushboo Verma 8c8abfdece Add var_dumps to debug 2025-06-16 18:47:50 +05:30
Khushboo Verma 5e345c0388 Revert some changes 2025-06-16 17:29:01 +05:30
Khushboo Verma 362618c5af Merge branch 'fix-github-check-urls' into chore-update-env-var-used-for-domain 2025-06-16 17:19:55 +05:30
shimon c0c30fe767 remove duplicate use 2025-06-15 12:40:22 +03:00
shimon d7e2552999 Merge branch '1.7.x' of github.com:appwrite/appwrite into PLA-3018 2025-06-15 12:38:50 +03:00
shimon 7d54a6191d remove duplicate use 2025-06-15 12:13:15 +03:00
shimon 4d41c90367 remove duplicate use 2025-06-15 12:00:39 +03:00
shimon 96c035401b Override project resource to update hooks, since x-appwrite-project is not available when executing custom domain function 2025-06-15 11:30:57 +03:00
DarshanandGitHub 3be1aa3801 Merge branch '1.7.x' into fix-templates 2025-06-15 11:21:33 +05:30
Khushboo Verma 3ad5a2652e Update console version 2025-06-13 19:14:00 +05:30
Khushboo VermaandGitHub 28db9a289b Merge branch '1.7.x' into feat-add-branch-url-for-first-git-deployment 2025-06-13 19:08:14 +05:30
Khushboo Verma 88d9bdd395 Merge branch 'fix-build-activation-race-condition' of github.com:appwrite/appwrite into fix-build-activation-race-condition 2025-06-13 19:05:12 +05:30
Khushboo Verma 995482ee20 Update console version 2025-06-13 19:04:46 +05:30
Khushboo Verma d2abdea6cf Resolve merge conflicts 2025-06-13 19:04:17 +05:30
Khushboo Verma fc656167d5 Composer update 2025-06-13 18:11:51 +05:30
Khushboo Verma 37388fcf1b Change php version in composer.lock 2025-06-13 18:08:19 +05:30
Khushboo Verma 55be41f633 Resolve merge conflicts 2025-06-13 18:06:47 +05:30
Khushboo Verma cee6420fa2 Use env vars instead of request 2025-06-13 15:50:53 +05:30
Khushboo Verma 8bac836483 Merge branch 'fix-github-check-urls' into chore-update-env-var-used-for-domain 2025-06-13 15:18:31 +05:30
Khushboo Verma 01aa9fbb48 Merge branch 'chore-update-env-var-used-for-domain' of github.com:appwrite/appwrite into chore-update-env-var-used-for-domain 2025-06-13 15:18:17 +05:30
Khushboo VermaandGitHub d7c3100fe9 Merge branch '1.7.x' into chore-update-env-var-used-for-domain 2025-06-13 15:18:02 +05:30
Khushboo Verma 43f9254302 Merge branch '1.7.x' into chore-update-env-var-used-for-domain 2025-06-12 20:32:02 +05:30
Khushboo Verma 710b8bda56 Use _APP_CONSOLE_DOMAIN, if not found, then use _APP_DOMAIN 2025-06-12 17:27:21 +05:30
Khushboo VermaandGitHub dde7570072 Merge branch '1.7.x' into fix-build-activation-race-condition 2025-06-10 16:21:51 +05:30
DarshanandGitHub e6d143c806 Merge branch '1.7.x' into fix-templates 2025-06-10 14:20:28 +05:30
Khushboo VermaandGitHub ef12f49277 Merge branch '1.7.x' into feat-add-branch-url-for-first-git-deployment 2025-06-10 13:08:34 +05:30
Khushboo Verma fa8e5b5b8e Add commit url 2025-06-04 19:11:07 +05:30
Khushboo Verma 54552bf1b4 Create branch url for first git deployment 2025-06-04 18:34:01 +05:30
Khushboo Verma 6530d31e7a Use ->action(...)) 2025-06-04 14:07:43 +05:30
Khushboo Verma e44d1b6600 Merge branch '1.7.x' into fix-build-activation-race-condition 2025-06-03 14:23:51 +05:30
Khushboo Verma 2088792d09 Fix build activation race condition 2025-06-03 14:23:17 +05:30
Khushboo Verma 7a465dc8f8 Don't auto-activate deployment which started earlier & ended later than active deployment 2025-06-02 17:53:35 +05:30
DarshanandGitHub cd467ddc89 Merge branch '1.7.x' into fix-templates 2025-05-14 10:21:08 +05:30
DarshanandGitHub b302b5416d Merge branch '1.7.x' into fix-templates 2025-05-13 17:52:57 +05:30
Darshan 0f67737690 change: color. 2025-05-13 17:49:31 +05:30
Darshan e523eb508a Merge remote-tracking branch 'origin/fix-templates' into fix-templates 2025-05-04 19:16:32 +05:30
Darshan 8546195c04 address comments by coderabbitai. 2025-05-04 19:16:25 +05:30
DarshanandGitHub f13a28cf6d Merge branch '1.7.x' into fix-templates 2025-05-04 19:08:06 +05:30
Luke B. SilverandGitHub d82812cc04 Merge branch '1.6.x' into feat-exp-scheme 2025-04-15 10:11:31 +01:00
loks0n 2427f950b5 fix: realtime 2025-04-14 14:34:22 +01:00
loks0n e551e4ad5b chore: fmt 2025-04-14 14:23:01 +01:00
loks0n 67a313cef3 fix: tests 2025-04-14 13:50:48 +01:00
loks0n 3c2b88dc86 chore: remove unused 2025-04-14 13:02:02 +01:00
loks0n 944624f13a chore: fmt 2025-04-14 12:59:39 +01:00
loks0n 4ac2571135 Merge branch '1.6.x' of https://github.com/appwrite/appwrite into feat-exp-scheme 2025-04-14 12:58:25 +01:00
loks0n 0a4c430ae7 feat: exp scheme 2025-04-14 12:56:42 +01:00
Darshan f56fcc6d90 fix: remaining tests! pheww! 2025-03-29 19:56:13 +05:30
Darshan f2c43c14bf fix: realtime test. 2025-03-29 19:20:27 +05:30
Darshan c4852836ef fix: realtime test. 2025-03-29 18:59:36 +05:30
Darshan b22be9b586 fix: test with teamName. 2025-03-29 18:53:51 +05:30
Darshan 48139cf49c Merge remote-tracking branch 'origin/fix-templates' into fix-templates 2025-03-29 18:23:07 +05:30
Darshan 736078203a update: change method name. 2025-03-29 18:22:59 +05:30
Darshan b1c67e6f74 fix: other remaining tests. 2025-03-29 18:21:25 +05:30
Darshan 6f501e2777 fix: teams test. 2025-03-29 17:19:46 +05:30
DarshanandGitHub bcd12fdfba Merge branch '1.7.x' into fix-templates 2025-03-29 14:32:13 +05:30
Darshan 734fa7dc77 update: languages; 2025-03-29 14:31:01 +05:30
Darshan e4311de735 update: languages; 2025-03-29 12:52:55 +05:30
Darshan 0071f0e728 update: languages; will update the rest later ;)
Note: have cross referenced with GPT, Google Translator and various other regional translators.
2025-03-28 19:40:56 +05:30
Darshan 57c06f1e5b update: use buttons instead of links for inner-base template. 2025-03-28 16:44:44 +05:30
308 changed files with 2568 additions and 1452 deletions
+4 -2
View File
@@ -22,6 +22,7 @@ _APP_OPTIONS_FORCE_HTTPS=disabled
_APP_OPTIONS_ROUTER_FORCE_HTTPS=disabled
_APP_OPENSSL_KEY_V1=your-secret-key
_APP_DOMAIN=traefik
_APP_CONSOLE_DOMAIN=localhost
_APP_DOMAIN_FUNCTIONS=functions.localhost
_APP_DOMAIN_SITES=sites.localhost
_APP_DOMAIN_TARGET_CNAME=test.localhost
@@ -84,8 +85,9 @@ _APP_COMPUTE_MAINTENANCE_INTERVAL=600
_APP_COMPUTE_RUNTIMES_NETWORK=runtimes
_APP_EXECUTOR_SECRET=your-secret-key
_APP_EXECUTOR_HOST=http://exc1/v1
_APP_FUNCTIONS_RUNTIMES=php-8.0,node-18.0,python-3.9,ruby-3.1
_APP_SITES_RUNTIMES=static-1,node-22,flutter-3.32
_APP_BROWSER_HOST=http://appwrite-browser:3000/v1
_APP_FUNCTIONS_RUNTIMES=node-22
_APP_SITES_RUNTIMES=static-1,node-22
_APP_MAINTENANCE_INTERVAL=86400
_APP_MAINTENANCE_START_TIME=12:00
_APP_MAINTENANCE_RETENTION_CACHE=2592000
+3 -2
View File
@@ -64,8 +64,9 @@ jobs:
sudo wget -O /usr/share/keyrings/azlux-archive-keyring.gpg https://azlux.fr/repo.gpg
sudo apt update
sudo apt install oha
oha --version
- name: Benchmark PR
run: 'oha -z 180s http://localhost/v1/health/version -j > benchmark.json'
run: 'oha -z 180s http://localhost/v1/health/version --output-format json > benchmark.json'
- name: Cleaning
run: docker compose down -v
- name: Installing latest version
@@ -78,7 +79,7 @@ jobs:
docker compose up -d
sleep 10
- name: Benchmark Latest
run: oha -z 180s http://localhost/v1/health/version -j > benchmark-latest.json
run: oha -z 180s http://localhost/v1/health/version --output-format json > benchmark-latest.json
- name: Prepare comment
run: |
echo '## :sparkles: Benchmark results' > benchmark.txt
+85 -4
View File
@@ -178,6 +178,7 @@ jobs:
- name: Load and Start Appwrite
run: |
docker load --input /tmp/${{ env.IMAGE }}.tar
sed -i 's|^_APP_BROWSER_HOST=.*|_APP_BROWSER_HOST=http://invalid-browser/v1|' .env
docker compose up -d
sleep 30
@@ -198,7 +199,7 @@ jobs:
docker compose exec -T \
-e _APP_DATABASE_SHARED_TABLES \
-e _APP_DATABASE_SHARED_TABLES_V1 \
appwrite test /usr/src/code/tests/e2e/Services/${{ matrix.service }} --debug --exclude-group devKeys
appwrite test /usr/src/code/tests/e2e/Services/${{ matrix.service }} --debug --exclude-group devKeys,screenshots
e2e_shared_mode_test:
name: E2E Shared Mode Service Test
@@ -277,14 +278,12 @@ jobs:
docker compose exec -T \
-e _APP_DATABASE_SHARED_TABLES \
-e _APP_DATABASE_SHARED_TABLES_V1 \
appwrite test /usr/src/code/tests/e2e/Services/${{ matrix.service }} --debug --exclude-group devKeys
appwrite test /usr/src/code/tests/e2e/Services/${{ matrix.service }} --debug --exclude-group devKeys,screenshots
e2e_dev_keys:
name: E2E Service Test (Dev Keys)
runs-on: ubuntu-latest
needs: setup
strategy:
fail-fast: false
steps:
- name: checkout
uses: actions/checkout@v4
@@ -360,3 +359,85 @@ jobs:
-e _APP_DATABASE_SHARED_TABLES \
-e _APP_DATABASE_SHARED_TABLES_V1 \
appwrite test /usr/src/code/tests/e2e/Services/Projects --debug --group=devKeys
e2e_screenshots_keys:
name: E2E Service Test (Site Screenshots)
runs-on: ubuntu-latest
needs: setup
steps:
- name: checkout
uses: actions/checkout@v4
- name: Load Cache
uses: actions/cache@v4
with:
key: ${{ env.CACHE_KEY }}
path: /tmp/${{ env.IMAGE }}.tar
fail-on-cache-miss: true
- name: Load and Start Appwrite
run: |
docker load --input /tmp/${{ env.IMAGE }}.tar
sed -i 's/_APP_OPTIONS_ABUSE=disabled/_APP_OPTIONS_ABUSE=enabled/' .env
docker compose up -d
sleep 30
- name: Run Site tests with browser connected in dedicated table mode
run: |
echo "Keeping original value of _APP_BROWSER_HOST"
echo "Using project tables"
export _APP_DATABASE_SHARED_TABLES=
export _APP_DATABASE_SHARED_TABLES_V1=
docker compose exec -T \
-e _APP_DATABASE_SHARED_TABLES \
-e _APP_DATABASE_SHARED_TABLES_V1 \
appwrite test /usr/src/code/tests/e2e/Services/Sites --debug --group=screenshots
e2e_screenshots_shared_mode:
name: E2E Shared Mode Service Test (Site Screenshots)
runs-on: ubuntu-latest
needs: [ setup, check_database_changes ]
if: needs.check_database_changes.outputs.database_changed == 'true'
strategy:
fail-fast: false
matrix:
tables-mode: [
'Shared V1',
'Shared V2',
]
steps:
- name: checkout
uses: actions/checkout@v4
- name: Load Cache
uses: actions/cache@v4
with:
key: ${{ env.CACHE_KEY }}
path: /tmp/${{ env.IMAGE }}.tar
fail-on-cache-miss: true
- name: Load and Start Appwrite
run: |
docker load --input /tmp/${{ env.IMAGE }}.tar
sed -i 's/_APP_OPTIONS_ABUSE=disabled/_APP_OPTIONS_ABUSE=enabled/' .env
docker compose up -d
sleep 30
- name: Run Site tests with browser connected in ${{ matrix.tables-mode }} table mode
run: |
echo "Keeping original value of _APP_BROWSER_HOST"
if [ "${{ matrix.tables-mode }}" == "Shared V1" ]; then
echo "Using shared tables V1"
export _APP_DATABASE_SHARED_TABLES=database_db_main
export _APP_DATABASE_SHARED_TABLES_V1=database_db_main
elif [ "${{ matrix.tables-mode }}" == "Shared V2" ]; then
echo "Using shared tables V2"
export _APP_DATABASE_SHARED_TABLES=database_db_main
export _APP_DATABASE_SHARED_TABLES_V1=
fi
docker compose exec -T \
-e _APP_DATABASE_SHARED_TABLES \
-e _APP_DATABASE_SHARED_TABLES_V1 \
appwrite test /usr/src/code/tests/e2e/Services/Sites --debug --group=screenshots
+6 -4
View File
@@ -188,16 +188,18 @@ CLI::setResource('getLogsDB', function (Group $pools, Cache $cache) {
return $database;
};
}, ['pools', 'cache']);
CLI::setResource('publisher', function (Group $pools) {
return new BrokerPool(publisher: $pools->get('publisher'));
}, ['pools']);
CLI::setResource('publisherRedis', function () {
// Stub
});
CLI::setResource('queueForStatsUsage', function (Publisher $publisher) {
return new StatsUsage($publisher);
}, ['publisher']);
CLI::setResource('queueForStatsResources', function (Publisher $publisher) {
return new StatsResources($publisher);
}, ['publisher']);
CLI::setResource('publisher', function (Group $pools) {
return new BrokerPool(publisher: $pools->get('publisher'));
}, ['pools']);
CLI::setResource('queueForFunctions', function (Publisher $publisher) {
return new Func($publisher);
}, ['publisher']);
+2 -2
View File
@@ -5,7 +5,7 @@
*/
use Appwrite\Auth\Auth;
use Appwrite\Network\Validator\Origin;
use Appwrite\Network\Platform;
use Utopia\Database\Helpers\ID;
use Utopia\System\System;
@@ -23,7 +23,7 @@ $console = [
[
'$collection' => ID::custom('platforms'),
'name' => 'Localhost',
'type' => Origin::CLIENT_TYPE_WEB,
'type' => Platform::TYPE_WEB,
'hostname' => 'localhost',
], // Current host is added on app init
],
@@ -1,6 +1,6 @@
<p>{{hello}}</p>
<p>{{body}}</p>
<p><a href="{{redirect}}" target="_blank">{{redirect}}</a></p>
<p><a href="{{redirect}}" target="_blank" style="font-size: 14px; font-family: Inter, sans-serif; color: #ffffff; text-decoration: none; background-color: #2D2D31; border-radius: 8px; padding: 9px 14px; border: 1px solid #414146; display: inline-block; text-align:center; box-sizing: border-box;">{{buttonText}}</a></p>
<p>{{footer}}</p>
<p style="margin-bottom: 32px">
{{thanks}}
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Volg hierdie skakel om u e-pos adres te bevestig.",
"emails.verification.footer": "Ignoreer gerus hierdie boodskap as u nie die versoek gestuur het om u adres te bevestig nie.",
"emails.verification.thanks": "Baie dankie,",
"emails.verification.buttonText": "Bevestig e-posadres",
"emails.verification.signature": "Die {{project}} span",
"emails.magicSession.subject": "Teken aan",
"emails.magicSession.hello": "Goeie dag,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Volg hierdie skakel om u {{project}} wagwoord te herstel.",
"emails.recovery.footer": "Ignoreer gerus hierdie boodskap as u nie die versoek gestuur het om u wagwoord te herstel nie.",
"emails.recovery.thanks": "Baie dankie,",
"emails.recovery.buttonText": "Stel wagwoord terug",
"emails.recovery.signature": "Die {{project}} span",
"emails.invitation.subject": "Uitnodiging om by die %s span aan te sluit by %s",
"emails.invitation.hello": "Goeie dag,",
"emails.invitation.body": "Hierdie boodskap is aan u gestuur omdat {{owner}} u uitnooi om 'n lid van die {{team}} groep by die {{project}} projek te wees.",
"emails.invitation.footer": "As u nie belang stel nie, kan u gerus hierdie boodskap ignoreer.",
"emails.invitation.thanks": "Baie dankie,",
"emails.invitation.buttonText": "Aanvaar uitnodiging na {{team}}",
"emails.invitation.signature": "Die {{project}} span",
"locale.country.unknown": "Onbekend",
"countries.af": "Afghanistan",
@@ -8,6 +8,7 @@
"emails.verification.body": "تبّع هاد الوصلة باش تيقّن لادريسة تاع ليميل ديالك.",
"emails.verification.footer": "إلا ماشي نتا اللي طلبتي تيقّن هاد لادريسة تاع ليميل، ممكن تنخّل هاد البرية.",
"emails.verification.thanks": "شكرا،",
"emails.verification.buttonText": "تأكيد عنوان البريد الإلكتروني",
"emails.verification.signature": "فرقة {{project}}",
"emails.magicSession.subject": "تكونيكطا",
"emails.magicSession.hello": "السلام،",
@@ -20,12 +21,14 @@
"emails.recovery.body": "تبّع هاد الوصلة باش تبدّل كلمة السر تاع {{project}}.",
"emails.recovery.footer": "إلا ماشي نتا اللي طلبتي تبدّل كلمة السر، ممكن تنخّل هاد البرية.",
"emails.recovery.thanks": "شكرا،",
"emails.recovery.buttonText": "إعادة تعيين كلمة السر",
"emails.recovery.signature": "فرقة {{project}}",
"emails.invitation.subject": "عراضة ل فرقة %s ف %s",
"emails.invitation.hello": "السلام،",
"emails.invitation.body": "هاد البرية تصيفطات ليك حيت {{owner}} بغى يعرض عليك تولّي عضو ف فرقة {{team}} عند {{project}}.",
"emails.invitation.footer": "إلا كنتي ما مسوّقش, ممكن تنخّل هاد البرية.",
"emails.invitation.thanks": "شكرا،",
"emails.invitation.buttonText": "اقبل الدعوة إلى {{team}}",
"emails.invitation.signature": "فرقة {{project}}",
"emails.certificate.subject": "السرتافيكة فشلات ل %s",
"emails.certificate.hello": "السلام،",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "برجاء اتباع الرابط التالي لتأكيد بريدك الإلكتروني",
"emails.verification.footer": "لو لم تطلب تأكيد هذا البريد الإلكتروني، يمكنك تجاهل هذه الرسالة",
"emails.verification.thanks": "شكرا،",
"emails.verification.buttonText": "تأكيد عنوان البريد الإلكتروني",
"emails.verification.signature": "فريق {{project}}",
"emails.magicSession.subject": "تسجيل الدخول",
"emails.magicSession.hello": "أهلا،",
@@ -20,12 +21,14 @@
"emails.recovery.body": "برجاء اتباع الراط التالي لتغيير كلمة السر الخاصة بـ{{project}}",
"emails.recovery.footer": "لولم تطلب تغيير كلمة السر، يمكنك تجاهل هذه الرسالة",
"emails.recovery.thanks": "شكرا،",
"emails.recovery.buttonText": "إعادة تعيين كلمة المرور",
"emails.recovery.signature": "فريق {{project}}",
"emails.invitation.subject": "دعوة لفريق %s في %s",
"emails.invitation.hello": "أهلا،",
"emails.invitation.body": "هذة الرسالة تم ارسالها لك لأن {{owner}} ارسل لك دعوة لتكون عضوا بفريق {{team}} في {{project}}",
"emails.invitation.footer": "اذا كنت غير مهتم، يمكنك تجاهل هذه الرسالة",
"emails.invitation.thanks": "شكرا،",
"emails.invitation.buttonText": "قبول الدعوة إلى {{team}}",
"emails.invitation.signature": "فريق {{project}}",
"locale.country.unknown": "مجهول",
"countries.af": "أفغانستان",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "আপোনাৰ ইমেইল ঠিকনা প্ৰমাণিত কৰিবলৈ এই লিংকটো অনুসৰণ কৰক।",
"emails.verification.footer": "যদি আপুনি এই ঠিকনাটো সত্যাপিত কৰিবলৈ কোৱা নাই, আপুনি এই বাৰ্তাটো উপেক্ষা কৰিব পাৰে।",
"emails.verification.thanks": "ধন্যবাদ,",
"emails.verification.buttonText": "ইমেইল ঠিকনা নিশ্চিত কৰক",
"emails.verification.signature": "{{project}} দল",
"emails.magicSession.subject": "লগইন",
"emails.magicSession.hello": "নমস্কাৰ,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "আপোনাৰ {{project}} পাছৱৰ্ড ৰিছেট কৰিবলৈ এই লিংকটো অনুসৰণ কৰক।.",
"emails.recovery.footer": "যদি আপুনি আপোনাৰ পাছৱৰ্ড ৰিছেট কৰিবলৈ কোৱা নাছিল, আপুনি এই বাৰ্তাটো উপেক্ষা কৰিব পাৰে।",
"emails.recovery.thanks": "ধন্যবাদ,",
"emails.recovery.buttonText": "পাছৱৰ্ড ৰিছেট কৰক",
"emails.recovery.signature": "{{project}} দল",
"emails.invitation.subject": "%s বছৰত %s দললৈ নিমন্ত্ৰণ",
"emails.invitation.hello": "নমস্কাৰ,",
"emails.invitation.body": "এই মেইলটো আপোনালৈ প্ৰেৰণ কৰা হৈছিল কাৰণ {{owner}} জনে আপোনাক {{project}} বছৰবয়সত {{team}} দলৰ সদস্য হ'বলৈ আমন্ত্ৰণ জনাব বিচাৰিছিল।",
"emails.invitation.footer": "যদি আপুনি আগ্ৰহী নহয়, আপুনি এই বাৰ্তাটো উপেক্ষা কৰিব পাৰে।",
"emails.invitation.thanks": "ধন্যবাদ,",
"emails.invitation.buttonText": "{{team}}-লৈ নিমন্ত্ৰণ গ্ৰহণ কৰক",
"emails.invitation.signature": "{{project}} দল",
"locale.country.unknown": "অজ্ঞাত ",
"countries.af": "আফগানিস্তান ",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "E-poçt ünvanınızı təsdiq etmək üçün bu linki izləyin.",
"emails.verification.footer": "Bu ünvanı doğrulamağı xahiş etməmisinizsə, bu mesajı gözardı edə bilərsiniz.",
"emails.verification.thanks": "Təşəkkürlər,",
"emails.verification.buttonText": "E-poçt ünvanını təsdiqlə",
"emails.verification.signature": "{{project}} komandası",
"emails.magicSession.subject": "Daxil Olmaq",
"emails.magicSession.hello": "Salam,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "{{project}} şifrənizi sıfırlamaq üçün bu linki izləyin.",
"emails.recovery.footer": "Şifrənizi sıfırlamağı xahiş etməmisinizsə, bu mesajı gözardı edə bilərsiniz.",
"emails.recovery.thanks": "Təşəkkürlər,",
"emails.recovery.buttonText": "Şifrəni sıfırla",
"emails.recovery.signature": "{{project}} komandası",
"emails.invitation.subject": "%s Komandasına Dəvət %sdə",
"emails.invitation.hello": "Salam,",
"emails.invitation.body": "{{owner}}, {{project}}də {{team}} komandasına üzv olmağa dəvət etmək istədiyi üçün bu məktub sizə göndərildi.",
"emails.invitation.footer": "Əgər maraqlanmırsınızsa, bu mesajı gözardı edə bilərsiniz.",
"emails.invitation.thanks": "Təşəkkürlər,",
"emails.invitation.buttonText": "{{team}} dəvətini qəbul et",
"emails.invitation.signature": "{{project}} komandası",
"locale.country.unknown": "Naməlum",
"countries.af": "Əfqanıstan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Перайдзіце па гэтай спасылцы, каб пацвердзіць свой адрас электроннай пошты",
"emails.verification.footer": "Калі вы не запытвалі пацвярджэнне гэтага адрасу, праігнаруйце гэтае паведамленне.",
"emails.verification.thanks": "Дзякуем,",
"emails.verification.buttonText": "Пацвердзіць адрас электроннай пошты",
"emails.verification.signature": "каманда {{project}}",
"emails.magicSession.subject": "Лагін",
"emails.magicSession.hello": "Прывітанне,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Перайдзіце па гэтай спасылцы, каб скінуць пароль для праекта {{project}}.",
"emails.recovery.footer": "Калі вы не прасілі скінуць пароль, вы можаце праігнараваць гэта паведамленне.",
"emails.recovery.thanks": "Дзякуем,",
"emails.recovery.buttonText": "Аднавіць пароль",
"emails.recovery.signature": "каманда {{project}}",
"emails.invitation.subject": "Запрошення до Команди %s у %s",
"emails.invitation.hello": "Прывітанне,",
"emails.invitation.body": "Гэта паведамленне было адпраўлена вам, таму што {{owner}} хацеў запрасіць вас стаць членам каманды {{team}} у {{project}}.",
"emails.invitation.footer": "Калі вам гэта не цікава, вы можаце праігнараваць гэтае паведамленне.",
"emails.invitation.thanks": "Дзякуем,",
"emails.invitation.buttonText": "Прыняць запрашэнне ў {{team}}",
"emails.invitation.signature": "каманда {{project}}",
"locale.country.unknown": "Невядомы",
"countries.af": "Афганістан",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "ईमेल प्रमाणिकरण करे क लेल दिहल गइल लिंक फॉलो करें|",
"emails.verification.footer": "अगर ई पता को सत्यापित करे के लिए ना कहाले, तो आप ई संदेश क अनदेखा कर सकत अछि।",
"emails.verification.thanks": "धन्यवाद,",
"emails.verification.buttonText": "ईमेल पता के पुष्टि करीं",
"emails.verification.signature": "{{project}} टीम",
"emails.magicSession.subject": "लॉग इन करीं|",
"emails.magicSession.hello": "प्रणाम,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "पासवर्ड बदल क लेल दिहल गइल लिंक फॉलो करें|",
"emails.recovery.footer": "अगर पासवर्ड बदल क लेल ना कहाले, तो आप ई संदेश क अनदेखा कर सकत अछि।",
"emails.recovery.thanks": "धन्यवाद,",
"emails.recovery.buttonText": "पासवर्ड रीसेट करीं",
"emails.recovery.signature": "{{project}} टीम",
"emails.invitation.subject": "%s टीम क %s पे न्योता देवे क लेल|",
"emails.invitation.hello": "प्रणाम,",
"emails.invitation.body": "ई मेल आपके एही लेल भेजल गईल रहल काहे क {{owner}} आपके {{project}} क {{team}} टीम का सदस्य बनावे चाहित रहे|",
"emails.invitation.footer": "अगर आवे क इच्छा ना होवत, तो आप ई संदेश क अनदेखा कर सकत अछि।",
"emails.invitation.thanks": "धन्यवाद,",
"emails.invitation.buttonText": "{{team}} में नेवता स्वीकार करीं",
"emails.invitation.signature": "{{project}} टीम",
"locale.country.unknown": "अनजान",
"countries.af": "अफ़ग़ानिस्तान",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "এই লিঙ্কের মাধ্যমে ইমেইল যাচাই করুন।",
"emails.verification.footer": "আপনি যদি এই ঠিকানা যাচাই করতে না বলেন, তাহলে আপনি এই বার্তাটি উপেক্ষা করতে পারেন।",
"emails.verification.thanks": "ধন্যবাদ,",
"emails.verification.buttonText": "ইমেইল ঠিকানা নিশ্চিত করুন",
"emails.verification.signature": "{{project}} টীম",
"emails.magicSession.subject": "লগ ইন",
"emails.magicSession.hello": "নমস্কার,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "এই লিঙ্কের মাধ্যমে আপনার {{project}} পাসওয়ার্ড পুনরায় সেট করুন।",
"emails.recovery.footer": "আপনি যদি আপনার পাসওয়ার্ড পুনরায় সেট করতে না বলেন, তাহলে আপনি এই বার্তাটি উপেক্ষা করতে পারেন।",
"emails.recovery.thanks": "ধন্যবাদ,",
"emails.recovery.buttonText": "পাসওয়ার্ড রিসেট করুন",
"emails.recovery.signature": "{{project}} টীম",
"emails.invitation.subject": "%s টিমকে %s তে আমন্ত্রণ জানান",
"emails.invitation.hello": "নমস্কার,",
"emails.invitation.body": "এই মেইলটি আপনাকে পাঠানো হয়েছে কারণ {{owner}} আপনাকে {{project}} এর সাথে যুক্ত {{team}} টিমের সদস্য হওয়ার জন্য আমন্ত্রণ জানাতে চেয়েছিলেন।",
"emails.invitation.footer": "যদি এটি আপনার জন্য প্রয়োজনীয় না হয়, আপনি এই বার্তাটি উপেক্ষা করতে পারেন।",
"emails.invitation.thanks": "ধন্যবাদ,",
"emails.invitation.buttonText": "{{team}}-এর আমন্ত্রণ গ্রহণ করুন",
"emails.invitation.signature": "{{project}} টীম",
"locale.country.unknown": "অজানা",
"countries.af": "আফগানিস্তান",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Accedeix a aquest enllaç per tal de verificar la teva adreça electrònica.",
"emails.verification.footer": "Si no has sol·licitat la verificació d'aquesta adreça electrònica, pots ignorar aquest missatge.",
"emails.verification.thanks": "Gràcies,",
"emails.verification.buttonText": "Confirma l'adreça electrònica",
"emails.verification.signature": "Equip {{project}}",
"emails.magicSession.subject": "Entrar",
"emails.magicSession.hello": "Hola,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Accedeix a aquest enllaç per a reinicialitzar la teva contrasenya de {{project}}.",
"emails.recovery.footer": "Si no has sol·licitat reinicialitzar la teva contrasenya, pots ignorar aquest missatge.",
"emails.recovery.thanks": "Gràcies,",
"emails.recovery.buttonText": "Restableix la contrasenya",
"emails.recovery.signature": "Equip {{project}}",
"emails.invitation.subject": "Invitació a l'equip %s a s%",
"emails.invitation.hello": "Hola,",
"emails.invitation.body": "Aquest correu se t'ha enviat perquè {{owner}} vol convidar-te a formar part de l'equip {{team}} al {{project}}.",
"emails.invitation.footer": "Si no és del teu interès, pots ignorar aquest missatge.",
"emails.invitation.thanks": "Gràcies,",
"emails.invitation.buttonText": "Accepta la invitació a {{team}}",
"emails.invitation.signature": "Equip {{project}}",
"locale.country.unknown": "Desconegut",
"countries.af": "Afganistan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Følg dette link, for at verificere din email adresse.",
"emails.verification.footer": "Hvis du ikke har bedt om at verificere denne adresse, ignorer venligst denne besked.",
"emails.verification.thanks": "Tak,",
"emails.verification.buttonText": "Bekræft e-mailadresse",
"emails.verification.signature": "{{project}} team",
"emails.magicSession.subject": "Login",
"emails.magicSession.hello": "Hej,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Følg dette link for at nulstille koden til {{project}}.",
"emails.recovery.footer": "Hvis du ikke har bedt om at nulstille dit password, ignorer venligst denne besked.",
"emails.recovery.thanks": "Tak,",
"emails.recovery.buttonText": "Nulstil adgangskode",
"emails.recovery.signature": "{{project}} team",
"emails.invitation.subject": "Invitation til %s Team på %s",
"emails.invitation.hello": "Hej,",
"emails.invitation.body": "Denne mail blev sendt til dig, fordi {{owner}} vil invitere dig til at blive medlem af {{team}} teamet på {{project}}.",
"emails.invitation.footer": "Hvis du ikke er interesseret, ignorer venligst denne besked.",
"emails.invitation.thanks": "Tak,",
"emails.invitation.buttonText": "Accepter invitation til {{team}}",
"emails.invitation.signature": "{{project}} team",
"locale.country.unknown": "Ukendt",
"countries.af": "Afghanistan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Folge diesem Link, um deine E-Mail-Adresse zu bestätigen.",
"emails.verification.footer": "Solltest du keine Verifizierung dieser E-Mail-Adresse angefordert haben, kannst du diese Nachricht ignorieren.",
"emails.verification.thanks": "Danke,",
"emails.verification.buttonText": "E-Mail-Adresse bestätigen",
"emails.verification.signature": "{{project}}-Team",
"emails.magicSession.subject": "Login",
"emails.magicSession.hello": "Hey,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Folge diesem Link, um dein {{project}}-Kennwort zurückzusetzen.",
"emails.recovery.footer": "Solltest du keine Kennwort-Zurücksetzung angefordert haben, kannst du diese Nachricht ignorieren.",
"emails.recovery.thanks": "Danke,",
"emails.recovery.buttonText": "Passwort zurücksetzen",
"emails.recovery.signature": "{{project}}-Team",
"emails.invitation.subject": "Einladung zum %s-Team auf %s",
"emails.invitation.hello": "Hello,",
"emails.invitation.body": "Du erhälst diese E-Mail, weil {{owner}} dich in das Team {{team}} auf {{project}} eingeladen hat.",
"emails.invitation.footer": "Wenn du nicht interessiert bist, kannst du diese Nachricht ignorieren.",
"emails.invitation.thanks": "Danke,",
"emails.invitation.buttonText": "Einladung zu {{team}} annehmen",
"emails.invitation.signature": "{{project}}-Team",
"locale.country.unknown": "Unbekannt",
"countries.af": "Afghanistan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Ακολουθήστε αυτό το link για να επαληθεύσετε τη δ/νση του email σας",
"emails.verification.footer": "Εάν δεν ζητήσατε επαλήθευση αυτής της δ/νσης email, μπορείτε να αγνοήσετε αυτό το μήνυμα",
"emails.verification.thanks": "Ευχαριστούμε,",
"emails.verification.buttonText": "Επιβεβαιώστε διεύθυνση email",
"emails.verification.signature": "Η ομάδα του {{project}}",
"emails.magicSession.subject": "Είσοδος",
"emails.magicSession.hello": "Γεια σου,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Ακολουθήστε αυτό το link για να αλλάξετε τον {{project}} κωδικό σας",
"emails.recovery.footer": "Εάν δεν ζητήσατε αλλαγή του κωδικού σας πρόσβασης, μπορείτε να αγνοήσετε αυτό το μήνυμα",
"emails.recovery.thanks": "Ευχαριστούμε,",
"emails.recovery.buttonText": "Επαναφορά κωδικού πρόσβασης",
"emails.recovery.signature": "Η ομάδα του {{project}}",
"emails.invitation.subject": "Πρόσκληση στην %s Ομάδα στον %s",
"emails.invitation.hello": "Γεια σου,",
"emails.invitation.body": "Αυτό το email στάλθηκε επειδή ο/η {{owner}} θέλει να σας προσκαλέσει να γίνετε μέλος της ομάδας {{team}} του {{project}}.",
"emails.invitation.footer": "Εάν δεν ενδιαφέρεστε, μπορείτε να αγνοήσετε αυτό το μήνυμα.",
"emails.invitation.thanks": "Ευχαριστούμε,",
"emails.invitation.buttonText": "Αποδεχόμενος την πρόσκληση στην {{team}}",
"emails.invitation.signature": "Η ομάδα του {{project}}",
"locale.country.unknown": "Άγνωστο",
"countries.af": "Αφγανιστάν",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Follow this link to verify your email address to your {{b}}{{project}}{{/b}} account.",
"emails.verification.footer": "If you didnt ask to verify this address, you can ignore this message.",
"emails.verification.thanks": "Thanks,",
"emails.verification.buttonText": "Confirm email address",
"emails.verification.signature": "{{project}} team",
"emails.magicSession.subject": "{{project}} Login",
"emails.magicSession.hello": "Hello {{user}},",
@@ -45,12 +46,14 @@
"emails.recovery.body": "Follow this link to reset your {{b}}{{project}}{{/b}} password.",
"emails.recovery.footer": "If you didn't ask to reset your password, you can ignore this message.",
"emails.recovery.thanks": "Thanks,",
"emails.recovery.buttonText": "Reset password",
"emails.recovery.signature": "{{project}} team",
"emails.invitation.subject": "Invitation to %s Team at %s",
"emails.invitation.hello": "Hello {{user}},",
"emails.invitation.body": "This mail was sent to you because {{b}}{{owner}}{{/b}} wanted to invite you to become a member of the {{b}}{{team}}{{/b}} team at {{b}}{{project}}{{/b}}.",
"emails.invitation.footer": "If you are not interested, you can ignore this message.",
"emails.invitation.thanks": "Thanks,",
"emails.invitation.buttonText": "Accept invite to {{team}}",
"emails.invitation.signature": "{{project}} team",
"emails.certificate.subject": "Certificate failure for %s",
"emails.certificate.hello": "Hello,",
+3
View File
@@ -7,6 +7,7 @@
"emails.verification.body": "Alklaku ĉi tiun ligon por kontroli vian retpoŝtan adreson.",
"emails.verification.footer": "Se vi ne petis ĉi tiun konfirmon de ĉi tiu retpoŝto, vi povas ignori ĉi tiun mesaĝon.",
"emails.verification.thanks": "Dankegon.,",
"emails.verification.buttonText": "Konfirmi retadreson",
"emails.verification.signature": "Teamo {{project}}",
"emails.magicSession.subject": "Login",
"emails.magicSession.hello": "Saluton,",
@@ -19,12 +20,14 @@
"emails.recovery.body": "Alklaku ĉi tiun ligon por reagordi vian pasvorton. {{project}}",
"emails.recovery.footer": "Se vi ne petis reagordi vian pasvorton, vi povas ignori ĉi tiun mesaĝon.",
"emails.recovery.thanks": "Dankegon,",
"emails.recovery.buttonText": "Pasvorton restarigi",
"emails.recovery.signature": "Teamo {{project}}",
"emails.invitation.subject": "Invito al la Teamo %s em %s",
"emails.invitation.hello": "Dankegon,",
"emails.invitation.body": "Ĉi tiu retpoŝto estis sendita ĉar la {{owner}} volas inviti vin fariĝi membro de la Teamo {{team}} en {{project}}.",
"emails.invitation.footer": "Se vi ne interesiĝas, vi povas ignori ĉi tiun mesaĝon.",
"emails.invitation.thanks": "Dankegon,",
"emails.invitation.buttonText": "Akcepti inviton al {{team}}",
"emails.invitation.signature": "Teamo {{project}}",
"locale.country.unknown": "Unknown",
"countries.af": "Afghanistan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Haz clic en este enlace para verificar tu correo:",
"emails.verification.footer": "Si no has solicitado verificar este correo, puedes ignorar este mensaje.",
"emails.verification.thanks": "Gracias.,",
"emails.verification.buttonText": "Confirmar dirección de correo",
"emails.verification.signature": "El equipo de {{project}}.",
"emails.magicSession.subject": "Inicio de sesión",
"emails.magicSession.hello": "Hola,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Haz clic en este enlace para restablecer la contraseña de {{project}}:",
"emails.recovery.footer": "Si no has solicitado restablecer la contraseña, puedes ignorar este mensaje.",
"emails.recovery.thanks": "Gracias.,",
"emails.recovery.buttonText": "Restablecer contraseña",
"emails.recovery.signature": "El equipo de {{project}}",
"emails.invitation.subject": "Invitación al equipo %s en %s",
"emails.invitation.hello": "Hola,",
"emails.invitation.body": "Este correo ha sido enviado a petición de {{owner}} quién quiere invitarte a formar parte del equipo {{team}} en {{project}}.",
"emails.invitation.footer": "Si no estás interesado, puedes ignorar este mensaje.",
"emails.invitation.thanks": "Gracias.,",
"emails.invitation.buttonText": "Aceptar invitación a {{team}}",
"emails.invitation.signature": "El equipo de {{project}}",
"locale.country.unknown": "Desconocido",
"countries.af": "Afganistán",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "برای تأیید ایمیل‌تان پیوند زیر را دنبال کنید.",
"emails.verification.footer": "اگر شما درخواست تأیید حساب نداده‌اید، می‌توانید این پیام را نادیده بگیرید.",
"emails.verification.thanks": "سپاس فراوان،",
"emails.verification.buttonText": "آدرس ایمیل را تایید کنید",
"emails.verification.signature": "تیم {{user}}",
"emails.magicSession.subject": "ورود به حساب کاربری",
"emails.magicSession.hello": "سلام،",
@@ -20,12 +21,14 @@
"emails.recovery.body": "برای بازیابی گذرواژه‌تان پیوند زیر را دنبال کنید.",
"emails.recovery.footer": "اگر شما درخواست بازیابی گذرواژه نداده‌اید، می‌توانید این پیام را نادیده بگیرید.",
"emails.recovery.thanks": "سپاس فراوان،",
"emails.recovery.buttonText": "بازنشانی رمز عبور",
"emails.recovery.signature": "تیم {{user}}",
"emails.invitation.subject": "دعوت به تیم %s در %s",
"emails.invitation.hello": "سلام،",
"emails.invitation.body": "این ایمیل برای شما فرستاده شده‌است زیرا {{owner}} می‌خواهد شما را به تیم {{team}} در پروژه‌ی {{project}} بیفزاید.",
"emails.invitation.footer": "اگر علاقه ندارید، می‌توانید این پیام را نادیده بگیرید.",
"emails.invitation.thanks": "سپاس فراوان،",
"emails.invitation.buttonText": "دعوت را به {{team}} بپذیرید",
"emails.invitation.signature": "تیم {{user}}",
"locale.country.unknown": "ناشناخته",
"countries.af": "افغانستان",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Suivez ce lien pour vérifier votre adresse e-mail.",
"emails.verification.footer": "Si vous n'avez pas demandé à vérifier cette adresse, vous pouvez ignorer ce message.",
"emails.verification.thanks": "Merci,",
"emails.verification.buttonText": "Confirmez l'adresse e-mail",
"emails.verification.signature": "Équipe {{project}}",
"emails.magicSession.subject": "Connexion",
"emails.magicSession.hello": "Bonjour,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Suivez ce lien pour réinitialiser votre mot de passe pour {{project}}.",
"emails.recovery.footer": "Si vous n'avez pas demandé à réinitialiser votre mot de passe, vous pouvez ignorer ce message.",
"emails.recovery.thanks": "Merci,",
"emails.recovery.buttonText": "Réinitialisation du mot de passe",
"emails.recovery.signature": "L'équipe {{project}}",
"emails.invitation.subject": "Invitation à l'équipe %s de %s",
"emails.invitation.hello": "Bonjour,",
"emails.invitation.body": "Cet e-mail vous a été envoyé parce que {{owner}} souhaite vous inviter à devenir membre de l'équipe {{team}} pour {{project}}.",
"emails.invitation.footer": "Si vous n'êtes pas intéressé, vous pouvez ignorer ce message.",
"emails.invitation.thanks": "Merci,",
"emails.invitation.buttonText": "Accepter l'invitation à {{team}}",
"emails.invitation.signature": "L'équipe {{project}}",
"locale.country.unknown": "Inconnu",
"countries.af": "Afghanistan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Lean an nasc seo chun do ríomhphost a fhíorú.",
"emails.verification.footer": "Mura ndearna tú iarratas an seoladh seo a fhíoru, déan neamhaird den teachtaireacht seo.",
"emails.verification.thanks": "Go raibh maith agat,",
"emails.verification.buttonText": "Deimhnigh seoladh ríomhphoist",
"emails.verification.signature": "{{project}} foireann",
"emails.magicSession.subject": "Logáil isteach",
"emails.magicSession.hello": "Haigh,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Lean an nasc seo chun do pasfhocal {{project}} a athshocrú.",
"emails.recovery.footer": "Mura ndearna tú iarratas do pasfhocal a athshocrú, déan neamhaird den teachtaireacht seo.",
"emails.recovery.thanks": "Go raibh maith agat,",
"emails.recovery.buttonText": "Athshocraigh focal faire",
"emails.recovery.signature": "{{project}} foireann",
"emails.invitation.subject": "Cuireadh do %s foireann ag %s",
"emails.invitation.hello": "Haigh,",
"emails.invitation.body": "Seoladh an ríomhphost seo chugat mar ba mhaith le {{owner}} cuireadh a thabhairt duit bheith mar bhall den fhoireann {{team}} ag obair ar {{project}}.",
"emails.invitation.footer": "Is cuma leat? Déan neamhaird den teachtaireacht seo.",
"emails.invitation.thanks": "Go raibh maith agat,",
"emails.invitation.buttonText": "Glac le cuireadh chuig {{team}}",
"emails.invitation.signature": "{{project}} foireann",
"locale.country.unknown": "Neamhaithnid",
"countries.af": "An Afganastáin",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "તમારું ઇમેઇલ સરનામું ચકાસવા માટે આ લિંકને અનુસરો.",
"emails.verification.footer": "જો તમે આ સરનામાંની ચકાસણી કરવાનું ન કહ્યું હોય, તો તમે આ સંદેશને અવગણી શકો છો.",
"emails.verification.thanks": "આભાર,",
"emails.verification.buttonText": "ઇમેઇલ સરનામું ખાતરી કરો",
"emails.verification.signature": "{{project}} ટીમ",
"emails.magicSession.subject": "પ્રવેશ કરો",
"emails.magicSession.hello": "નમસ્કાર,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "તમારો {{project}} પાસવર્ડ ફરીથી સેટ કરવા માટે આ લિંકને અનુસરો.",
"emails.recovery.footer": "જો તમે તમારો પાસવર્ડ ફરીથી સેટ કરવાનું ન કહ્યું હોય, તો તમે આ સંદેશને અવગણી શકો છો.",
"emails.recovery.thanks": "આભાર,",
"emails.recovery.buttonText": "પાસવર્ડ રીસેટ કરો",
"emails.recovery.signature": "{{project}} ટીમ",
"emails.invitation.subject": "%s ટીમને %s પર આમંત્રણ",
"emails.invitation.hello": "નમસ્કાર,",
"emails.invitation.body": "આ મેઇલ તમને મોકલવામાં આવ્યો હતો કારણ કે {{owner}} તમને {{project}} માં {{team}} ટીમના સભ્ય બનવા માટે આમંત્રિત કરવા માંગતા હતો.",
"emails.invitation.footer": "જો તમને રસ નથી, તો તમે આ સંદેશને અવગણી શકો છો.",
"emails.invitation.thanks": "આભાર,",
"emails.invitation.buttonText": "{{team}} નું આમંત્રણ સ્વીકારો",
"emails.invitation.signature": "{{project}} ટીમ",
"locale.country.unknown": "અજાણ",
"countries.af": "અફઘાનિસ્તાન",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "לחץ על קישור זה כדי לאמת את כתובת הדוא\"ל שלך.",
"emails.verification.footer": "אם לא ביקשת לאמת כתובת זו, תוכל להתעלם מהודעה זו.",
"emails.verification.thanks": "תודה,",
"emails.verification.buttonText": "אשר כתובת דוא\"ל",
"emails.verification.signature": "צוות {{project}}",
"emails.magicSession.subject": "כניסה למערכת",
"emails.magicSession.hello": "שלום,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "עקוב אחר קישור זה כדי לאפס את סיסמתך ב-{{project}}.",
"emails.recovery.footer": "אם לא ביקשת לאפס את הסיסמה, תוכל להתעלם מהודעה זו.",
"emails.recovery.thanks": "תודה,",
"emails.recovery.buttonText": "סיסמא איפוס",
"emails.recovery.signature": "צוות {{project}}",
"emails.invitation.subject": "הזמנה לצוות %s ב- %s",
"emails.invitation.hello": "שלום,",
"emails.invitation.body": "דואר זה נשלח אליך מכיוון ש {{owner}} רצה להזמין אותך להיות חבר בצוות {{team}} ב-{{project}}.",
"emails.invitation.footer": "אם אינך מעוניין, תוכל להתעלם מהודעה זו.",
"emails.invitation.thanks": "תודה,",
"emails.invitation.buttonText": "אשר הזמנה ל-{{team}}",
"emails.invitation.signature": "צוות {{project}}",
"locale.country.unknown": "לא ידוע",
"countries.af": "אפגניסטן",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "इस लिंक के माध्यम से अपने ईमेल को सत्यापित कीजिये।",
"emails.verification.footer": "यदि आप इस पते को सत्यापित नहीं करना चाहते हैं, तो आप इस संदेश को नज़रअंदाज़ कर सकते हैं।",
"emails.verification.thanks": "धन्यवाद,",
"emails.verification.buttonText": "ईमेल पता सत्यापित करें",
"emails.verification.signature": "{{project}} टीम",
"emails.magicSession.subject": "लॉग इन",
"emails.magicSession.hello": "नमस्ते,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "इस लिंक के माध्यम से अपना {{project}} पासवर्ड रीसेट करें।",
"emails.recovery.footer": "यदि आप अपना पासवर्ड रीसेट नहीं करना चाहते हैं, तो आप इस संदेश को नज़रअंदाज़ कर सकते हैं।",
"emails.recovery.thanks": "धन्यवाद,",
"emails.recovery.buttonText": "पासवर्ड रीसेट करें",
"emails.recovery.signature": "{{project}} टीम",
"emails.invitation.subject": "%s टीम का यहाँ %s पर आमंत्रण",
"emails.invitation.hello": "नमस्ते,",
"emails.invitation.body": "यह मेल आपको इसलिए भेजा गया है क्योंकि {{owner}} आपको {{team}} टीम का सदस्य बनाना चाहते है, जो {{project}} से जुड़ा हुआ है।",
"emails.invitation.footer": "यदि आप इसमें रूचि नहीं रखते, तो आप इस संदेश को नज़रअंदाज़ कर सकते हैं।",
"emails.invitation.thanks": "धन्यवाद,",
"emails.invitation.buttonText": "{{team}} का निमंत्रण स्वीकार करें",
"emails.invitation.signature": "{{project}} टीम",
"locale.country.unknown": "अज्ञात",
"countries.af": "अफ़ग़ानिस्तान",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Slijedite ovu poveznicu da biste potvrdili svoju adresu e-pošte.",
"emails.verification.footer": "Ukoliko niste zatražili potvrdu ove adrese, možete zanemariti ovu poruku.",
"emails.verification.thanks": "Hvala,",
"emails.verification.buttonText": "Potvrdi adresu e-pošte",
"emails.verification.signature": "{{project}} tim",
"emails.magicSession.subject": "Prijavite se",
"emails.magicSession.hello": "Pozdrav,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Slijedite ovu poveznicu za ponovno postavljanje {{project}} lozinke.",
"emails.recovery.footer": "Ako niste zatražili ponovno postavljanje Vaše lozinke, možete zanemariti ovu poruku.",
"emails.recovery.thanks": "Hvala,",
"emails.recovery.buttonText": "Resetiraj lozinku",
"emails.recovery.signature": "{{project}} tim",
"emails.invitation.subject": "Pozivnica za %s tim na %s",
"emails.invitation.hello": "Pozdrav,",
"emails.invitation.body": "Ova poruka Vam je poslana jer Vas je {{owner}} htio pozvati da postanete član {{team}} tima na {{project}}.",
"emails.invitation.footer": "Ukoliko niste zainteresirani, možete zanemariti ovu poruku.",
"emails.invitation.thanks": "Hvala,",
"emails.invitation.buttonText": "Prihvati pozivnicu za {{team}}",
"emails.invitation.signature": "{{project}} tim",
"locale.country.unknown": "Nepoznato",
"countries.af": "Afganistan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Kattints a linkre, hogy megerősítsd az email címedet.",
"emails.verification.footer": "Ha nem te kérted a címed megerősítését, akkor nyugodtan hagyd figyelmen kívül ezt az üzenetet.",
"emails.verification.thanks": "Köszönettel,",
"emails.verification.buttonText": "E-mail-cím megerősítése",
"emails.verification.signature": "a {{project}} csapat",
"emails.magicSession.subject": "Bejelentkezés",
"emails.magicSession.hello": "Szia,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Kattints a linkre a {{project}} jelszavad visszaállításához.",
"emails.recovery.footer": "Ha nem te kezdeményezted a jelszavad visszaállítását, akkor nyugodtan hagyd figyelmen kívül ezt az üzenetet.",
"emails.recovery.thanks": "Köszönettel,",
"emails.recovery.buttonText": "Jelszó visszaállítása",
"emails.recovery.signature": "a {{project}} csapat",
"emails.invitation.subject": "Meghívó a(z) %s csapatba, a(z) %s projektbe",
"emails.invitation.hello": "Szia,",
"emails.invitation.body": "Ezt a levelet azért kaptad, mert {{owner}} meghívott, hogy légy a {{team}} csapat tagja a {{project}} projektben.",
"emails.invitation.footer": "Ha nem érdekel a lehetőség, nyugodtan hagyd figyelmen kívül ezt az üzenetet.",
"emails.invitation.thanks": "Köszönettel,",
"emails.invitation.buttonText": "Elfogadni meghívást a {{team}-re",
"emails.invitation.signature": "a {{project}} csapat",
"locale.country.unknown": "Ismeretlen",
"countries.af": "Afganisztán",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Ikuti tautan ini untuk memverifikasi alamat email Anda.",
"emails.verification.footer": "Jika Anda tidak meminta untuk memverifikasi alamat email ini, Anda dapat mengabaikan pesan ini.",
"emails.verification.thanks": "Terima kasih,",
"emails.verification.buttonText": "Konfirmasi alamat email",
"emails.verification.signature": "Tim {{project}}",
"emails.magicSession.subject": "Masuk",
"emails.magicSession.hello": "Hai,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Ikuti tautan ini untuk menyetel ulang kata sandi {{project}} Anda.",
"emails.recovery.footer": "Jika Anda tidak meminta untuk menyetel ulang kata sandi, Anda dapat mengabaikan pesan ini.",
"emails.recovery.thanks": "Terima kasih,",
"emails.recovery.buttonText": "Atur ulang kata sandi",
"emails.recovery.signature": "Tim {{project}}",
"emails.invitation.subject": "Undangan ke Tim %s di %s",
"emails.invitation.hello": "Halo,",
"emails.invitation.body": "Email ini dikirimkan kepada Anda karena {{owner}} ingin mengundang Anda untuk menjadi anggota tim {{team}} di {{project}}.",
"emails.invitation.footer": "Jika Anda tidak tertarik, Anda dapat mengabaikan pesan ini.",
"emails.invitation.thanks": "Terima kasih,",
"emails.invitation.buttonText": "Terima undangan ke {{team}}",
"emails.invitation.signature": "Tim {{project}}",
"locale.country.unknown": "Tidak diketahui",
"countries.af": "Afganistan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Clicca questo link per verificare il tuo indirizzo email.",
"emails.verification.footer": "Se non hai richiesto la verifica dellindirizzo email, puoi ignorare questo messaggio.",
"emails.verification.thanks": "Grazie,",
"emails.verification.buttonText": "Confermare l'indirizzo email",
"emails.verification.signature": "Il team {{project}}",
"emails.magicSession.subject": "Login",
"emails.magicSession.hello": "Ciao,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Clicca questo link per reimpostare la tua password di {{project}}.",
"emails.recovery.footer": "Se non hai richiesto la reimpostazione della password, puoi ignorare questo messaggio.",
"emails.recovery.thanks": "Grazie,",
"emails.recovery.buttonText": "Reimposta password",
"emails.recovery.signature": "Il team {{project}}",
"emails.invitation.subject": "Invito al Team %s per %s",
"emails.invitation.hello": "Ciao,",
"emails.invitation.body": "Hai ricevuto questa email perché {{owner}} ti ha invitato a diventare un membro del team {{team}} di {{project}}.",
"emails.invitation.footer": "Ignora questo messaggio se non sei interessatə.",
"emails.invitation.thanks": "Grazie,",
"emails.invitation.buttonText": "Accetta invito a {{team}}",
"emails.invitation.signature": "Il team {{project}}",
"locale.country.unknown": "Sconosciuto",
"countries.af": "Afghanistan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "メールアドレスを有効化するためには下記リンクをクリックして下さい。",
"emails.verification.footer": "このメールに心当たりが無い場合は破棄をお願いいたします。",
"emails.verification.thanks": "ご利用いただきありがとうございます。、",
"emails.verification.buttonText": "メールアドレスを確認する",
"emails.verification.signature": "{{project}}チーム",
"emails.magicSession.subject": "ログイン",
"emails.magicSession.hello": "こんにちは、",
@@ -20,12 +21,14 @@
"emails.recovery.body": "パスワードをリセットするためには下記リンクをクリックしてください。",
"emails.recovery.footer": "このメールに心当たりが無い場合は破棄をお願いいたします。",
"emails.recovery.thanks": "ご利用いただきありがとうございます。、",
"emails.recovery.buttonText": "パスワードをリセット",
"emails.recovery.signature": "{{project}}チーム",
"emails.invitation.subject": "%sチームへの招待が%sから来ました。",
"emails.invitation.hello": "こんにちは、",
"emails.invitation.body": "{{owner}}さんが{{project}}の{{team}}チームにあなたを招待しています。",
"emails.invitation.footer": "このメールに心当たりが無い場合は破棄をお願いいたします。",
"emails.invitation.thanks": "ご利用いただきありがとうございます。、",
"emails.invitation.buttonText": "{{team}}への招待を承諾する",
"emails.invitation.signature": "{{project}}チーム",
"locale.country.unknown": "不明",
"countries.af": "アフガニスタン",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Klik link iki kanggo verifikasi alamat email sampeyan.",
"emails.verification.footer": "Yen sampeyan ora njaluk verifikasi alamat iki, sampeyan iso nglirwakake pesen iki.",
"emails.verification.thanks": "Matur nuwun,",
"emails.verification.buttonText": "Konfirmasi alamat email",
"emails.verification.signature": "Tim {{project}}",
"emails.magicSession.subject": "Masuk",
"emails.magicSession.hello": "Hai,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Klik link iki kanggo setel ulang sandi {{project}}.",
"emails.recovery.footer": "Yen sampeyan ora njaluk setel ulang sandi, sampeyan iso nglirwakake pesen iki.",
"emails.recovery.thanks": "Matur nuwun,",
"emails.recovery.buttonText": "Reset sandhi",
"emails.recovery.signature": "Tim {{project}}",
"emails.invitation.subject": "Undangan ke Tim %s di %s",
"emails.invitation.hello": "Halo,",
"emails.invitation.body": "Email iki dikirim menyang sampeyan amarga {{owner}} pengin ngajak sampeyan dadi anggota tim {{team}} di {{project}}.",
"emails.invitation.footer": "Yen sampeyan ora tertarik, sampeyan iso nglirwakake pesen iki.",
"emails.invitation.thanks": "Matur nuwun,",
"emails.invitation.buttonText": "Tampa undhangan menyang {{team}}",
"emails.invitation.signature": "Tim {{project}}",
"locale.country.unknown": "Ora dingerteni",
"countries.af": "Afghanistan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "ನಿಮ್ಮ ಇಮೇಲ್ ವಿಳಾಸ ಪರಿಶೀಲನೆಗೆ ಈ ಲಿಂಕನ್ನು ಅನುಸರಿಸಿ",
"emails.verification.footer": "ನೀವು ಇಮೇಲ್ ವಿಳಾಸ ಪರಿಶೀಲನೆಗೆ ಕೇಳದಿದ್ದರೆ, ಈ ಸಂದೇಶವನ್ನು ನಿರ್ಲಕ್ಷಿಸಿ",
"emails.verification.thanks": "ಧನ್ಯವಾದಗಳು,",
"emails.verification.buttonText": "ಇಮೇಲ್ ವಿಳಾಸವನ್ನು ದೃಢೀಕರಿಸಿ",
"emails.verification.signature": "{{project}} ತಂಡ",
"emails.magicSession.subject": "ಲಾಗಿನ್",
"emails.magicSession.hello": "ನಮಸ್ಕಾರ,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "ನಿಮ್ಮ {{project}} ಗುಪ್ತಪದವನ್ನು ಮರುಹೊಂದಿಸಲು ಈ ಲಿಂಕನ್ನು ಅನುಸರಿಸಿ",
"emails.recovery.footer": "ನೀವು ಗುಪ್ತಪದವನ್ನು ಮರುಹೊಂದಿಸಲು ಕೇಳದಿದ್ದರೆ, ಈ ಸಂದೇಶವನ್ನು ನಿರ್ಲಕ್ಷಿಸಿ",
"emails.recovery.thanks": "ಧನ್ಯವಾದಗಳು,",
"emails.recovery.buttonText": "ಗುಪ್ತಪದವನ್ನು ಮರುಸೆಟ್ ಮಾಡಿ",
"emails.recovery.signature": "{{project}} ತಂಡ",
"emails.invitation.subject": "%s ತಂಡಕ್ಕೆ %s ರಲ್ಲಿ ಆಹ್ವಾನ",
"emails.invitation.hello": "ನಮಸ್ಕಾರ,",
"emails.invitation.body": "ಈ ಇಮೇಲ್ ನಿಮಗೆ ಬಂದಿದೆ ಏಕೆಂದರೆ {{owner}} ನಿಮ್ಮನ್ನು {{team}} ತಂಡದ {{project}}ರಲ್ಲಿ ಸದಸ್ಯ ಆಗಲಿಕ್ಕೆ ಆಹ್ವಾನಿಸಿದ್ದಾರೆ",
"emails.invitation.footer": "ನಿಮಗೆ ಆಸಕ್ತಿಯಿಲ್ಲದಿದ್ದರೆ, ಈ ಸಂದೇಶವನ್ನು ನಿರ್ಲಕ್ಷಿಸಿ",
"emails.invitation.thanks": "ಧನ್ಯವಾದಗಳು,",
"emails.invitation.buttonText": "{{team}} ಗೆ ಆಹ್ವಾನವನ್ನು ಸ್ವೀಕರಿಸಿ",
"emails.invitation.signature": "{{project}} ತಂಡ",
"locale.country.unknown": "Unknown",
"countries.af": "ಅಫ್ಘಾನಿಸ್ತಾನ",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "이메일 인증을 위해 링크를 클릭하여주세요.",
"emails.verification.footer": "이메일 인증을 부탁하지 않으셨다면 이 메시지를 무시하여주세요.",
"emails.verification.thanks": "감사합니다、",
"emails.verification.buttonText": "이메일 주소를 확인합니다",
"emails.verification.signature": "{{project}} 팀",
"emails.magicSession.subject": "로그인",
"emails.magicSession.hello": "안녕하세요、",
@@ -20,12 +21,14 @@
"emails.recovery.body": "{{project}}의 비밀번호 재설정을 위해 링크를 클릭하여주세요.",
"emails.recovery.footer": "비밀번호 재설정 신청을 하지 않으셨다면 이 메세지를 무시하여주세요.",
"emails.recovery.thanks": "감사합니다、",
"emails.recovery.buttonText": "비밀번호 재설정",
"emails.recovery.signature": "{{project}} 팀",
"emails.invitation.subject": "초대장 %s 팀 - %s",
"emails.invitation.hello": "안녕하세요、",
"emails.invitation.body": "{{owner}}님이 귀하를 {{project}}의 {{team}} 팀으로 초대합니다.",
"emails.invitation.footer": "팀에 합류할 의사가 없으시면 이 메세지를 무시하여주세요.",
"emails.invitation.thanks": "감사합니다、",
"emails.invitation.buttonText": "{{team}} 초대를 수락하기",
"emails.invitation.signature": "{{project}} 팀",
"locale.country.unknown": "알려지지 않은",
"countries.af": "아프가니스탄",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Sequere hanc nexum ut quin inscriptionem tuum.",
"emails.verification.footer": "Si verificationem huius inscriptionis non postulasti, nuntium hunc ignorare potes.",
"emails.verification.thanks": "Gratias,",
"emails.verification.buttonText": "Confirma inscriptionem electronicam",
"emails.verification.signature": "{{project}} Team",
"emails.magicSession.subject": "Log in",
"emails.magicSession.hello": "Salve ibi,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Sequere hanc conjunctionem ut recipias project password {{project}}",
"emails.recovery.footer": "Si tesseram tuam recuperare non petis, nuntium hunc ignorare potes",
"emails.recovery.thanks": "Gratias,",
"emails.recovery.buttonText": "Reset password",
"emails.recovery.signature": "{{project}} team",
"emails.invitation.subject": "Invitatio pro %s in quadrigis %s",
"emails.invitation.hello": "Salve ibi,",
"emails.invitation.body": "Haec inscriptio ad te missa est quia dominus incepto {{owner}} te invitare vult ut membrum {{team}} quadrigis fias ad {{project}}",
"emails.invitation.footer": "Si non quaero, potes hunc nuntium ignorare",
"emails.invitation.thanks": "Gratias,",
"emails.invitation.buttonText": "Accipe invitare ad {{team}}",
"emails.invitation.signature": "{{project}} team",
"locale.country.unknown": "Ignotum",
"countries.af": "Afghanistan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Follegt dëse Link fir Är E -Mail Adress z'iwwerpréiwen.",
"emails.verification.footer": "Wann Dir net gefrot hutt dës Adress z'iwwerpréiwen, kënnt Dir dëse Message ignoréieren.",
"emails.verification.thanks": "Merci,",
"emails.verification.buttonText": "E-Mail-Adress bestätegen",
"emails.verification.signature": "{{project}} équipe",
"emails.magicSession.subject": "Login",
"emails.magicSession.hello": "Hey,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Follegt dëse Link fir Äert {{project}} Passwuert zréckzesetzen.",
"emails.recovery.footer": "Wann Dir net gefrot hutt Äert Passwuert zréckzesetzen, kënnt Dir dëse Message ignoréieren.",
"emails.recovery.thanks": "Merci,",
"emails.recovery.buttonText": "Passwuert zrécksetzen",
"emails.recovery.signature": "{{project}} équipe",
"emails.invitation.subject": "Invitatioun un %s équipe bei %s",
"emails.invitation.hello": "Hallo,",
"emails.invitation.body": "Dës E -Mail gouf un Iech geschéckt well {{owner}} Iech invitéiere wëllt fir Member vum {{team}} Team bei {{project}} ze ginn.",
"emails.invitation.footer": "Wann Dir net interesséiert sidd, kënnt Dir dëse Message ignoréieren.",
"emails.invitation.thanks": "Merci,",
"emails.invitation.buttonText": "Invitatioun bei {{team}} akzeptéieren",
"emails.invitation.signature": "{{project}} équipe",
"locale.country.unknown": "Onbekannt",
"countries.af": "Afghanistan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Spauskite šią nuorodą, kad patvirtintumėte savo el. paštą.",
"emails.verification.footer": "Jei neprašėte patvirtinti šio el. pašto, galite ignoruoti šį pranešimą.",
"emails.verification.thanks": "Ačiū,",
"emails.verification.buttonText": "Patvirtinti el. pašto adresą",
"emails.verification.signature": "{{project}} komanda",
"emails.magicSession.subject": "Prisijungti",
"emails.magicSession.hello": "Labas,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Spauskite šią nuorodą, kad atkurtumėte projekto {{project}} slaptažodį.",
"emails.recovery.footer": "Jei neprašėte atkurti savo slaptažodzio, galite ignoruoti šį pranešimą.",
"emails.recovery.thanks": "Ačiū,",
"emails.recovery.buttonText": "Atstatyti slaptažodį",
"emails.recovery.signature": "{{project}} komanda",
"emails.invitation.subject": "Pakvietimas į %s komandą %s projekte",
"emails.invitation.hello": "Labas,",
"emails.invitation.body": "Šis el. laiškas buvo atsiųstas jums, nes {{owner}} norėjo jus pakviesti tapti projekto {{project}} dalimi {{team}} komandoje.",
"emails.invitation.footer": "Jei jūsų tai nedomina, galite ignoruoti šį pranešimą.",
"emails.invitation.thanks": "Ačiū,",
"emails.invitation.buttonText": "Priimti kvietimą į {{team}}",
"emails.invitation.signature": "{{project}} komanda",
"locale.country.unknown": "Nežinoma",
"countries.af": "Afganistanas",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Sekojiet saitei, lai apstiprinātu savu e-pasta adresi.",
"emails.verification.footer": "Ja Jūs nepieprasījāt šīs adreses apstiprinājumu, lūdzu, ignorējiet šo ziņu.",
"emails.verification.thanks": "Paldies,",
"emails.verification.buttonText": "Apstiprināt e-pasta adresi",
"emails.verification.signature": "{{project}} komanda",
"emails.magicSession.subject": "Ieiet",
"emails.magicSession.hello": "Sveicināti,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Sekojiet saitei, lai atjauninātu {{project}} paroli.",
"emails.recovery.footer": "Ja Jūs nepieprasījāt paroles atjaunināšanu, lūdzu, ignorējiet šo ziņu.",
"emails.recovery.thanks": "Paldies,",
"emails.recovery.buttonText": "Atiestatīt paroli",
"emails.recovery.signature": "{{project}} komanda",
"emails.invitation.subject": "Ielūgums piebiedroties %s komandai %s projektā.",
"emails.invitation.hello": "Labdien,",
"emails.invitation.body": "Šis e-pasts tika nosūtīts Jums, jo {{owner}} vēlējās Jūs ielūgt kļūt par {{team}} komandas biedru {{project}} projektā.",
"emails.invitation.footer": "Ja Jūs neesat ieinteresēts, lūdzu, ignorējiet šo ziņu.",
"emails.invitation.thanks": "Paldies,",
"emails.invitation.buttonText": "Pieņemt ielūgumu uz {{team}}",
"emails.invitation.signature": "{{project}} komanda",
"locale.country.unknown": "Nav zināms",
"countries.af": "Afganistāna",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "നിങ്ങളുടെ ഇമെയിൽ വിലാസം സ്ഥിരീകരിക്കുന്നതിനായി ഈ ലിങ്ക് പിന്തുടരുക.",
"emails.verification.footer": "ഈ വിലാസം സ്ഥിരീകരിക്കാന്‍ നിങ്ങൾ ആവശ്യപ്പെട്ടില്ലെങ്കിൽ, നിങ്ങൾക്ക് ഈ സന്ദേശം അവഗണിക്കാവുന്നതാണ്.",
"emails.verification.thanks": "നന്ദി,",
"emails.verification.buttonText": "ഇമെയിൽ വിലാസം സ്ഥിരീകരിക്കുക",
"emails.verification.signature": "{{project}} ടീം",
"emails.magicSession.subject": "ലോഗിൻ",
"emails.magicSession.hello": "നമസ്കാരം,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "നിങ്ങളുടെ {{Project}} രഹസ്യവാക്ക് പുനക്രമീകരിക്കുന്നതിന് ഈ ലിങ്ക് പിന്തുടരുക.",
"emails.recovery.footer": "നിങ്ങളുടെ രഹസ്യവാക്ക് പുനക്രമീകരിക്കാന്‍ നിങ്ങൾ ആവശ്യപ്പെട്ടില്ലെങ്കിൽ, ഈ സന്ദേശം അവഗണിക്കാവുന്നതാണ്.",
"emails.recovery.thanks": "നന്ദി,",
"emails.recovery.buttonText": "പാസ്‌വേഡ് റീസെറ്റ് ചെയ്യുക",
"emails.recovery.signature": "{{project}} ടീം",
"emails.invitation.subject": "%s -ലെ %s ടീമിലേക്കുള്ള ക്ഷണം",
"emails.invitation.hello": "നമസ്കാരം,",
"emails.invitation.body": "നിങ്ങളെ {{project}} -ലെ {{team}} ടീമിലെ അംഗമാകുവാന്‍ ക്ഷണിക്കാൻ {{owner}} ആഗ്രഹിക്കുന്നതിനാലാണ് ഈ മെയിൽ നിങ്ങൾക്ക് അയക്കുന്നത്.",
"emails.invitation.footer": "നിങ്ങൾക്ക് താൽപ്പര്യമില്ലെങ്കിൽ, ഈ സന്ദേശം അവഗണിക്കാവുന്നതാണ്.",
"emails.invitation.thanks": "നന്ദി,",
"emails.invitation.buttonText": "{{team}} ലേക്കുള്ള ക്ഷണം സ്വീകരിക്കുക",
"emails.invitation.signature": "{{project}} ടീം",
"locale.country.unknown": "Unknown",
"countries.af": "അഫ്ഗാനിസ്ഥാൻ",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "आपला ईमेल पत्ता सत्यापित करण्यासाठी या दुव्याचे अनुसरण करा.",
"emails.verification.footer": "आपण या पत्त्याची पडताळणी करण्यास सांगितले नसल्यास, आपण या संदेशाकडे दुर्लक्ष करू शकता.",
"emails.verification.thanks": "धन्यवाद,",
"emails.verification.buttonText": "ईमेल पत्ता सत्यापित करा",
"emails.verification.signature": "{{project}} संघ",
"emails.magicSession.subject": "लॉगिन करा",
"emails.magicSession.hello": "नमस्कार ,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "आपला {{project}}चे पासवर्ड रीसेट करण्यासाठी या लिंकचे अनुसरण करा",
"emails.recovery.footer": "आपण आपला पासवर्ड रीसेट करण्यास सांगितले नसल्यास, आपण या संदेशाकडे दुर्लक्ष करू शकता.",
"emails.recovery.thanks": "धन्यवाद,",
"emails.recovery.buttonText": "पासवर्ड रीसेट करा",
"emails.recovery.signature": "{{project}} संघ",
"emails.invitation.subject": "%s संघ %s येथे सामील होण्यासाठी आमंत्रण",
"emails.invitation.hello": "नमस्कार,",
"emails.invitation.body": "हा मेल तुम्हाला पाठवला होता कारण {{owner}} तुम्हाला {{project}} येथे {{team}} टीमचे सदस्य होण्यासाठी आमंत्रित करू इच्छित होते.",
"emails.invitation.footer": "आपल्याला स्वारस्य नसल्यास, आपण या संदेशाकडे दुर्लक्ष करू शकता.",
"emails.invitation.thanks": "धन्यवाद,",
"emails.invitation.buttonText": "{{team}} साठी आमंत्रण स्वीकारा",
"emails.invitation.signature": "{{project}} संघ",
"locale.country.unknown": "अज्ञात",
"countries.af": "अफगानिस्तान",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Tekan pautan ini untuk mengesahkan alamat email anda.",
"emails.verification.footer": "Sekiranya anda tidak membuat permintaan untuk mengesahkan email ini, sila abaikan mesej ini.",
"emails.verification.thanks": "Terima kasih,",
"emails.verification.buttonText": "Sahkan alamat email",
"emails.verification.signature": "{{project}} team",
"emails.magicSession.subject": "Log masuk",
"emails.magicSession.hello": "Hey,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Tekan pautan ini untuk menetapkan semula kata laluan {{project}}.",
"emails.recovery.footer": "Sekiranya anda tidak membuat permintaan menetap semula kata laluan, sila abaikan mesej ini.",
"emails.recovery.thanks": "Terima kasih,",
"emails.recovery.buttonText": "Tetapkan semula kata laluan",
"emails.recovery.signature": "{{project}} team",
"emails.invitation.subject": "Jemputan ke pasukan %s di %s",
"emails.invitation.hello": "Hello,",
"emails.invitation.body": "Anda menerima mel ini kerana {{owner}} ingin menjemput anda untuk menjadi ahli pasukan {{team}} di {{project}}.",
"emails.invitation.footer": "Sekiranya anda tidak berminat, sila abaikan mesej ini.",
"emails.invitation.thanks": "Terima kasih,",
"emails.invitation.buttonText": "Terima jemputan ke {{team}}",
"emails.invitation.signature": "{{project}} team",
"locale.country.unknown": "Tidak Diketahui",
"countries.af": "Afghanistan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Følg denne lenken for å bekrefte din e-postadresse.",
"emails.verification.footer": "Dersom du ikke ba om å bekrefte e-postadressen, kan du se bort fra denne meldingen.",
"emails.verification.thanks": "Takk,",
"emails.verification.buttonText": "Bekreft e-postadresse",
"emails.verification.signature": "{{project}} team",
"emails.magicSession.subject": "Pålogging",
"emails.magicSession.hello": "Hei,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Følg denne lenken for å nullstille ditt {{project}} passord.",
"emails.recovery.footer": "Dersom du ikke ba om å nullstille passordet ditt, kan du se bort fra denne meldingen.",
"emails.recovery.thanks": "Takk,",
"emails.recovery.buttonText": "Tilbakestill passord",
"emails.recovery.signature": "{{project}} team",
"emails.invitation.subject": "Invitasjon til %s Team ved %s",
"emails.invitation.hello": "Hei,",
"emails.invitation.body": "Denne meldingen ble sendt til deg fordi {{owner}} ønsket å invitere deg til å bli medlem av {{team}} team ved {{project}}.",
"emails.invitation.footer": "Dersom du ikke er interessert, kan du se bort fra denne meldingen.",
"emails.invitation.thanks": "Takk,",
"emails.invitation.buttonText": "Godta invitasjon til {{team}}",
"emails.invitation.signature": "{{project}} team",
"locale.country.unknown": "Ukjent",
"countries.af": "Afghanistan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "इमेल ठेगाना प्रमाणित गर्नको लागी यो लिंकमा जानुहोस।",
"emails.verification.footer": "यदि तपाइँले आफ्नो खाता प्रमाणित गर्न सोध्नु भएको छैन भने तपाइँले यो सन्देश लाई बेवास्ता गर्न सक्नुहुन्छ।",
"emails.verification.thanks": "धन्यवाद,",
"emails.verification.buttonText": "इमेल ठेगाना पुष्टि गर्नुहोस्",
"emails.verification.signature": "{{project}} समूह",
"emails.magicSession.subject": "लगइन",
"emails.magicSession.hello": "नमस्ते,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "{{project}}को पासवर्ड रिसेट गर्नको लागी यो लिंकमा जानुहोस।",
"emails.recovery.footer": "यदि तपाइँले आफ्नो पासवर्ड रिसेट गर्न सोध्नु भएको छैन भने तपाइँले यो सन्देश लाई बेवास्ता गर्न सक्नुहुन्छ।",
"emails.recovery.thanks": "धन्यवाद,",
"emails.recovery.buttonText": "रिसेट पासवर्ड",
"emails.recovery.signature": "{{project}} समूह",
"emails.invitation.subject": "%s समूहको लागि %s मा निमन्त्रणा",
"emails.invitation.hello": "नमस्ते,",
"emails.invitation.body": "{{owner}}ले तपाइँलाई {{project}}मा {{team}}को सदस्य बन्न आमन्त्रित गर्न चाहनु भएको छ। त्येसैले तपाइँलाई यो सन्देश पठाइएको हो।",
"emails.invitation.footer": "यदि तपाइँ इच्छुक हुनुहुन्न भने, तपाइँले यो सन्देशलाई बेवास्ता गर्न सक्नुहुन्छ।",
"emails.invitation.thanks": "धन्यवाद,",
"emails.invitation.buttonText": "{{team}} मा निमन्त्रणा स्वीकार गर्नुहोस्",
"emails.invitation.signature": "{{project}} समूह",
"locale.country.unknown": "अज्ञात",
"countries.af": "अफगानिस्तान",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Volg deze link om uw e-mail te verifieren",
"emails.verification.footer": "Als u geen aanvraag voor verificatie heeft gemaakt, kan u deze mail negeren",
"emails.verification.thanks": "Bedankt,",
"emails.verification.buttonText": "Bevestig e-mailadres",
"emails.verification.signature": "{{project}} team",
"emails.magicSession.subject": "Login",
"emails.magicSession.hello": "Hoi,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Volg deze link om het wachtwoord van uw project {{project}} te wijzigen",
"emails.recovery.footer": "Als u geen aanvraag heeft gemaakt om uw wachtwoord te wijzigen, kan u deze mail negeren",
"emails.recovery.thanks": "Bedankt,",
"emails.recovery.buttonText": "Wachtwoord opnieuw instellen",
"emails.recovery.signature": "{{project}} team",
"emails.invitation.subject": "Uitnodiging van %s Team uit %s",
"emails.invitation.hello": "Hallo,",
"emails.invitation.body": "U ontvangt deze mail want u was uitgenodig door {{owner}} om lid van het {{team}} team te worden in {{project}} ",
"emails.invitation.footer": "Als u niet geintereseerd bent, kan u deze mail negeren.",
"emails.invitation.thanks": "Bedankt,",
"emails.invitation.buttonText": "Uitnodiging voor {{team}} accepteren",
"emails.invitation.signature": "{{project}} team",
"locale.country.unknown": "Onbekend",
"countries.af": "Afghanistan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Følg denne lenkja for å bekrefta din e-postadresse.",
"emails.verification.footer": "Om du ikkje bad om å bekrefta e-postadressa, kan du ignorera denne meldinga.",
"emails.verification.thanks": "Takk,",
"emails.verification.buttonText": "Stadfest e-postadresse",
"emails.verification.signature": "{{project}} team",
"emails.magicSession.subject": "Pålogging",
"emails.magicSession.hello": "Hei,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Følg denne lenkja for å nullstilla ditt {{project}} passord.",
"emails.recovery.footer": "Om du ikkje ba om å nullstilla passordet ditt, kan du ignorera denne meldinga.",
"emails.recovery.thanks": "Takk,",
"emails.recovery.buttonText": "Nullstill passord",
"emails.recovery.signature": "{{project}} team",
"emails.invitation.subject": "Innbyding til %s Team ved %s",
"emails.invitation.hello": "Hallo,",
"emails.invitation.body": "Denne meldinga ble sendt til deg fordi {{owner}} ynskja å invitera deg til å bli medlem av {{team}} team i {{project}}.",
"emails.invitation.footer": "Om du ikkje er interessert, kan du ignorera denne meldinga.",
"emails.invitation.thanks": "Takk,",
"emails.invitation.buttonText": "Godta invitasjon til {{team}}",
"emails.invitation.signature": "{{project}} team",
"locale.country.unknown": "Ukjend",
"countries.af": "Afghanistan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "ଆପଣଙ୍କର ଇମେଲ୍ ଠିକଣା ଯାଞ୍ଚ କରିବାକୁ ଏହି ଲିଙ୍କ୍ ଅନୁସରଣ କରନ୍ତୁ |",
"emails.verification.footer": "ଯଦି ଆପଣ ଏହି ଠିକଣା ଯାଞ୍ଚ କରିବାକୁ କହି ନାହାଁନ୍ତି, ତେବେ ଆପଣ ଏହି ସନ୍ଦେଶକୁ ଉପେକ୍ଷା କରିପାରିବେ |",
"emails.verification.thanks": "ଧନ୍ୟବାଦ,",
"emails.verification.buttonText": "ଇମେଲ ଠିକଣା ନିଶ୍ଚିତ କରନ୍ତୁ",
"emails.verification.signature": "{{project}} ଦଳ",
"emails.magicSession.subject": "ଲଗଇନ୍ କରନ୍ତୁ",
"emails.magicSession.hello": "ନମସ୍କାର,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "ଆପଣଙ୍କର {{project}} ପାସୱାର୍ଡ ପୁନଃ ସେଟ୍ କରିବାକୁ ଏହି ଲିଙ୍କକୁ ଅନୁସରଣ କରନ୍ତୁ |",
"emails.recovery.footer": "ଯଦି ଆପଣ ଆପଣଙ୍କର ପାସୱାର୍ଡ ପୁନଃ ସେଟ୍ କରିବାକୁ କହି ନାହାଁନ୍ତି, ତେବେ ଆପଣ ଏହି ସନ୍ଦେଶକୁ ଉପେକ୍ଷା କରିପାରିବେ |",
"emails.recovery.thanks": "ଧନ୍ୟବାଦ,",
"emails.recovery.buttonText": "ପାସୱାର୍ଡ ପୁନଃସେଟ୍ କରନ୍ତୁ",
"emails.recovery.signature": "{{project}} ଦଳ",
"emails.invitation.subject": "%s ରେ %s ଦଳକୁ ନିମନ୍ତ୍ରଣ |",
"emails.invitation.hello": "ନମସ୍କାର,",
"emails.invitation.body": "ଏହି ମେଲ୍ ଆପଣଙ୍କୁ ପଠାଯାଇଥିଲା କାରଣ {{owner}} ଆପଣଙ୍କୁ {{project} ରେ {{team}} ଦଳର ସଦସ୍ୟ ହେବାକୁ ଆମନ୍ତ୍ରଣ କରିବାକୁ ଚାହୁଁଥିଲେ |",
"emails.invitation.footer": "ଯଦି ଆପଣ ଆଗ୍ରହୀ ନୁହଁନ୍ତି, ଆପଣ ଏହି ସନ୍ଦେଶକୁ ଅଣଦେଖା କରିପାରିବେ |",
"emails.invitation.thanks": "ଧନ୍ୟବାଦ,",
"emails.invitation.buttonText": "{{team}} ପାଇଁ ଆମନ୍ତ୍ରଣ ଗ୍ରହଣ କରନ୍ତୁ",
"emails.invitation.signature": "{{project}} ଦଳ",
"locale.country.unknown": "ଅଜ୍ଞାତ",
"countries.af": "ଆଫଗାନିସ୍ତାନ",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Przejdź do tego linku, aby zweryfikować swój adres e-mail.",
"emails.verification.footer": "Jeśli to nie Ty prosiłeś o zweryfikowanie tego adresu, zignoruj tę wiadomość.",
"emails.verification.thanks": "Dziękujemy,",
"emails.verification.buttonText": "Potwierdź adres e-mail",
"emails.verification.signature": "Zespół {{project}}",
"emails.magicSession.subject": "Logowanie",
"emails.magicSession.hello": "Cześć,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Przejdź do tego linku, aby zresetować hasło dla {{project}}.",
"emails.recovery.footer": "Jeśli to nie Ty prosiłeś o zresetowanie swojego hasła, zignoruj tę wiadomość.",
"emails.recovery.thanks": "Dziękujemy,",
"emails.recovery.buttonText": "Zresetuj hasło",
"emails.recovery.signature": "Zespół {{project}}",
"emails.invitation.subject": "Zaproszenie do zespołu %s w %s",
"emails.invitation.hello": "Cześć,",
"emails.invitation.body": "Otrzymujesz tę wiadomość, ponieważ {{owner}} zaprasza Cię do grona członków zespołu {{team}} w projekcie {{project}}.",
"emails.invitation.footer": "Jeśli nie jesteś zainteresowany, zignoruj tę wiadomość.",
"emails.invitation.thanks": "Dziękujemy,",
"emails.invitation.buttonText": "Zaakceptuj zaproszenie do {{team}}",
"emails.invitation.signature": "Zespół {{project}}",
"locale.country.unknown": "Nieznany",
"countries.af": "Afganistan",
@@ -8,6 +8,7 @@
"emails.verification.body": "Clique neste link para verificar o seu endereço de e-mail.",
"emails.verification.footer": "Se você não solicitou a verificação deste e-mail, ignore essa mensagem.",
"emails.verification.thanks": "Muito obrigado,",
"emails.verification.buttonText": "Confirmar endereço de e-mail",
"emails.verification.signature": "Time {{project}}",
"emails.magicSession.subject": "Login",
"emails.magicSession.hello": "Olá,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Clique neste link para redefinir sua senha do {{project}}.",
"emails.recovery.footer": "Se você não solicitou a redefinição da sua senha, você pode ignorar essa mensagem.",
"emails.recovery.thanks": "Muito obrigado,",
"emails.recovery.buttonText": "Redefinir senha",
"emails.recovery.signature": "Time {{project}}",
"emails.invitation.subject": "Convite para o Time %s em %s",
"emails.invitation.hello": "Olá,",
"emails.invitation.body": "Este e-mail foi enviado porque {{owner}} deseja convidar você a se tornar membro do Time {{team}} em {{project}}.",
"emails.invitation.footer": "Caso não tenha interesse, ignore essa mensagem.",
"emails.invitation.thanks": "Muito obrigado,",
"emails.invitation.buttonText": "Aceitar convite para {{team}}",
"emails.invitation.signature": "Time {{project}}",
"locale.country.unknown": "Desconhecido",
"countries.af": "Afeganistão",
@@ -8,6 +8,7 @@
"emails.verification.body": "Siga esta ligação para verificar o seu endereço de correio electrónico.",
"emails.verification.footer": "Se não pediu para verificar este endereço, pode ignorar esta mensagem.",
"emails.verification.thanks": "Obrigado,",
"emails.verification.buttonText": "Confirmar endereço de email",
"emails.verification.signature": "Equipa {{project}}",
"emails.magicSession.subject": "Login",
"emails.magicSession.hello": "Olá ,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Utilize este link para redefinir a palavra-passe do seu projecto {{project}}",
"emails.recovery.footer": "Se não pediu para redefinir a sua palavra-passe, pode ignorar esta mensagem.",
"emails.recovery.thanks": "Obrigado,",
"emails.recovery.buttonText": "Repor palavra-passe",
"emails.recovery.signature": "Equipa {{project}}",
"emails.invitation.subject": "Convite à equipa de %s às %s",
"emails.invitation.hello": "Olá,",
"emails.invitation.body": "Este correio foi-lhe enviado porque {{owner}} queria convidá-lo a tornar-se membro da equipa {{team}} da {{project}}.",
"emails.invitation.footer": "Se não estiver interessado, pode ignorar esta mensagem.",
"emails.invitation.thanks": "Obrigado,",
"emails.invitation.buttonText": "Aceitar convite para o {{team}}",
"emails.invitation.signature": "Equipa {{project}}",
"locale.country.unknown": "Desconhecido",
"countries.af": "Afeganistão",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Click pe acest link pentru a valida adresa de email.",
"emails.verification.footer": "Dacă nu ai cerut validarea adresei de email, poți ignora acest mesaj.",
"emails.verification.thanks": "Mulțumim,",
"emails.verification.buttonText": "Confirmă adresa de email",
"emails.verification.signature": "Echipa {{project}}",
"emails.magicSession.subject": "Login",
"emails.magicSession.hello": "Bună ziua,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Click aici pentru a reseta parola pentru {{project}}",
"emails.recovery.footer": "Dacă nu ai cerut să îți schimbi parola, ignoră acest mesaj.",
"emails.recovery.thanks": "Mulțumim,",
"emails.recovery.buttonText": "Resetează parola",
"emails.recovery.signature": "Echipa {{project}}",
"emails.invitation.subject": "Invitatie catre %s Echipa la %s",
"emails.invitation.hello": "Bună ziua,",
"emails.invitation.body": "Acest email a fost trimis pentru că {{owner}} a vrut ca tu să devii membru al echipei {{team}} la {{project}}.",
"emails.invitation.footer": "Dacă nu esti interesat, poți ignora acest email.",
"emails.invitation.thanks": "Mulțumim,",
"emails.invitation.buttonText": "Acceptă invitația la {{team}}",
"emails.invitation.signature": "Echipa {{project}}",
"locale.country.unknown": "Necunoscut",
"countries.af": "Afghanistan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Перейдите по ссылке, чтобы подтвердить свой адрес электронной почты.",
"emails.verification.footer": "Если вы не запрашивали подтверждение этого адреса, проигнорируйте это сообщение.",
"emails.verification.thanks": "Спасибо,",
"emails.verification.buttonText": "Подтвердить адрес электронной почты",
"emails.verification.signature": "команда {{project}}",
"emails.magicSession.subject": "Логин",
"emails.magicSession.hello": "Здравствуйте,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Перейдите по этой ссылке для того чтобы сбросить свой пароль для проекта {{project}}",
"emails.recovery.footer": "Если вы не запрашивали сброс пароля, проигнорируйте это сообщение.",
"emails.recovery.thanks": "Спасибо,",
"emails.recovery.buttonText": "Сбросить пароль",
"emails.recovery.signature": "команда {{project}}",
"emails.invitation.subject": "Приглашение в команду %s по проекту %s",
"emails.invitation.hello": "Здравствуйте,",
"emails.invitation.body": "Это письмо отправлено вам, потому что {{owner}} приглашает стать членом команды {{team}} в проекте {{project}}.",
"emails.invitation.footer": "Если вы не заинтересованы, проигнорируйте это сообщение.",
"emails.invitation.thanks": "Спасибо,",
"emails.invitation.buttonText": "Принять приглашение в {{team}}",
"emails.invitation.signature": "команда {{project}}",
"locale.country.unknown": "Неизвестно",
"countries.af": "Афганистан",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "ई-पत्रनिर्णायनार्थमिदं संयोगसूत्रमनुसरतु।",
"emails.verification.footer": "यदि अस्य संकेतस्य निर्णायनं नेष्यते तर्हि वात्र्तामिमामुपेक्षताम्‌।",
"emails.verification.thanks": "धन्यवादः,",
"emails.verification.buttonText": "ईमेल-पत्त्रं सुनिश्चित करें",
"emails.verification.signature": "{{project}} गणः",
"emails.magicSession.subject": "संप्रवेशः",
"emails.magicSession.hello": "अयि,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "{{project}} कूटशब्दपुनयाेजनाय संयोगमेनमनुसरतु।",
"emails.recovery.footer": "यदि कूटशब्दस्य पुनयाेजनं नेष्यते तर्हि वात्र्तामिमामुपेक्षताम्‌।",
"emails.recovery.thanks": "धन्यवादः,",
"emails.recovery.buttonText": "गुप्तशब्दं पुनः स्थापित करें",
"emails.recovery.signature": "{{project}} गणः",
"emails.invitation.subject": "गणस्य आमन्त्रणम्‌ %s इति %s",
"emails.invitation.hello": "अयि भो,",
"emails.invitation.body": "{{owner}} {{team}} गणे {{project}} मध्ये भवद्योगदानमच्छितीति हेतोः पत्रमदिं भवत्सकाशं प्रेषतिम्।",
"emails.invitation.footer": "यदि भवदनिच्छा तर्हि वात्र्तामिमामुपेक्षताम्‌।",
"emails.invitation.thanks": "धन्यवादः,",
"emails.invitation.buttonText": "{{team}} निमन्त्रणं स्वीकुरुत",
"emails.invitation.signature": "{{project}} गणः",
"locale.country.unknown": "अज्ञातम्‌ ",
"countries.af": "आफगानिस्थानम्‌",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "پنھنجي اي ميل ايڊريس جي تصديق ڪرڻ لاءِ ھن لنڪ تي عمل ڪريو.",
"emails.verification.footer": "جيڪڏھن توھان نه پ askيا ھئا ھن ايڊريس جي تصديق ڪرڻ لاءِ ، توھان نظر انداز ڪري سگھوٿا ھن پيغام کي.",
"emails.verification.thanks": "مهرباني,",
"emails.verification.buttonText": "اي ميل پتو تصديق ڪريو",
"emails.verification.signature": "{{project}} ٽيم",
"emails.magicSession.subject": "لاگ ان",
"emails.magicSession.hello": "هي ,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "ھن لنڪ تي عمل ڪريو پنھنجو {{project}} پاسورڊ ري سيٽ ڪرڻ لاءِ.",
"emails.recovery.footer": "جيڪڏھن توھان نه پ پيو ھو پنھنجي پاسورڊ کي ري سيٽ ڪرڻ لاءِ ، توھان نظر انداز ڪري سگھوٿا ھن پيغام کي.",
"emails.recovery.thanks": "مهرباني,",
"emails.recovery.buttonText": "پاسورڊ ري سيٽ ڪريو",
"emails.recovery.signature": "{{project}} ٽيم",
"emails.invitation.subject": "%s ٽيم %s تيجي دعوت",
"emails.invitation.hello": "هيلو,",
"emails.invitation.body": "ھي اي ميل توھان ڏانھن موڪليو ويو آھي {اڪاڻ ته {{owner}} توھان کي دعوت ڏيڻ چاھي ٿو ته توھان {{team}} ٽيم جو ميمبر بڻجي {{project}} تي.",
"emails.invitation.footer": "جيڪڏھن توھان دلچسپي نٿا رکو ، توھان نظر انداز ڪري سگھوٿا ھن پيغام کي.",
"emails.invitation.thanks": "مهرباني,",
"emails.invitation.buttonText": "{{team}} جي دعوت قبول ڪريو",
"emails.invitation.signature": "{{project}} ٽيم",
"locale.country.unknown": "نامعلوم",
"countries.af": "افغانستان",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "ඔබගේ විද්‍යුත් තැපැල් ලිපිනය සත්‍යාපනය කිරීමට මෙම සම්බන්ධකය අනුගමනය කරන්න.",
"emails.verification.footer": "මෙම ලිපිනය සත්‍යාපනය කරන ලෙස ඔබ ඉල්ලුවේ නැත්නම්, ඔබට මෙම පණිවිඩය නොසලකා හැරිය හැක.",
"emails.verification.thanks": "ස්තුතියි,",
"emails.verification.buttonText": "ඊමේල් ලිපිනය තහවුරු කරන්න",
"emails.verification.signature": "{{project}} කණ්ඩායම",
"emails.magicSession.subject": "ප්‍රවේශ වන්න",
"emails.magicSession.hello": "හේයි,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "ඔබගේ {{project}} මුරපදය නැවත සැකසීමට මෙම සම්බන්ධකය අනුගමනය කරන්න.",
"emails.recovery.footer": "ඔබගේ මුරපදය නැවත සකසන ලෙස ඔබ ඉල්ලුවේ නැත්නම්, ඔබට මෙම පණිවිඩය නොසලකා හැරිය හැක.",
"emails.recovery.thanks": "ස්තුතියි,",
"emails.recovery.buttonText": "මුරපදය යළි පිහිටුවන්න",
"emails.recovery.signature": "{{project}} කණ්ඩායම",
"emails.invitation.subject": "%s කණ්ඩායමට ආරාධනා %s හි",
"emails.invitation.hello": "ආයුබෝවන්,",
"emails.invitation.body": "මෙම තැපැල් ඔබට එව්වේ, {{owner}} හට {{project}} හි {{team}} කණ්ඩායමේ සාමාජිකයෙකු වීමට ඔබට ආරාධනා කිරීමට අවශ්‍ය වූ බැවිනි.",
"emails.invitation.footer": "ඔබ උනන්දුවක් නොදක්වන්නේ නම්, ඔබට මෙම පණිවිඩය නොසලකා හැරිය හැක.",
"emails.invitation.thanks": "ස්තුතියි,",
"emails.invitation.buttonText": "{{team}} සඳහා ආරාධනය පිළිගෙනින්න",
"emails.invitation.signature": "{{project}} කණ්ඩායම",
"locale.country.unknown": "නොදන්නා",
"countries.af": "ඇෆ්ගනිස්ථානය",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Použi tento link pre overenie svojej emailovej adresy.",
"emails.verification.footer": "Ak si nepožiadal o overenie tejto adresy, môžeš túto správu ignorovať.",
"emails.verification.thanks": "Ďakujeme.,",
"emails.verification.buttonText": "Potvrďte e-mailovú adresu",
"emails.verification.signature": "{{project}} tím",
"emails.magicSession.subject": "Prihlásenie",
"emails.magicSession.hello": "Ahoj,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Použi tento link pre obnovenie svojho {{project}} hesla.",
"emails.recovery.footer": "Ak si nepožiadal o obnovu svojho hesla, túto správu môžeš ignorovať.",
"emails.recovery.thanks": "Ďakujeme,",
"emails.recovery.buttonText": "Obnoviť heslo",
"emails.recovery.signature": "{{project}} tím",
"emails.invitation.subject": "Pozvánka do %s Tímu v %s",
"emails.invitation.hello": "Ahoj,",
"emails.invitation.body": "Tento email ti bol zaslaný, pretože {{owner}} ťa pozval, aby si sa stal členom {{team}} tímu v projekte {{project}}.",
"emails.invitation.footer": "Ak nemáš záujem, môžeš túto správu ignorovať.",
"emails.invitation.thanks": "Ďakujeme,",
"emails.invitation.buttonText": "Prijať pozvánku do {{team}}",
"emails.invitation.signature": "{{project}} tím",
"locale.country.unknown": "Neznámy",
"countries.af": "Afganistan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Tevedza chinongedzo ichi kuti uratidze kuti kero iyi ndeyako.",
"emails.verification.footer": "Kana usina kukumbira kuti uratidze kuti kero iyi ndeyako, unogona kufuratira meseji iyi.",
"emails.verification.thanks": "Ndatenda,",
"emails.verification.buttonText": "Simbisa kero yeemail",
"emails.verification.signature": "Chikwata che{{project}}",
"emails.magicSession.subject": "Pinda",
"emails.magicSession.hello": "Hesi,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Baya chinongedzo ichi kuti uchinje pasiwedhi yako ye{{project}}.",
"emails.recovery.footer": "Kana usina kukumbira kuchinja pasiwedhi yako, unogona kufuratira meseji iyi.",
"emails.recovery.thanks": "Ndatenda,",
"emails.recovery.buttonText": "Gadzirisa password",
"emails.recovery.signature": "Chikwata che{{project}}",
"emails.invitation.subject": "Kukokwa kuchikwata che%s ku%s",
"emails.invitation.hello": "Mhoro,",
"emails.invitation.body": "Tsamba iyi yatumirwa kwauri nekuti {{owner}} anga achida kuti uve nhengo yechikwata che{{team}} pachirongwa che{{project}}.",
"emails.invitation.footer": "Kana usiri kufarira kuve nhengo yechikwata ichi, unogona kufuratira meseji iyi.",
"emails.invitation.thanks": "Ndatenda,",
"emails.invitation.buttonText": "Gamuchira kukokwa ku {{team}}",
"emails.invitation.signature": "Chikwata che{{project}}",
"locale.country.unknown": "Haizivikanwe",
"countries.af": "Afuganisitani",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Klicka på denna länk för att verifiera din email",
"emails.verification.footer": "Om du inte bad om att verifiera den här e-postadressen kan du ignorera detta mail.",
"emails.verification.thanks": "Tack,",
"emails.verification.buttonText": "Bekräfta e-postadress",
"emails.verification.signature": "{{project}} teamet",
"emails.magicSession.subject": "Logga in",
"emails.magicSession.hello": "Hej,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Klicka på denna länk för att återställa lösenordet på {{project}}",
"emails.recovery.footer": "Om du inte bad om att återställa ditt lösenord kan du ignorera detta mail.",
"emails.recovery.thanks": "Tack,",
"emails.recovery.buttonText": "Återställ lösenord",
"emails.recovery.signature": "{{project}} teamet",
"emails.invitation.subject": "Inbjudan till %s teamet på %s",
"emails.invitation.hello": "Hej,",
"emails.invitation.body": "Detta mail skickades till dig eftersom {{owner}} ville bjuda in dig att bli medlem i teamet {{team}} på {{project}}.",
"emails.invitation.footer": "Om du inte är intresserad kan du ignorera detta mail.",
"emails.invitation.thanks": "Tack,",
"emails.invitation.buttonText": "Acceptera inbjudan till {{team}}",
"emails.invitation.signature": "{{project}} teamet",
"locale.country.unknown": "Okänt",
"countries.af": "Afghanistan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "உங்கள் மின்னஞ்சல் முகவரியைச் சரிபார்க்க இந்த இணைப்பைப் பின்தொடரவும்.",
"emails.verification.footer": "இந்த முகவரியைச் சரிபார்க்கும்படி உங்களிடம் கேட்கப்படவில்லை என்றால், இந்தச் செய்தியை நீங்கள் புறக்கணிக்கலாம்.",
"emails.verification.thanks": "நன்றி,",
"emails.verification.buttonText": "மின்னஞ்சல் முகவரியை உறுதிப்படுத்தவும்",
"emails.verification.signature": "{{project}} குழு ",
"emails.magicSession.subject": "உள்நுழைய",
"emails.magicSession.hello": "ஏய்,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "மீட்டமைக்க இந்த இணைப்பைப் பின்தொடரவும் {{project}} கடவுச்சொல்.",
"emails.recovery.footer": "உங்கள் கடவுச்சொல்லை மீட்டமைக்கும்படி உங்களிடம் கேட்கப்படவில்லை என்றால், இந்தச் செய்தியை நீங்கள் புறக்கணிக்கலாம்.",
"emails.recovery.thanks": "நன்றி,",
"emails.recovery.buttonText": "கடவுச்சொல்லை மீட்டமைக்கவும்",
"emails.recovery.signature": "{{project}} குழு",
"emails.invitation.subject": "அழைப்பிதழ் %s குழு %s ",
"emails.invitation.hello": "வணக்கம்,",
"emails.invitation.body": "{{project}} இல் {{team}} குழுவில் உறுப்பினராக உங்களை {{owner}} அழைக்க விரும்புவதால், இந்த அஞ்சல் உங்களுக்கு அனுப்பப்பட்டது.",
"emails.invitation.footer": "உங்களுக்கு ஆர்வம் இல்லை என்றால், இந்த செய்தியை நீங்கள் புறக்கணிக்கலாம்.",
"emails.invitation.thanks": "நன்றி,",
"emails.invitation.buttonText": "{{team}} அழைப்பை ஏற்கவும்",
"emails.invitation.signature": "{{project}} குழு",
"locale.country.unknown": "அறியவில்லை",
"countries.af": "ஆப்கானித்தான்",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "ఈ లింక్ ద్వారా ఇమెయిల్ ని ధృవీకరించండి",
"emails.verification.footer": "మీరు ఈ చిరునామాను ధృవీకరించమని అడగనట్లయితే, మీరు ఈ సందేశాన్ని విస్మరించవచ్చు",
"emails.verification.thanks": "ధన్యవాదాలు,",
"emails.verification.buttonText": "ఇమెయిల్ చిరునామాను నిర్ధారించండి",
"emails.verification.signature": "{{project}} జట్",
"emails.magicSession.subject": "లాగిన్",
"emails.magicSession.hello": "నమస్కారము,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "మీ {{project}} పాస్వర్డ్ ని రీసెట్ చేయడానికి ఈ లింక్ ని అనుసరించండి",
"emails.recovery.footer": "మీరు మీ పాస్వర్డ్ ని రీసెట్ చేయమని అడగనట్లయితే, మీరు ఈ సందేశాన్ని విస్మరించవచ్చు",
"emails.recovery.thanks": "ధన్యవాదాల,",
"emails.recovery.buttonText": "పాస్‌వర్డ్‌ను రీసెట్ చేయండి",
"emails.recovery.signature": "{{project}} జట్",
"emails.invitation.subject": "%s వద్ద %s బృందానికి ఆహ్వానం",
"emails.invitation.hello": "నమస్కారమ,",
"emails.invitation.body": "{{owner}} మిమ్మల్ని {{project}} లో {{team}} బృందంలో సభ్యునిగా ఉండమని ఆహ్వానించాలనుకుంటున్నందున ఈ మెయిల్ మీకు పంపబడింది.",
"emails.invitation.footer": "మీకు ఆసక్తి లేకుంటే, మీరు ఈ సందేశాన్ని విస్మరించవచ్చు.",
"emails.invitation.thanks": "ధన్యవాదాల,",
"emails.invitation.buttonText": "{{team}} కు ఆహ్వానాన్ని ఆమోదించండి",
"emails.invitation.signature": "{{project}} జట్",
"locale.country.unknown": "తెలియని",
"countries.af": "ఆఫ్ఘనిస్తాన్",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "กดเข้าไปที่ลิงก์นี้เพื่อยืนยันอีเมลของท่าน",
"emails.verification.footer": "หากท่านไม่ได้ต้องการที่จะยืนยันอีเมลนี้ ท่านสามารถเพิกเฉยข้อความนี้ได้",
"emails.verification.thanks": "ขอบคุณ",
"emails.verification.buttonText": "ยืนยันที่อยู่อีเมล",
"emails.verification.signature": "ทีม {{project}}",
"emails.magicSession.subject": "เข้าสู่ระบบ",
"emails.magicSession.hello": "เรียนผู้ใช้งาน",
@@ -20,12 +21,14 @@
"emails.recovery.body": "กดเข้าไปที่ลิงก์นี้เพื่อรีเซ็ตรหัสผ่านสำหรับโปรเจกต์ {{project}} ของท่าน",
"emails.recovery.footer": "หากท่านไม่ได้ต้องการที่จะรีเซ็ตรหัสผ่านของท่าน ท่านสามารถเพิกเฉยข้อความนี้ได้",
"emails.recovery.thanks": "ขอบคุณ",
"emails.recovery.buttonText": "รีเซ็ตรหัสผ่าน",
"emails.recovery.signature": "ทีม {{project}}",
"emails.invitation.subject": "เรียนเชิญเข้าร่วม ทีม %s จากโปรเจกต์ %s",
"emails.invitation.hello": "สวัสดี",
"emails.invitation.body": "ท่านได้รับอีเมลฉบับนี้เนื่องจาก {{owner}} ต้องการที่จะเชิญชวนคุณเข้าร่วมเป็นส่วนหนึ่งของ ทีม {{team}} จากโปรเจกต์ {{project}}",
"emails.invitation.footer": "หากท่านไม่ได้สนใจที่จะเข้าร่วม ท่านสามารถเพิกเฉยข้อความนี้ได้",
"emails.invitation.thanks": "ขอบคุณ",
"emails.invitation.buttonText": "ยอมรับคำเชิญเข้าร่วม {{team}}",
"emails.invitation.signature": "ทีม {{project}}",
"locale.country.unknown": "ไม่ทราบ",
"countries.af": "อัฟกานิสถาน",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Sundin ang link na ito upang ma-verify ang iyong email address.",
"emails.verification.footer": "Kung hindi mo hiningi na i-verify ang address na ito, maaari mong balewalain ang mensahe na ito.",
"emails.verification.thanks": "Salamat,",
"emails.verification.buttonText": "Kumpirmahin ang email address",
"emails.verification.signature": "Pangkat ng {{project}}",
"emails.magicSession.subject": "Mag log in",
"emails.magicSession.hello": "Kamusta ,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Sundin ang link na ito upang i-reset ang password ng iyong {{project}}.",
"emails.recovery.footer": "Kung hindi mo hiningi na i-reset ang iyong password, maaari mong balewalain ang mensahe na ito.",
"emails.recovery.thanks": "Salamat,",
"emails.recovery.buttonText": "I-reset ang password",
"emails.recovery.signature": "Pangkat ng {{project}}",
"emails.invitation.subject": "Imbitasyon para sa Pangkat %s sa %s",
"emails.invitation.hello": "Kamusta,",
"emails.invitation.body": "Ipinadala sa iyo ang mail na ito dahil gusto kang imbitahan ni {{owner}} na maging miyembro ng Pangkat {{team}} sa ilalim ng proyektong {{project}}.",
"emails.invitation.footer": "Kung ikaw ay hindi interesado, maaari mong balewalain ang mensaheng ito.",
"emails.invitation.thanks": "Salamat,",
"emails.invitation.buttonText": "Tanggapin ang paanyaya sa {{team}}",
"emails.invitation.signature": "Pangkat ng {{project}}",
"locale.country.unknown": "Hindi kilala",
"countries.af": "Apganistan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Eposta adresini doğrulamak için bu bağlantıyı kullanın.",
"emails.verification.footer": "Eğer bu eposta adresini doğrulamak isteyen siz değilseniz devam etmeyin.",
"emails.verification.thanks": "Teşekkürler,",
"emails.verification.buttonText": "E-posta adresini doğrula",
"emails.verification.signature": "{{project}} takımı",
"emails.magicSession.subject": "Giriş",
"emails.magicSession.hello": "Merhaba,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "{{project}} şifrenizi sıfırlamak için bu bağlantıyı kullanın.",
"emails.recovery.footer": "Eğer şifre sıfırlama talebinde bulunmadıysanız devam etmeyin.",
"emails.recovery.thanks": "Teşekkürler,",
"emails.recovery.buttonText": "Şifreyi sıfırla",
"emails.recovery.signature": "{{project}} takımı",
"emails.invitation.subject": "%s üzerinde %s Takımına Davet",
"emails.invitation.hello": "Merhaba,",
"emails.invitation.body": "Bu epostayı aldınız, çünkü {{owner}} sizi {{project}} üzerinde {{team}} takımının üyesi olmaya davet etti.",
"emails.invitation.footer": "Eğer ilgilenmiyorsanız devam etmeyin.",
"emails.invitation.thanks": "Teşekkürler,",
"emails.invitation.buttonText": "{{team}}'e daveti kabul et",
"emails.invitation.signature": "{{project}} takımı",
"locale.country.unknown": "Bilinmeyen",
"countries.af": "Afganistan",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Перейдіть за цим посиланням, щоб підтвердити свою електронну адресу.",
"emails.verification.footer": "Якщо ви не запитували підтвердження цієї адреси, ви можете ігнорувати це повідомлення.",
"emails.verification.thanks": "Дякуємо,",
"emails.verification.buttonText": "Підтвердити адресу електронної пошти",
"emails.verification.signature": "команда {{project}}",
"emails.magicSession.subject": "Логін",
"emails.magicSession.hello": "Вітаємо,",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Перейдіть за цим посиланням для того щоб скинути свій пароль для проекту {{project}}",
"emails.recovery.footer": "Якщо ви не запитували скидання паролю, проігноруйте це повідомлення.",
"emails.recovery.thanks": "Дякуємо,",
"emails.recovery.buttonText": "Скинути пароль",
"emails.recovery.signature": "команда {{project}}",
"emails.invitation.subject": "Запрошення до %s Команди у %s",
"emails.invitation.hello": "Вітаємо,",
"emails.invitation.body": "Цей лист був надісланий вам тому що {{owner}} запрошує вас стати членом команди {{team}} у проекті {{project}}.",
"emails.invitation.footer": "Якщо ви не зацікавлені, проігноруйте це повідомлення.",
"emails.invitation.thanks": "Дякуємо,",
"emails.invitation.buttonText": "Прийняти запрошення до {{team}}",
"emails.invitation.signature": "команда {{project}}",
"locale.country.unknown": "Невідомо",
"countries.af": "Афганістан",
+4 -1
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "براہ کرم اپنے ای میل کی تصدیق کے لیے درج ذیل لنک پر عمل کریں۔",
"emails.verification.footer": "اگر آپ نے اس پتے کی تصدیق کے لیے نہیں کہا تو آپ اس پیغام کو نظر انداز کر سکتے ہیں۔",
"emails.verification.thanks": "شکریہ،",
"emails.verification.buttonText": "ای میل پتہ کی تصدیق کریں",
"emails.verification.signature": "ٹیم۔ {{project}}",
"emails.magicSession.subject": "اگ ان کریں",
"emails.magicSession.hello": "خوش آمدید،",
@@ -20,13 +21,15 @@
"emails.recovery.body": "{{project}} کا پاس ورڈ تبدیل کرنے کے لیے درج ذیل لنک پر عمل کریں",
"emails.recovery.footer": "اگر آپ نے اپنا پاس ورڈ دوبارہ ترتیب دینے کے لیے نہیں کہا تو آپ اس پیغام کو نظر انداز کر سکتے ہیں۔",
"emails.recovery.thanks": "شکریہ،",
"emails.recovery.buttonText": "پاس ورڈ ری سیٹ کریں",
"emails.recovery.signature": "ٹیم۔ {{project}}",
"emails.invitation.subject": "%s پر %s ٹیم کو دعوت",
"emails.invitation.hello": "خوش آمدید،",
"emails.invitation.body": "یہ پیغام آپ کو اس لیے بھیجا گیا تھا کہ {{owner}} نے آپ کو {{project}} میں {{team}} ٹیم کا رکن بننے کی دعوت بھیجی",
"emails.invitation.footer": "اگر آپ دلچسپی نہیں رکھتے تو آپ اس پیغام کو نظر انداز کر سکتے ہیں۔",
"emails.invitation.thanks": "شکریہ،",
"emails.invitation.signature": "ٹیم۔ {{project}",
"emails.invitation.buttonText": "{{team}} کی دعوت قبول کریں",
"emails.invitation.signature": "ٹیم۔ {{project}}",
"locale.country.unknown": "نامعلوم",
"countries.af": "افغانستان",
"countries.ao": "انگولا",
+3
View File
@@ -8,6 +8,7 @@
"emails.verification.body": "Nhấn vào đường dẫn sau để xác minh địa chỉ email của bạn.",
"emails.verification.footer": "Nếu bạn không yêu cầu xác minh tài khoản, bạn có thể bỏ qua email này.",
"emails.verification.thanks": "Cảm ơn",
"emails.verification.buttonText": "Xác nhận địa chỉ email",
"emails.verification.signature": "Nhóm {{project}}",
"emails.magicSession.subject": "Đăng nhập",
"emails.magicSession.hello": "Chào",
@@ -20,12 +21,14 @@
"emails.recovery.body": "Nhấn vào đường dẫn sau để thiết lập lại mật khẩu {{project}} của bạn.",
"emails.recovery.footer": "Nếu bạn không yêu cầu thiết lập lại mật khẩu, bạn có thể bỏ qua email này.",
"emails.recovery.thanks": "Cảm ơn",
"emails.recovery.buttonText": "Đặt lại mật khẩu",
"emails.recovery.signature": "Nhóm {{project}}",
"emails.invitation.subject": "Lời mời tham gia nhóm %s tại %s",
"emails.invitation.hello": "Xin chào",
"emails.invitation.body": "Email này được gửi cho bạn vì {{owner}} muốn mời bạn trở thành một thành viên của nhóm {{team}} tại {{project}}.",
"emails.invitation.footer": "Nếu bạn không quan tâm, bạn có thể bỏ qua email này.",
"emails.invitation.thanks": "Cảm ơn",
"emails.invitation.buttonText": "Chấp nhận lời mời vào {{team}}",
"emails.invitation.signature": "Nhóm {{project}}",
"locale.country.unknown": "Không xác định",
"countries.af": "Afghanistan",
@@ -8,6 +8,7 @@
"emails.verification.body": "点此链接验证您的电子邮件地址。",
"emails.verification.footer": "如果您没有要求验证此地址,则可忽略此消息。",
"emails.verification.thanks": "谢谢、",
"emails.verification.buttonText": "确认邮箱地址",
"emails.verification.signature": "{{project}} 团队",
"emails.magicSession.subject": "登录",
"emails.magicSession.hello": "你好、",
@@ -20,12 +21,14 @@
"emails.recovery.body": "点此链接重置您的 {{project}} 密码。",
"emails.recovery.footer": "如果您没有要求重置密码,则可以忽略此消息。",
"emails.recovery.thanks": "谢谢、",
"emails.recovery.buttonText": "重置密码",
"emails.recovery.signature": "{{project}} 团队",
"emails.invitation.subject": "邀请 %s 团队在 %s",
"emails.invitation.hello": "你好、",
"emails.invitation.body": "这封邮件发送给您是因为 {{owner}} 想邀请您成为 {{team}} 团队在 {{project}}.",
"emails.invitation.footer": "如果您不感兴趣,可以忽略此消息。",
"emails.invitation.thanks": "谢谢、",
"emails.invitation.buttonText": "接受加入 {{team}} 的邀请",
"emails.invitation.signature": "{{project}} 团队",
"locale.country.unknown": "未知",
"countries.af": "阿富汗",
@@ -8,6 +8,7 @@
"emails.verification.body": "按照此連結驗證您的電子郵件地址。",
"emails.verification.footer": "如果您沒有要求驗證此地址,則可以忽略此消息。",
"emails.verification.thanks": "謝謝、",
"emails.verification.buttonText": "確認電子郵件地址",
"emails.verification.signature": "{{project}} 團隊",
"emails.magicSession.subject": "登入",
"emails.magicSession.hello": "嗨、",
@@ -20,12 +21,14 @@
"emails.recovery.body": "按照此連結重置您的 {{project}} 密碼。",
"emails.recovery.footer": "如果您沒有要求重置密碼,則可以忽略此消息。",
"emails.recovery.thanks": "謝謝、",
"emails.recovery.buttonText": "重設密碼",
"emails.recovery.signature": "{{project}} 團隊",
"emails.invitation.subject": "邀請 %s 團隊在 %s",
"emails.invitation.hello": "您好、",
"emails.invitation.body": "發送這封郵件給您是因為 {{owner}} 想邀請您成為 {{team}} 團隊在 {{project}}。",
"emails.invitation.footer": "如果您不感興趣,可以忽略此消息。",
"emails.invitation.thanks": "謝謝、",
"emails.invitation.buttonText": "接受加入 {{team}} 的邀請",
"emails.invitation.signature": "{{project}} 團隊",
"locale.country.unknown": "未知",
"countries.af": "阿富汗",
+7 -6
View File
@@ -59,7 +59,7 @@ return [
[
'key' => 'flutter',
'name' => 'Flutter',
'version' => '17.0.1',
'version' => '17.0.2',
'url' => 'https://github.com/appwrite/sdk-for-flutter',
'package' => 'https://pub.dev/packages/appwrite',
'enabled' => true,
@@ -134,7 +134,7 @@ return [
[
'key' => 'react-native',
'name' => 'React Native',
'version' => '0.10.0',
'version' => '0.10.1',
'url' => 'https://github.com/appwrite/sdk-for-react-native',
'package' => 'https://npmjs.com/package/react-native-appwrite',
'enabled' => true,
@@ -217,7 +217,7 @@ return [
[
'key' => 'cli',
'name' => 'Command Line',
'version' => '8.0.2',
'version' => '8.2.2',
'url' => 'https://github.com/appwrite/sdk-for-cli',
'package' => 'https://www.npmjs.com/package/appwrite-cli',
'enabled' => true,
@@ -231,6 +231,7 @@ return [
'gitRepoName' => 'sdk-for-cli',
'gitUserName' => 'appwrite',
'gitBranch' => 'dev',
'repoBranch' => 'master',
'exclude' => [
'services' => [
['name' => 'assistant'],
@@ -250,7 +251,7 @@ return [
[
'key' => 'nodejs',
'name' => 'Node.js',
'version' => '17.0.0',
'version' => '17.1.0',
'url' => 'https://github.com/appwrite/sdk-for-node',
'package' => 'https://www.npmjs.com/package/node-appwrite',
'enabled' => true,
@@ -358,7 +359,7 @@ return [
[
'key' => 'dotnet',
'name' => '.NET',
'version' => '0.13.0',
'version' => '0.14.0',
'url' => 'https://github.com/appwrite/sdk-for-dotnet',
'package' => 'https://www.nuget.org/packages/Appwrite',
'enabled' => true,
@@ -376,7 +377,7 @@ return [
[
'key' => 'dart',
'name' => 'Dart',
'version' => '16.0.0',
'version' => '16.1.0',
'url' => 'https://github.com/appwrite/sdk-for-dart',
'package' => 'https://pub.dev/packages/dart_appwrite',
'enabled' => true,
+2 -7
View File
@@ -6,13 +6,8 @@ use Utopia\System\System;
* List of Appwrite Sites templates
*/
$protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS') == 'disabled' ? 'http' : 'https';
$hostname = System::getEnv('_APP_DOMAIN');
// TODO: Development override
if (System::getEnv('_APP_ENV') === 'development') {
$hostname = 'localhost';
}
$protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS') === 'disabled' ? 'http' : 'https';
$hostname = System::getEnv('_APP_DOMAIN', '');
$url = $protocol . '://' . $hostname;
+96 -38
View File
@@ -21,6 +21,7 @@ use Appwrite\Event\StatsUsage;
use Appwrite\Extend\Exception;
use Appwrite\Hooks\Hooks;
use Appwrite\Network\Validator\Email;
use Appwrite\Network\Validator\Redirect;
use Appwrite\OpenSSL\OpenSSL;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
@@ -60,7 +61,6 @@ use Utopia\System\System;
use Utopia\Validator\ArrayList;
use Utopia\Validator\Assoc;
use Utopia\Validator\Boolean;
use Utopia\Validator\Host;
use Utopia\Validator\Text;
use Utopia\Validator\URL;
use Utopia\Validator\WhiteList;
@@ -1182,16 +1182,23 @@ App::get('/v1/account/sessions/oauth2/:provider')
->label('abuse-limit', 50)
->label('abuse-key', 'ip:{ip}')
->param('provider', '', new WhiteList(\array_keys(Config::getParam('oAuthProviders')), true), 'OAuth2 Provider. Currently, supported providers are: ' . \implode(', ', \array_keys(\array_filter(Config::getParam('oAuthProviders'), fn ($node) => (!$node['mock'])))) . '.')
->param('success', '', fn ($clients, $devKey) => $devKey->isEmpty() ? new Host($clients) : new URL(), 'URL to redirect back to your app after a successful login attempt. Only URLs from hostnames in your project\'s platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['clients', 'devKey'])
->param('failure', '', fn ($clients, $devKey) => $devKey->isEmpty() ? new Host($clients) : new URL(), 'URL to redirect back to your app after a failed login attempt. Only URLs from hostnames in your project\'s platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['clients', 'devKey'])
->param('success', '', fn ($platforms, $devKey) => $devKey->isEmpty() ? new Redirect($platforms) : new URL(), 'URL to redirect back to your app after a successful login attempt. Only URLs from hostnames in your project\'s platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['platforms', 'devKey'])
->param('failure', '', fn ($platforms, $devKey) => $devKey->isEmpty() ? new Redirect($platforms) : new URL(), 'URL to redirect back to your app after a failed login attempt. Only URLs from hostnames in your project\'s platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['platforms', 'devKey'])
->param('scopes', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'A list of custom OAuth2 scopes. Check each provider internal docs for a list of supported scopes. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' scopes are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true)
->inject('request')
->inject('response')
->inject('project')
->action(function (string $provider, string $success, string $failure, array $scopes, Request $request, Response $response, Document $project) use ($oauthDefaultSuccess, $oauthDefaultFailure) {
$protocol = $request->getProtocol();
$protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS') === 'disabled' ? 'http' : 'https';
$port = $request->getPort();
$callbackBase = $protocol . '://' . $request->getHostname();
if ($protocol === 'https' && $port !== '443') {
$callbackBase .= ':' . $port;
} elseif ($protocol === 'http' && $port !== '80') {
$callbackBase .= ':' . $port;
}
$callback = $protocol . '://' . $request->getHostname() . '/v1/account/sessions/oauth2/callback/' . $provider . '/' . $project->getId();
$callback = $callbackBase . '/v1/account/sessions/oauth2/callback/' . $provider . '/' . $project->getId();
$providerEnabled = $project->getAttribute('oAuthProviders', [])[$provider . 'Enabled'] ?? false;
if (!$providerEnabled) {
@@ -1216,12 +1223,20 @@ App::get('/v1/account/sessions/oauth2/:provider')
throw new Exception(Exception::PROJECT_PROVIDER_UNSUPPORTED);
}
$host = System::getEnv('_APP_CONSOLE_DOMAIN', System::getEnv('_APP_DOMAIN', ''));
$redirectBase = $protocol . '://' . $host;
if ($protocol === 'https' && $port !== '443') {
$redirectBase .= ':' . $port;
} elseif ($protocol === 'http' && $port !== '80') {
$redirectBase .= ':' . $port;
}
if (empty($success)) {
$success = $protocol . '://' . $request->getHostname() . $oauthDefaultSuccess;
$success = $redirectBase . $oauthDefaultSuccess;
}
if (empty($failure)) {
$failure = $protocol . '://' . $request->getHostname() . $oauthDefaultFailure;
$failure = $redirectBase . $oauthDefaultFailure;
}
$oauth2 = new $className($appId, $appSecret, $callback, [
@@ -1251,9 +1266,14 @@ App::get('/v1/account/sessions/oauth2/callback/:provider/:projectId')
->inject('request')
->inject('response')
->action(function (string $projectId, string $provider, string $code, string $state, string $error, string $error_description, Request $request, Response $response) {
$domain = $request->getHostname();
$protocol = $request->getProtocol();
$protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS') === 'disabled' ? 'http' : 'https';
$port = $request->getPort();
$callbackBase = $protocol . '://' . $request->getHostname();
if ($protocol === 'https' && $port !== '443') {
$callbackBase .= ':' . $port;
} elseif ($protocol === 'http' && $port !== '80') {
$callbackBase .= ':' . $port;
}
$params = $request->getParams();
$params['project'] = $projectId;
@@ -1262,7 +1282,7 @@ App::get('/v1/account/sessions/oauth2/callback/:provider/:projectId')
$response
->addHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
->addHeader('Pragma', 'no-cache')
->redirect($protocol . '://' . $domain . '/v1/account/sessions/oauth2/' . $provider . '/redirect?'
->redirect($callbackBase . '/v1/account/sessions/oauth2/' . $provider . '/redirect?'
. \http_build_query($params));
});
@@ -1282,9 +1302,14 @@ App::post('/v1/account/sessions/oauth2/callback/:provider/:projectId')
->inject('request')
->inject('response')
->action(function (string $projectId, string $provider, string $code, string $state, string $error, string $error_description, Request $request, Response $response) {
$domain = $request->getHostname();
$protocol = $request->getProtocol();
$protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS') === 'disabled' ? 'http' : 'https';
$port = $request->getPort();
$callbackBase = $protocol . '://' . $request->getHostname();
if ($protocol === 'https' && $port !== '443') {
$callbackBase .= ':' . $port;
} elseif ($protocol === 'http' && $port !== '80') {
$callbackBase .= ':' . $port;
}
$params = $request->getParams();
$params['project'] = $projectId;
@@ -1293,7 +1318,7 @@ App::post('/v1/account/sessions/oauth2/callback/:provider/:projectId')
$response
->addHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
->addHeader('Pragma', 'no-cache')
->redirect($protocol . '://' . $domain . '/v1/account/sessions/oauth2/' . $provider . '/redirect?'
->redirect($callbackBase . '/v1/account/sessions/oauth2/' . $provider . '/redirect?'
. \http_build_query($params));
});
@@ -1317,15 +1342,24 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
->inject('request')
->inject('response')
->inject('project')
->inject('platforms')
->inject('devKey')
->inject('user')
->inject('dbForProject')
->inject('geodb')
->inject('queueForEvents')
->action(function (string $provider, string $code, string $state, string $error, string $error_description, Request $request, Response $response, Document $project, Document $user, Database $dbForProject, Reader $geodb, Event $queueForEvents) use ($oauthDefaultSuccess) {
$protocol = $request->getProtocol();
$callback = $protocol . '://' . $request->getHostname() . '/v1/account/sessions/oauth2/callback/' . $provider . '/' . $project->getId();
->action(function (string $provider, string $code, string $state, string $error, string $error_description, Request $request, Response $response, Document $project, array $platforms, Document $devKey, Document $user, Database $dbForProject, Reader $geodb, Event $queueForEvents) use ($oauthDefaultSuccess) {
$protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS') === 'disabled' ? 'http' : 'https';
$port = $request->getPort();
$callbackBase = $protocol . '://' . $request->getHostname();
if ($protocol === 'https' && $port !== '443') {
$callbackBase .= ':' . $port;
} elseif ($protocol === 'http' && $port !== '80') {
$callbackBase .= ':' . $port;
}
$callback = $callbackBase . '/v1/account/sessions/oauth2/callback/' . $provider . '/' . $project->getId();
$defaultState = ['success' => $project->getAttribute('url', ''), 'failure' => ''];
$validateURL = new URL();
$redirect = new Redirect($platforms);
$appId = $project->getAttribute('oAuthProviders', [])[$provider . 'Appid'] ?? '';
$appSecret = $project->getAttribute('oAuthProviders', [])[$provider . 'Secret'] ?? '{}';
$providerEnabled = $project->getAttribute('oAuthProviders', [])[$provider . 'Enabled'] ?? false;
@@ -1352,11 +1386,11 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
$state = $defaultState;
}
if (!$validateURL->isValid($state['success'])) {
if ($devKey->isEmpty() && !$redirect->isValid($state['success'])) {
throw new Exception(Exception::PROJECT_INVALID_SUCCESS_URL);
}
if (!empty($state['failure']) && !$validateURL->isValid($state['failure'])) {
if ($devKey->isEmpty() && !empty($state['failure']) && !$redirect->isValid($state['failure'])) {
throw new Exception(Exception::PROJECT_INVALID_FAILURE_URL);
}
$failure = [];
@@ -1423,13 +1457,13 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
$name = '';
$nameOAuth = $oauth2->getUserName($accessToken);
$userParam = \json_decode($request->getParam('user'), true);
$userParam = $request->getParam('user');
if (!empty($nameOAuth)) {
$name = $nameOAuth;
} elseif (is_array($userParam)) {
$nameParam = $userParam['name'];
if (is_array($nameParam) && isset($nameParam['firstName']) && isset($nameParam['lastName'])) {
$name = $nameParam['firstName'] . ' ' . $nameParam['lastName'];
} elseif ($userParam !== null) {
$userDecoded = \json_decode($userParam, true);
if (isset($userDecoded['name']['firstName']) && isset($userDecoded['name']['lastName'])) {
$name = $userDecoded['name']['firstName'] . ' ' . $userDecoded['name']['lastName'];
}
}
$email = $oauth2->getUserEmail($accessToken);
@@ -1747,8 +1781,6 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
$state['success']['query'] = URLParser::unparseQuery($query);
$state['success'] = URLParser::unparse($state['success']);
$expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), $duration));
$response
->addHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
->addHeader('Pragma', 'no-cache')
@@ -1779,16 +1811,23 @@ App::get('/v1/account/tokens/oauth2/:provider')
->label('abuse-limit', 50)
->label('abuse-key', 'ip:{ip}')
->param('provider', '', new WhiteList(\array_keys(Config::getParam('oAuthProviders')), true), 'OAuth2 Provider. Currently, supported providers are: ' . \implode(', ', \array_keys(\array_filter(Config::getParam('oAuthProviders'), fn ($node) => (!$node['mock'])))) . '.')
->param('success', '', fn ($clients, $devKey) => $devKey->isEmpty() ? new Host($clients) : new URL(), 'URL to redirect back to your app after a successful login attempt. Only URLs from hostnames in your project\'s platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['clients', 'devKey'])
->param('failure', '', fn ($clients, $devKey) => $devKey->isEmpty() ? new Host($clients) : new URL(), 'URL to redirect back to your app after a failed login attempt. Only URLs from hostnames in your project\'s platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['clients', 'devKey'])
->param('success', '', fn ($platforms, $devKey) => $devKey->isEmpty() ? new Redirect($platforms) : new URL(), 'URL to redirect back to your app after a successful login attempt. Only URLs from hostnames in your project\'s platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['platforms', 'devKey'])
->param('failure', '', fn ($platforms, $devKey) => $devKey->isEmpty() ? new Redirect($platforms) : new URL(), 'URL to redirect back to your app after a failed login attempt. Only URLs from hostnames in your project\'s platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['platforms', 'devKey'])
->param('scopes', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'A list of custom OAuth2 scopes. Check each provider internal docs for a list of supported scopes. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' scopes are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true)
->inject('request')
->inject('response')
->inject('project')
->action(function (string $provider, string $success, string $failure, array $scopes, Request $request, Response $response, Document $project) use ($oauthDefaultSuccess, $oauthDefaultFailure) {
$protocol = $request->getProtocol();
$protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS') === 'disabled' ? 'http' : 'https';
$port = $request->getPort();
$callbackBase = $protocol . '://' . $request->getHostname();
if ($protocol === 'https' && $port !== '443') {
$callbackBase .= ':' . $port;
} elseif ($protocol === 'http' && $port !== '80') {
$callbackBase .= ':' . $port;
}
$callback = $protocol . '://' . $request->getHostname() . '/v1/account/sessions/oauth2/callback/' . $provider . '/' . $project->getId();
$callback = $callbackBase . '/v1/account/sessions/oauth2/callback/' . $provider . '/' . $project->getId();
$providerEnabled = $project->getAttribute('oAuthProviders', [])[$provider . 'Enabled'] ?? false;
if (!$providerEnabled) {
@@ -1813,12 +1852,20 @@ App::get('/v1/account/tokens/oauth2/:provider')
throw new Exception(Exception::PROJECT_PROVIDER_UNSUPPORTED);
}
$host = System::getEnv('_APP_CONSOLE_DOMAIN', System::getEnv('_APP_DOMAIN', ''));
$redirectBase = $protocol . '://' . $host;
if ($protocol === 'https' && $port !== '443') {
$redirectBase .= ':' . $port;
} elseif ($protocol === 'http' && $port !== '80') {
$redirectBase .= ':' . $port;
}
if (empty($success)) {
$success = $protocol . '://' . $request->getHostname() . $oauthDefaultSuccess;
$success = $redirectBase . $oauthDefaultSuccess;
}
if (empty($failure)) {
$failure = $protocol . '://' . $request->getHostname() . $oauthDefaultFailure;
$failure = $redirectBase . $oauthDefaultFailure;
}
$oauth2 = new $className($appId, $appSecret, $callback, [
@@ -1860,7 +1907,7 @@ App::post('/v1/account/tokens/magic-url')
->label('abuse-key', ['url:{url},email:{param-email}', 'url:{url},ip:{ip}'])
->param('userId', '', new CustomId(), 'Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
->param('email', '', new Email(), 'User email.')
->param('url', '', fn ($clients, $devKey) => $devKey->isEmpty() ? new Host($clients) : new URL(), 'URL to redirect the user back to your app from the magic URL login. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['clients', 'devKey'])
->param('url', '', fn ($platforms, $devKey) => $devKey->isEmpty() ? new Redirect($platforms) : new URL(), 'URL to redirect the user back to your app from the magic URL login. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['platforms', 'devKey'])
->param('phrase', false, new Boolean(), 'Toggle for security phrase. If enabled, email will be send with a randomly generated phrase and the phrase will also be included in the response. Confirming phrases match increases the security of your authentication flow.', true)
->inject('request')
->inject('response')
@@ -1961,7 +2008,16 @@ App::post('/v1/account/tokens/magic-url')
$dbForProject->purgeCachedDocument('users', $user->getId());
if (empty($url)) {
$url = $request->getProtocol() . '://' . $request->getHostname() . '/console/auth/magic-url';
$protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS') === 'disabled' ? 'http' : 'https';
$host = System::getEnv('_APP_CONSOLE_DOMAIN', System::getEnv('_APP_DOMAIN', ''));
$port = $request->getPort();
$callbackBase = $protocol . '://' . $host;
if ($protocol === 'https' && $port !== '443') {
$callbackBase .= ':' . $port;
} elseif ($protocol === 'http' && $port !== '80') {
$callbackBase .= ':' . $port;
}
$url = $callbackBase . '/console/auth/magic-url';
}
$url = Template::parseURL($url);
@@ -3146,7 +3202,7 @@ App::post('/v1/account/recovery')
->label('abuse-limit', 10)
->label('abuse-key', ['url:{url},email:{param-email}', 'url:{url},ip:{ip}'])
->param('email', '', new Email(), 'User email.')
->param('url', '', fn ($clients, $devKey) => $devKey->isEmpty() ? new Host($clients) : new URL(), 'URL to redirect the user back to your app from the recovery email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', false, ['clients', 'devKey'])
->param('url', '', fn ($platforms, $devKey) => $devKey->isEmpty() ? new Redirect($platforms) : new URL(), 'URL to redirect the user back to your app from the recovery email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', false, ['platforms', 'devKey'])
->inject('request')
->inject('response')
->inject('user')
@@ -3217,6 +3273,7 @@ App::post('/v1/account/recovery')
->setParam('{{hello}}', $locale->getText("emails.recovery.hello"))
->setParam('{{footer}}', $locale->getText("emails.recovery.footer"))
->setParam('{{thanks}}', $locale->getText("emails.recovery.thanks"))
->setParam('{{buttonText}}', $locale->getText("emails.recovery.buttonText"))
->setParam('{{signature}}', $locale->getText("emails.recovery.signature"));
$body = $message->render();
@@ -3412,7 +3469,7 @@ App::post('/v1/account/verification')
))
->label('abuse-limit', 10)
->label('abuse-key', 'url:{url},userId:{userId}')
->param('url', '', fn ($clients, $devKey) => $devKey->isEmpty() ? new Host($clients) : new URL(), 'URL to redirect the user back to your app from the verification email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', false, ['clients', 'devKey']) // TODO add built-in confirm page
->param('url', '', fn ($platforms, $devKey) => $devKey->isEmpty() ? new Redirect($platforms) : new URL(), 'URL to redirect the user back to your app from the verification email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', false, ['platforms', 'devKey']) // TODO add built-in confirm page
->inject('request')
->inject('response')
->inject('project')
@@ -3472,6 +3529,7 @@ App::post('/v1/account/verification')
->setParam('{{hello}}', $locale->getText("emails.verification.hello"))
->setParam('{{footer}}', $locale->getText("emails.verification.footer"))
->setParam('{{thanks}}', $locale->getText("emails.verification.thanks"))
->setParam('{{buttonText}}', $locale->getText("emails.verification.buttonText"))
->setParam('{{signature}}', $locale->getText("emails.verification.signature"));
$body = $message->render();
+2 -1
View File
@@ -2958,6 +2958,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/indexes')
$collection->getAttribute('attributes'),
$dbForProject->getAdapter()->getMaxIndexLength(),
$dbForProject->getAdapter()->getInternalIndexesKeys(),
$dbForProject->getAdapter()->getSupportForIndexArray(),
);
if (!$validator->isValid($index)) {
@@ -4309,7 +4310,7 @@ App::put('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
}
$data['$id'] = $documentId;
$data['$permissions'] = $permissions;
$data['$permissions'] = $permissions ?? [];
$newDocument = new Document($data);
$operations = 0;
+14 -4
View File
@@ -523,11 +523,16 @@ App::get('/v1/health/queue/databases')
->param('name', 'database_db_main', new Text(256), 'Queue name for which to check the queue size', true)
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
->inject('publisher')
->inject('publisherRedis')
->inject('response')
->action(function (string $name, int|string $threshold, Publisher $publisher, Response $response) {
->action(function (string $name, int|string $threshold, Publisher $publisher, ?Publisher $publisherRedis, Response $response) {
$threshold = \intval($threshold);
$size = $publisher->getQueueSize(new Queue($name));
$isRedisFallback = \str_contains(System::getEnv('_APP_WORKER_REDIS_FALLBACK', ''), 'databases');
$size = $isRedisFallback
? $publisherRedis->getQueueSize(new Queue($name))
: $publisher->getQueueSize(new Queue($name));
if ($size >= $threshold) {
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
@@ -655,11 +660,16 @@ App::get('/v1/health/queue/migrations')
))
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
->inject('publisher')
->inject('publisherRedis')
->inject('response')
->action(function (int|string $threshold, Publisher $publisher, Response $response) {
->action(function (int|string $threshold, Publisher $publisher, ?Publisher $publisherRedis, Response $response) {
$threshold = \intval($threshold);
$size = $publisher->getQueueSize(new Queue(Event::MIGRATIONS_QUEUE_NAME));
$isRedisFallback = \str_contains(System::getEnv('_APP_WORKER_REDIS_FALLBACK', ''), 'migrations');
$size = $isRedisFallback
? $publisherRedis->getQueueSize(new Queue(Event::MIGRATIONS_QUEUE_NAME))
: $publisher->getQueueSize(new Queue(Event::MIGRATIONS_QUEUE_NAME));
if ($size >= $threshold) {
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
+3 -3
View File
@@ -361,7 +361,7 @@ App::post('/v1/migrations/csv')
$hasCompression = $compression !== Compression::NONE;
$migrationId = ID::unique();
$newPath = $deviceForImports->getPath('/' . $migrationId . '_' . $fileId . '.csv');
$newPath = $deviceForImports->getPath($migrationId . '_' . $fileId . '.csv');
if ($hasEncryption || $hasCompression) {
$source = $deviceForFiles->read($path);
@@ -410,8 +410,8 @@ App::post('/v1/migrations/csv')
'resources' => $resources,
'resourceId' => $resourceId,
'resourceType' => Resource::TYPE_DATABASE,
'statusCounters' => [],
'resourceData' => [],
'statusCounters' => '{}',
'resourceData' => '{}',
'errors' => [],
'options' => [
'path' => $newPath,
+3 -2
View File
@@ -8,8 +8,8 @@ use Appwrite\Event\Mail;
use Appwrite\Event\Validator\Event;
use Appwrite\Extend\Exception;
use Appwrite\Hooks\Hooks;
use Appwrite\Network\Platform;
use Appwrite\Network\Validator\Email;
use Appwrite\Network\Validator\Origin;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Method;
@@ -1790,7 +1790,7 @@ App::post('/v1/projects/:projectId/platforms')
]
))
->param('projectId', '', new UID(), 'Project unique ID.')
->param('type', null, new WhiteList([Origin::CLIENT_TYPE_WEB, Origin::CLIENT_TYPE_FLUTTER_WEB, Origin::CLIENT_TYPE_FLUTTER_IOS, Origin::CLIENT_TYPE_FLUTTER_ANDROID, Origin::CLIENT_TYPE_FLUTTER_LINUX, Origin::CLIENT_TYPE_FLUTTER_MACOS, Origin::CLIENT_TYPE_FLUTTER_WINDOWS, Origin::CLIENT_TYPE_APPLE_IOS, Origin::CLIENT_TYPE_APPLE_MACOS, Origin::CLIENT_TYPE_APPLE_WATCHOS, Origin::CLIENT_TYPE_APPLE_TVOS, Origin::CLIENT_TYPE_ANDROID, Origin::CLIENT_TYPE_UNITY, Origin::CLIENT_TYPE_REACT_NATIVE_IOS, Origin::CLIENT_TYPE_REACT_NATIVE_ANDROID], true), 'Platform type.')
->param('type', null, new WhiteList([Platform::TYPE_WEB, Platform::TYPE_FLUTTER_WEB, Platform::TYPE_FLUTTER_IOS, Platform::TYPE_FLUTTER_ANDROID, Platform::TYPE_FLUTTER_LINUX, Platform::TYPE_FLUTTER_MACOS, Platform::TYPE_FLUTTER_WINDOWS, Platform::TYPE_APPLE_IOS, Platform::TYPE_APPLE_MACOS, Platform::TYPE_APPLE_WATCHOS, Platform::TYPE_APPLE_TVOS, Platform::TYPE_ANDROID, Platform::TYPE_UNITY, Platform::TYPE_REACT_NATIVE_IOS, Platform::TYPE_REACT_NATIVE_ANDROID], true), 'Platform type.')
->param('name', null, new Text(128), 'Platform name. Max length: 128 chars.')
->param('key', '', new Text(256), 'Package name for Android or bundle ID for iOS or macOS. Max length: 256 chars.', true)
->param('store', '', new Text(256), 'App store or Google Play store ID. Max length: 256 chars.', true)
@@ -2274,6 +2274,7 @@ App::get('/v1/projects/:projectId/templates/email/:type/:locale')
->setParam('{{footer}}', $localeObj->getText("emails.{$type}.footer"))
->setParam('{{body}}', $localeObj->getText('emails.' . $type . '.body'), escapeHtml: false)
->setParam('{{thanks}}', $localeObj->getText("emails.{$type}.thanks"))
->setParam('{{buttonText}}', $localeObj->getText("emails.{$type}.buttonText"))
->setParam('{{signature}}', $localeObj->getText("emails.{$type}.signature"))
->setParam('{{direction}}', $localeObj->getText('settings.direction'));
$message = $message->render();
+26 -4
View File
@@ -18,6 +18,7 @@ use Appwrite\Utopia\Database\Validator\Queries\Buckets;
use Appwrite\Utopia\Database\Validator\Queries\Files;
use Appwrite\Utopia\Response;
use Utopia\App;
use Utopia\CLI\Console;
use Utopia\Config\Config;
use Utopia\Database\Database;
use Utopia\Database\DateTime;
@@ -953,17 +954,20 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
->param('output', '', new WhiteList(\array_keys(Config::getParam('storage-outputs')), true), 'Output format type (jpeg, jpg, png, gif and webp).', true)
// NOTE: this is only for the sdk generator and is not used in the action below and is utilised in `resources.php` for `resourceToken`.
->param('token', '', new Text(512), 'File token for accessing this file.', true)
->inject('request')
->inject('response')
->inject('dbForProject')
->inject('resourceToken')
->inject('deviceForFiles')
->inject('deviceForLocal')
->action(function (string $bucketId, string $fileId, int $width, int $height, string $gravity, int $quality, int $borderWidth, string $borderColor, int $borderRadius, float $opacity, int $rotation, string $background, string $output, ?string $token, Response $response, Database $dbForProject, Document $resourceToken, Device $deviceForFiles, Device $deviceForLocal) {
->inject('project')
->action(function (string $bucketId, string $fileId, int $width, int $height, string $gravity, int $quality, int $borderWidth, string $borderColor, int $borderRadius, float $opacity, int $rotation, string $background, string $output, ?string $token, Request $request, Response $response, Database $dbForProject, Document $resourceToken, Device $deviceForFiles, Device $deviceForLocal, Document $project) {
if (!\extension_loaded('imagick')) {
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Imagick extension is missing');
}
/* @type Document $bucket */
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
@@ -984,6 +988,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
if ($fileSecurity && !$valid && !$isToken) {
$file = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
} else {
/* @type Document $file */
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
}
@@ -1035,8 +1040,12 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
$output = empty($type) ? (array_search($mime, $outputs) ?? 'jpg') : $type;
}
$startTime = \microtime(true);
$source = $deviceForFiles->read($path);
$downloadTime = \microtime(true) - $startTime;
if (!empty($cipher)) { // Decrypt
$source = OpenSSL::decrypt(
$source,
@@ -1048,6 +1057,8 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
);
}
$decryptionTime = \microtime(true) - $startTime - $downloadTime;
switch ($algorithm) {
case Compression::ZSTD:
$compressor = new Zstd();
@@ -1059,6 +1070,8 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
break;
}
$decompressionTime = \microtime(true) - $startTime - $downloadTime - $decryptionTime;
try {
$image = new Image($source);
} catch (ImagickException $e) {
@@ -1089,6 +1102,12 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
$data = $image->output($output, $quality);
$renderingTime = \microtime(true) - $startTime - $downloadTime - $decryptionTime - $decompressionTime;
$totalTime = \microtime(true) - $startTime;
Console::info("File preview rendered,project=" . $project->getId() . ",bucket=" . $bucketId . ",file=" . $file->getId() . ",uri=" . $request->getURI() . ",total=" . $totalTime . ",rendering=" . $renderingTime . ",decryption=" . $decryptionTime . ",decompression=" . $decompressionTime . ",download=" . $downloadTime);
$contentType = (\array_key_exists($output, $outputs)) ? $outputs[$output] : $outputs['jpg'];
//Do not update transformedAt if it's a console user
@@ -1140,7 +1159,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/download')
->inject('resourceToken')
->inject('deviceForFiles')
->action(function (string $bucketId, string $fileId, ?string $token, Request $request, Response $response, Database $dbForProject, string $mode, Document $resourceToken, Device $deviceForFiles) {
/* @type Document $bucket */
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
@@ -1158,9 +1177,10 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/download')
throw new Exception(Exception::USER_UNAUTHORIZED);
}
if ($fileSecurity && !$valid) {
if ($fileSecurity && !$valid && !$isToken) {
$file = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
} else {
/* @type Document $file */
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
}
@@ -1300,6 +1320,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view')
->inject('resourceToken')
->inject('deviceForFiles')
->action(function (string $bucketId, string $fileId, ?string $token, Response $response, Request $request, Database $dbForProject, string $mode, Document $resourceToken, Device $deviceForFiles) {
/* @type Document $bucket */
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
@@ -1317,9 +1338,10 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view')
throw new Exception(Exception::USER_UNAUTHORIZED);
}
if ($fileSecurity && !$valid) {
if ($fileSecurity && !$valid && !$isToken) {
$file = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
} else {
/* @type Document $file */
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
}
+3 -2
View File
@@ -11,6 +11,7 @@ use Appwrite\Event\Messaging;
use Appwrite\Event\StatsUsage;
use Appwrite\Extend\Exception;
use Appwrite\Network\Validator\Email;
use Appwrite\Network\Validator\Redirect;
use Appwrite\Platform\Workers\Deletes;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
@@ -50,7 +51,6 @@ use Utopia\Locale\Locale;
use Utopia\System\System;
use Utopia\Validator\ArrayList;
use Utopia\Validator\Assoc;
use Utopia\Validator\Host;
use Utopia\Validator\Text;
use Utopia\Validator\URL;
use Utopia\Validator\WhiteList;
@@ -466,7 +466,7 @@ App::post('/v1/teams/:teamId/memberships')
}
return new ArrayList(new Key(), APP_LIMIT_ARRAY_PARAMS_SIZE);
}, '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](https://appwrite.io/docs/permissions). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' roles are allowed, each 32 characters long.', false, ['project'])
->param('url', '', fn ($clients, $devKey) => $devKey->isEmpty() ? new Host($clients) : new URL(), 'URL to redirect the user back to your app from the invitation email. This parameter is not required when an API key is supplied. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['clients', 'devKey']) // TODO add our own built-in confirm page
->param('url', '', fn ($platforms, $devKey) => $devKey->isEmpty() ? new Redirect($platforms) : new URL(), 'URL to redirect the user back to your app from the invitation email. This parameter is not required when an API key is supplied. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['platforms', 'devKey']) // TODO add our own built-in confirm page
->param('name', '', new Text(128), 'Name of the new team member. Max length: 128 chars.', true)
->inject('response')
->inject('project')
@@ -666,6 +666,7 @@ App::post('/v1/teams/:teamId/memberships')
->setParam('{{hello}}', $locale->getText("emails.invitation.hello"))
->setParam('{{footer}}', $locale->getText("emails.invitation.footer"))
->setParam('{{thanks}}', $locale->getText("emails.invitation.thanks"))
->setParam('{{buttonText}}', $locale->getText("emails.invitation.buttonText"))
->setParam('{{signature}}', $locale->getText("emails.invitation.signature"));
$body = $message->render();
+2
View File
@@ -649,6 +649,8 @@ App::get('/v1/users')
$total = $dbForProject->count('users', $filterQueries, APP_LIMIT_COUNT);
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
} catch (QueryException $e) {
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$response->dynamic(new Document([
'users' => $users,
+14 -8
View File
@@ -4,6 +4,7 @@ use Appwrite\Auth\OAuth2\Github as OAuth2Github;
use Appwrite\Event\Build;
use Appwrite\Event\Delete;
use Appwrite\Extend\Exception;
use Appwrite\Network\Validator\Redirect;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Method;
@@ -53,7 +54,6 @@ use Utopia\Detector\Detector\Runtime;
use Utopia\Detector\Detector\Strategy;
use Utopia\System\System;
use Utopia\Validator\Boolean;
use Utopia\Validator\Host;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
use Utopia\VCS\Adapter\Git\GitHub;
@@ -116,8 +116,10 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
}
$commentStatus = $isAuthorized ? 'waiting' : 'failed';
$protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS') === 'disabled' ? 'http' : 'https';
$hostname = System::getEnv('_APP_CONSOLE_DOMAIN', System::getEnv('_APP_DOMAIN', ''));
$authorizeUrl = $request->getProtocol() . '://' . $request->getHostname() . "/console/git/authorize-contributor?projectId={$projectId}&installationId={$installationId}&repositoryId={$repositoryId}&providerPullRequestId={$providerPullRequestId}";
$authorizeUrl = $protocol . '://' . $hostname . "/console/git/authorize-contributor?projectId={$projectId}&installationId={$installationId}&repositoryId={$repositoryId}&providerPullRequestId={$providerPullRequestId}";
$action = $isAuthorized ? ['type' => 'logs'] : ['type' => 'authorize', 'url' => $authorizeUrl];
@@ -378,7 +380,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
}
$owner = $github->getOwnerName($providerInstallationId);
$providerTargetUrl = $request->getProtocol() . '://' . $request->getHostname() . "/console/project-$region-$projectId/$resourceCollection/$resourceType-$resourceId";
$providerTargetUrl = $protocol . '://' . $hostname . "/console/project-$region-$projectId/$resourceCollection/$resourceType-$resourceId";
$github->updateCommitStatus($repositoryName, $providerCommitHash, $owner, 'pending', $message, $providerTargetUrl, $name);
}
@@ -424,8 +426,8 @@ App::get('/v1/vcs/github/authorize')
type: MethodType::WEBAUTH,
hide: true,
))
->param('success', '', fn ($clients) => new Host($clients), 'URL to redirect back to console after a successful installation attempt.', true, ['clients'])
->param('failure', '', fn ($clients) => new Host($clients), 'URL to redirect back to console after a failed installation attempt.', true, ['clients'])
->param('success', '', fn ($platforms) => new Redirect($platforms), 'URL to redirect back to console after a successful installation attempt.', true, ['platforms'])
->param('failure', '', fn ($platforms) => new Redirect($platforms), 'URL to redirect back to console after a failed installation attempt.', true, ['platforms'])
->inject('request')
->inject('response')
->inject('project')
@@ -437,6 +439,8 @@ App::get('/v1/vcs/github/authorize')
]);
$appName = System::getEnv('_APP_VCS_GITHUB_APP_NAME');
$protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS') === 'disabled' ? 'http' : 'https';
$hostname = System::getEnv('_APP_CONSOLE_DOMAIN', System::getEnv('_APP_DOMAIN', ''));
if (empty($appName)) {
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'GitHub App name is not configured. Please configure VCS (Version Control System) variables in .env file.');
@@ -444,7 +448,7 @@ App::get('/v1/vcs/github/authorize')
$url = "https://github.com/apps/$appName/installations/new?" . \http_build_query([
'state' => $state,
'redirect_uri' => $request->getProtocol() . '://' . $request->getHostname() . "/v1/vcs/github/callback"
'redirect_uri' => $protocol . '://' . $hostname . "/v1/vcs/github/callback"
]);
$response
@@ -494,10 +498,12 @@ App::get('/v1/vcs/github/callback')
}
$region = $project->getAttribute('region', 'default');
$protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS') === 'disabled' ? 'http' : 'https';
$hostname = System::getEnv('_APP_CONSOLE_DOMAIN', System::getEnv('_APP_DOMAIN', ''));
$defaultState = [
'success' => $request->getProtocol() . '://' . $request->getHostname() . "/console/project-$region-$projectId/settings/git-installations",
'failure' => $request->getProtocol() . '://' . $request->getHostname() . "/console/project-$region-$projectId/settings/git-installations",
'success' => $protocol . '://' . $hostname . "/console/project-$region-$projectId/settings/git-installations",
'failure' => $protocol . '://' . $hostname . "/console/project-$region-$projectId/settings/git-installations",
];
$state = \array_merge($defaultState, $state ?? []);
+37 -53
View File
@@ -49,14 +49,13 @@ use Utopia\Logger\Log\User;
use Utopia\Logger\Logger;
use Utopia\Platform\Service;
use Utopia\System\System;
use Utopia\Validator\Hostname;
use Utopia\Validator\Text;
Config::setParam('domainVerification', false);
Config::setParam('cookieDomain', 'localhost');
Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE);
function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, SwooleRequest $swooleRequest, Request $request, Response $response, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Executor $executor, Reader $geodb, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey)
function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Executor $executor, Reader $geodb, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey)
{
$host = $request->getHostname() ?? '';
if (!empty($previewHostname)) {
@@ -76,7 +75,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
}
$errorView = __DIR__ . '/../views/general/error.phtml';
$url = (System::getEnv('_APP_OPTIONS_FORCE_HTTPS') == 'disabled' ? 'http' : 'https') . '://' . System::getEnv('_APP_DOMAIN', '');
$url = (System::getEnv('_APP_OPTIONS_FORCE_HTTPS') == 'disabled' ? 'http' : 'https') . '://' . System::getEnv('_APP_CONSOLE_DOMAIN', System::getEnv('_APP_DOMAIN', ''));
if ($rule->isEmpty()) {
$appDomainFunctionsFallback = System::getEnv('_APP_DOMAIN_FUNCTIONS_FALLBACK', '');
@@ -118,6 +117,11 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
$project->setAttribute('accessedAt', DateTime::now());
Authorization::skip(fn () => $dbForPlatform->updateDocument('projects', $project->getId(), $project));
}
/**
* Set projectId to update the Error hook logger, since x-appwrite-project is not available when executing custom domain function
*/
$log->addTag('projectId', $project->getId());
}
if (array_key_exists('proxy', $project->getAttribute('services', []))) {
@@ -262,7 +266,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
}
if (!$authorized) {
$url = (System::getEnv('_APP_OPTIONS_FORCE_HTTPS') == 'disabled' ? 'http' : 'https') . "://" . System::getEnv('_APP_DOMAIN');
$url = (System::getEnv('_APP_OPTIONS_FORCE_HTTPS') == 'disabled' ? 'http' : 'https') . "://" . System::getEnv('_APP_CONSOLE_DOMAIN', System::getEnv('_APP_DOMAIN', ''));
$response
->addHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
->addHeader('Pragma', 'no-cache')
@@ -448,7 +452,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
$vars[$var->getAttribute('key')] = $var->getAttribute('value', '');
}
$protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS') == 'disabled' ? 'http' : 'https';
$protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS') === 'disabled' ? 'http' : 'https';
$hostname = System::getEnv('_APP_DOMAIN');
$endpoint = $protocol . '://' . $hostname . "/v1";
@@ -787,13 +791,14 @@ App::init()
->inject('swooleRequest')
->inject('request')
->inject('response')
->inject('log')
->inject('console')
->inject('project')
->inject('dbForPlatform')
->inject('getProjectDB')
->inject('locale')
->inject('localeCodes')
->inject('clients')
->inject('platforms')
->inject('geodb')
->inject('queueForStatsUsage')
->inject('queueForEvents')
@@ -804,7 +809,9 @@ App::init()
->inject('previewHostname')
->inject('devKey')
->inject('apiKey')
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForPlatform, callable $getProjectDB, Locale $locale, array $localeCodes, array $clients, Reader $geodb, StatsUsage $queueForStatsUsage, Event $queueForEvents, Certificate $queueForCertificates, Func $queueForFunctions, Executor $executor, callable $isResourceBlocked, string $previewHostname, Document $devKey, ?Key $apiKey) {
->inject('httpReferrer')
->inject('httpReferrerSafe')
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Document $console, Document $project, Database $dbForPlatform, callable $getProjectDB, Locale $locale, array $localeCodes, array $platforms, Reader $geodb, StatsUsage $queueForStatsUsage, Event $queueForEvents, Certificate $queueForCertificates, Func $queueForFunctions, Executor $executor, callable $isResourceBlocked, string $previewHostname, Document $devKey, ?Key $apiKey, string $httpReferrer, string $httpReferrerSafe) {
/*
* Appwrite Router
*/
@@ -812,7 +819,7 @@ App::init()
$mainDomain = System::getEnv('_APP_DOMAIN', '');
// Only run Router when external domain
if ($host !== $mainDomain || !empty($previewHostname)) {
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $executor, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $log, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $executor, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
$utopia->getRoute()?->label('router', true);
}
}
@@ -936,42 +943,9 @@ App::init()
$locale->setDefault($localeParam);
}
$referrer = $request->getReferer();
$origin = \parse_url($request->getOrigin($referrer), PHP_URL_HOST);
$protocol = \parse_url($request->getOrigin($referrer), PHP_URL_SCHEME);
$port = \parse_url($request->getOrigin($referrer), PHP_URL_PORT);
$refDomainOrigin = 'localhost';
$validator = new Hostname($clients);
if ($validator->isValid($origin)) {
$refDomainOrigin = $origin;
} elseif (!empty($origin)) {
// Auto-allow domains with linked rule
if (System::getEnv('_APP_RULES_FORMAT') === 'md5') {
$rule = Authorization::skip(fn () => $dbForPlatform->getDocument('rules', md5($origin ?? '')));
} else {
$rule = Authorization::skip(
fn () => $dbForPlatform->find('rules', [
Query::equal('domain', [$origin]),
Query::limit(1)
])
)[0] ?? new Document();
}
if (!$rule->isEmpty() && $rule->getAttribute('projectInternalId') === $project->getSequence()) {
$refDomainOrigin = $origin;
}
}
$refDomain = (!empty($protocol) ? $protocol : $request->getProtocol()) . '://' . $refDomainOrigin . (!empty($port) ? ':' . $port : '');
$refDomain = (!$route->getLabel('origin', false)) // This route is publicly accessible
? $refDomain
: (!empty($protocol) ? $protocol : $request->getProtocol()) . '://' . $origin . (!empty($port) ? ':' . $port : '');
$origin = \parse_url($request->getOrigin($httpReferrer), PHP_URL_HOST);
$selfDomain = new Domain($request->getHostname());
$endDomain = new Domain((string)$origin);
Config::setParam(
'domainVerification',
($selfDomain->getRegisterable() === $endDomain->getRegisterable()) &&
@@ -1043,7 +1017,7 @@ App::init()
->addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE')
->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Dev-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Forwarded-For, X-Forwarded-User-Agent')
->addHeader('Access-Control-Expose-Headers', 'X-Appwrite-Session, X-Fallback-Cookies')
->addHeader('Access-Control-Allow-Origin', $refDomain)
->addHeader('Access-Control-Allow-Origin', $httpReferrerSafe)
->addHeader('Access-Control-Allow-Credentials', 'true');
if (!$devKey->isEmpty()) {
@@ -1056,14 +1030,16 @@ App::init()
* Skip this check for non-web platforms which are not required to send an origin header
*/
$origin = $request->getOrigin($request->getReferer(''));
$originValidator = new Origin(\array_merge($project->getAttribute('platforms', []), $console->getAttribute('platforms', [])));
$originValidator = new Origin($platforms);
if (
!$originValidator->isValid($origin)
&& $devKey->isEmpty()
$devKey->isEmpty()
&& !empty($origin)
&& !$originValidator->isValid($origin)
&& \in_array($request->getMethod(), [Request::METHOD_POST, Request::METHOD_PUT, Request::METHOD_PATCH, Request::METHOD_DELETE])
&& $route->getLabel('origin', false) !== '*'
&& empty($request->getHeader('x-appwrite-key', ''))
&& \parse_url($httpReferrerSafe, PHP_URL_HOST) === 'localhost'
) {
throw new AppwriteException(AppwriteException::GENERAL_UNKNOWN_ORIGIN, $originValidator->getDescription());
}
@@ -1074,6 +1050,7 @@ App::options()
->inject('swooleRequest')
->inject('request')
->inject('response')
->inject('log')
->inject('dbForPlatform')
->inject('getProjectDB')
->inject('queueForEvents')
@@ -1086,7 +1063,7 @@ App::options()
->inject('project')
->inject('devKey')
->inject('apiKey')
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Executor $executor, Reader $geodb, callable $isResourceBlocked, string $previewHostname, Document $project, Document $devKey, ?Key $apiKey) {
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Executor $executor, Reader $geodb, callable $isResourceBlocked, string $previewHostname, Document $project, Document $devKey, ?Key $apiKey) {
/*
* Appwrite Router
*/
@@ -1094,7 +1071,7 @@ App::options()
$mainDomain = System::getEnv('_APP_DOMAIN', '');
// Only run Router when external domain
if ($host !== $mainDomain || !empty($previewHostname)) {
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $executor, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $log, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $executor, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
$utopia->getRoute()?->label('router', true);
}
}
@@ -1267,7 +1244,12 @@ App::error()
$log->addTag('url', $request->getURI());
$log->addTag('verboseType', get_class($error));
$log->addTag('code', $error->getCode());
$log->addTag('projectId', $project->getId());
$tags = $log->getTags();
if (!isset($tags['projectId'])) {
$log->addTag('projectId', $project->getId());
}
$log->addTag('hostname', $request->getHostname());
$log->addTag('locale', (string)$request->getParam('locale', $request->getHeader('x-appwrite-locale', '')));
@@ -1385,6 +1367,7 @@ App::get('/robots.txt')
->inject('swooleRequest')
->inject('request')
->inject('response')
->inject('log')
->inject('dbForPlatform')
->inject('getProjectDB')
->inject('queueForEvents')
@@ -1395,7 +1378,7 @@ App::get('/robots.txt')
->inject('isResourceBlocked')
->inject('previewHostname')
->inject('apiKey')
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Executor $executor, Reader $geodb, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey) {
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Executor $executor, Reader $geodb, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey) {
$host = $request->getHostname() ?? '';
$mainDomain = System::getEnv('_APP_DOMAIN', '');
@@ -1403,7 +1386,7 @@ App::get('/robots.txt')
$template = new View(__DIR__ . '/../views/general/robots.phtml');
$response->text($template->render(false));
} else {
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $executor, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $log, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $executor, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
$utopia->getRoute()?->label('router', true);
}
}
@@ -1417,6 +1400,7 @@ App::get('/humans.txt')
->inject('swooleRequest')
->inject('request')
->inject('response')
->inject('log')
->inject('dbForPlatform')
->inject('getProjectDB')
->inject('queueForEvents')
@@ -1427,7 +1411,7 @@ App::get('/humans.txt')
->inject('isResourceBlocked')
->inject('previewHostname')
->inject('apiKey')
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Executor $executor, Reader $geodb, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey) {
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Executor $executor, Reader $geodb, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey) {
$host = $request->getHostname() ?? '';
$mainDomain = System::getEnv('_APP_DOMAIN', '');
@@ -1435,7 +1419,7 @@ App::get('/humans.txt')
$template = new View(__DIR__ . '/../views/general/humans.phtml');
$response->text($template->render(false));
} else {
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $executor, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $log, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $executor, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
$utopia->getRoute()?->label('router', true);
}
}
-26
View File
@@ -129,32 +129,6 @@ App::get('/v1/mock/tests/general/oauth2/failure')
]);
});
App::patch('/v1/mock/functions-v2')
->desc('Update Function Version to V2 (outdated code syntax)')
->groups(['mock', 'api', 'functions'])
->label('scope', 'functions.write')
->label('docs', false)
->param('functionId', '', new UID(), 'Function ID.')
->inject('response')
->inject('dbForProject')
->action(function (string $functionId, Response $response, Database $dbForProject) {
$isDevelopment = System::getEnv('_APP_ENV', 'development') === 'development';
if (!$isDevelopment) {
throw new Exception(Exception::GENERAL_NOT_IMPLEMENTED);
}
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception(Exception::FUNCTION_NOT_FOUND);
}
$dbForProject->updateDocument('functions', $function->getId(), $function->setAttribute('version', 'v2'));
$response->noContent();
});
App::post('/v1/mock/api-key-unprefixed')
->desc('Create API Key (without standard prefix)')
->groups(['mock', 'api', 'projects'])
+14 -5
View File
@@ -22,6 +22,7 @@ use Utopia\Abuse\Abuse;
use Utopia\App;
use Utopia\Cache\Adapter\Filesystem;
use Utopia\Cache\Cache;
use Utopia\CLI\Console;
use Utopia\Config\Config;
use Utopia\Database\Database;
use Utopia\Database\DateTime;
@@ -563,7 +564,7 @@ App::init()
$cache = new Cache(
new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $project->getId())
);
$timestamp = 60 * 60 * 24 * 30;
$timestamp = 60 * 60 * 24 * 180; // Temporarily increase the TTL to 180 day to ensure files in the cache are still fetched.
$data = $cache->load($key, $timestamp);
if (!empty($data) && !$cacheLog->isEmpty()) {
@@ -575,7 +576,6 @@ App::init()
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
$isToken = !$resourceToken->isEmpty() && $resourceToken->getAttribute('bucketInternalId') === $bucket->getSequence();
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAppUser && !$isPrivilegedUser)) {
@@ -797,6 +797,12 @@ App::shutdown()
}
if (!empty($queueForDatabase->getType())) {
Console::info("Triggering database event: \n" . \json_encode([
'projectId' => $project->getId(),
'databaseId' => $queueForDatabase->getDatabase()?->getId(),
'collectionId' => $queueForDatabase->getCollection()?->getId(),
'documentId' => $queueForDatabase->getDocument()?->getId(),
]));
$queueForDatabase->trigger();
}
@@ -824,6 +830,10 @@ App::shutdown()
$resourceType = $parseLabel($pattern, $responsePayload, $requestParams, $user);
}
$cache = new Cache(
new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $project->getId())
);
$key = $request->cacheIdentifier();
$signature = md5($data['payload']);
$cacheLog = Authorization::skip(fn () => $dbForProject->getDocument('cache', $key));
@@ -841,12 +851,11 @@ App::shutdown()
} elseif (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_CACHE_UPDATE)) > $accessedAt) {
$cacheLog->setAttribute('accessedAt', $now);
Authorization::skip(fn () => $dbForProject->updateDocument('cache', $cacheLog->getId(), $cacheLog));
// Overwrite the file every APP_CACHE_UPDATE seconds to update the file modified time that is used in the TTL checks in cache->load()
$cache->save($key, $data['payload']);
}
if ($signature !== $cacheLog->getAttribute('signature')) {
$cache = new Cache(
new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $project->getId())
);
$cache->save($key, $data['payload']);
}
}
+2 -1
View File
@@ -36,7 +36,8 @@ App::setMode(System::getEnv('_APP_ENV', App::MODE_TYPE_PRODUCTION));
if (!App::isProduction()) {
// Allow specific domains to skip public domain validation in dev environment
// Useful for existing tests involving webhooks
PublicDomain::allow(['request-catcher']);
PublicDomain::allow(['request-catcher-sms']);
PublicDomain::allow(['request-catcher-webhook']);
}
$register->set('logger', function () {
// Register error logger
+85 -32
View File
@@ -19,6 +19,7 @@ use Appwrite\Event\StatsUsage;
use Appwrite\Event\Webhook;
use Appwrite\Extend\Exception;
use Appwrite\GraphQL\Schema;
use Appwrite\Network\Platform;
use Appwrite\Network\Validator\Origin;
use Appwrite\Utopia\Request;
use Executor\Executor;
@@ -79,9 +80,15 @@ App::setResource('localeCodes', function () {
App::setResource('publisher', function (Group $pools) {
return new BrokerPool(publisher: $pools->get('publisher'));
}, ['pools']);
App::setResource('publisherRedis', function () {
// Stub
});
App::setResource('consumer', function (Group $pools) {
return new BrokerPool(consumer: $pools->get('consumer'));
}, ['pools']);
App::setResource('consumerRedis', function () {
// Stub
});
App::setResource('queueForMessaging', function (Publisher $publisher) {
return new Messaging($publisher);
}, ['publisher']);
@@ -121,11 +128,11 @@ App::setResource('queueForCertificates', function (Publisher $publisher) {
App::setResource('queueForMigrations', function (Publisher $publisher) {
return new Migration($publisher);
}, ['publisher']);
App::setResource('clients', function ($request, $console, $project) {
App::setResource('platforms', function (Request $request, Document $console, Document $project) {
$console->setAttribute('platforms', [ // Always allow current host
'$collection' => ID::custom('platforms'),
'name' => 'Current Host',
'type' => Origin::CLIENT_TYPE_WEB,
'type' => Platform::TYPE_WEB,
'hostname' => $request->getHostname(),
], Document::SET_TYPE_APPEND);
@@ -138,39 +145,32 @@ App::setResource('clients', function ($request, $console, $project) {
}
$console->setAttribute('platforms', [
'$collection' => ID::custom('platforms'),
'type' => Origin::CLIENT_TYPE_WEB,
'type' => Platform::TYPE_WEB,
'name' => $hostname,
'hostname' => $hostname,
], Document::SET_TYPE_APPEND);
}
/**
* Get All verified client URLs for both console and current projects
* + Filter for duplicated entries
*/
$clientsConsole = \array_map(
fn ($node) => $node['hostname'],
\array_filter(
$console->getAttribute('platforms', []),
fn ($node) => (isset($node['type']) && ($node['type'] === Origin::CLIENT_TYPE_WEB) && !empty($node['hostname']))
)
);
$clients = $clientsConsole;
$platforms = $project->getAttribute('platforms', []);
foreach ($platforms as $node) {
if (
isset($node['type']) &&
($node['type'] === Origin::CLIENT_TYPE_WEB ||
$node['type'] === Origin::CLIENT_TYPE_FLUTTER_WEB) &&
!empty($node['hostname'])
) {
$clients[] = $node['hostname'];
}
// Add `exp` and `appwrite-callback-{projectId}` schemes
if (!$project->isEmpty() && $project->getId() !== 'console') {
$project->setAttribute('platforms', [
'$collection' => ID::custom('platforms'),
'type' => Platform::TYPE_SCHEME,
'name' => 'Expo',
'key' => 'exp',
], Document::SET_TYPE_APPEND);
$project->setAttribute('platforms', [
'$collection' => ID::custom('platforms'),
'type' => Platform::TYPE_SCHEME,
'name' => 'Appwrite Callback',
'key' => 'appwrite-callback-' . $project->getId(),
], Document::SET_TYPE_APPEND);
}
return \array_unique($clients);
return [
...$console->getAttribute('platforms', []),
...$project->getAttribute('platforms', []),
];
}, ['request', 'console', 'project']);
App::setResource('user', function ($mode, $project, $console, $request, $response, $dbForProject, $dbForPlatform) {
@@ -222,7 +222,9 @@ App::setResource('user', function ($mode, $project, $console, $request, $respons
Auth::$unique = $session['id'] ?? '';
Auth::$secret = $session['secret'] ?? '';
if (APP_MODE_ADMIN !== $mode) {
if ($mode === APP_MODE_ADMIN) {
$user = $dbForPlatform->getDocument('users', Auth::$unique);
} else {
if ($project->isEmpty()) {
$user = new Document([]);
} else {
@@ -232,8 +234,6 @@ App::setResource('user', function ($mode, $project, $console, $request, $respons
$user = $dbForProject->getDocument('users', Auth::$unique);
}
}
} else {
$user = $dbForPlatform->getDocument('users', Auth::$unique);
}
if (
@@ -264,7 +264,11 @@ App::setResource('user', function ($mode, $project, $console, $request, $respons
$jwtUserId = $payload['userId'] ?? '';
if (!empty($jwtUserId)) {
$user = $dbForProject->getDocument('users', $jwtUserId);
if ($mode === APP_MODE_ADMIN) {
$user = $dbForPlatform->getDocument('users', $jwtUserId);
} else {
$user = $dbForProject->getDocument('users', $jwtUserId);
}
}
$jwtSessionId = $payload['sessionId'] ?? '';
@@ -944,3 +948,52 @@ App::setResource('resourceToken', function ($project, $dbForProject, $request) {
}
return new Document([]);
}, ['project', 'dbForProject', 'request']);
App::setResource('httpReferrer', function (Request $request): string {
$referrer = $request->getReferer();
return $referrer;
}, ['request']);
App::setResource('httpReferrerSafe', function (Request $request, string $httpReferrer, array $platforms, Database $dbForPlatform, Document $project, App $utopia): string {
$origin = \parse_url($request->getOrigin($httpReferrer), PHP_URL_HOST);
$protocol = \parse_url($request->getOrigin($httpReferrer), PHP_URL_SCHEME);
$port = \parse_url($request->getOrigin($httpReferrer), PHP_URL_PORT);
$referrer = (!empty($protocol) ? $protocol : $request->getProtocol()) . '://' . $origin . (!empty($port) ? ':' . $port : '');
// Safe if route is publicly accessible
$route = $utopia->getRoute();
if ($route->getLabel('origin', false)) {
return $referrer;
}
// Safe if added as web platform
$originValidator = new Origin($platforms);
if ($originValidator->isValid($request->getOrigin($httpReferrer))) {
return $referrer;
}
// Safe if rule with same project ID exists
if (!empty($origin)) {
if (System::getEnv('_APP_RULES_FORMAT') === 'md5') {
$rule = Authorization::skip(fn () => $dbForPlatform->getDocument('rules', md5($origin ?? '')));
} else {
$rule = Authorization::skip(
fn () => $dbForPlatform->find('rules', [
Query::equal('domain', [$origin]),
Query::limit(1)
])
)[0] ?? new Document();
}
if (!$rule->isEmpty() && $rule->getAttribute('projectInternalId') === $project->getSequence()) {
return $referrer;
}
}
// Unsafe; Localhost is always safe for ease of local development
$origin = 'localhost';
$protocol = \parse_url($request->getOrigin($httpReferrer), PHP_URL_SCHEME);
$port = \parse_url($request->getOrigin($httpReferrer), PHP_URL_PORT);
$referrer = (!empty($protocol) ? $protocol : $request->getProtocol()) . '://' . $origin . (!empty($port) ? ':' . $port : '');
return $referrer;
}, ['request', 'httpReferrer', 'platforms', 'dbForPlatform', 'project', 'utopia']);
+3 -3
View File
@@ -532,7 +532,7 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server,
}
$timelimit = $app->getResource('timelimit');
$console = $app->getResource('console'); /** @var Document $console */
$platforms = $app->getResource('platforms');
$user = $app->getResource('user'); /** @var Document $user */
/*
@@ -557,9 +557,9 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server,
* Skip this check for non-web platforms which are not required to send an origin header.
*/
$origin = $request->getOrigin();
$originValidator = new Origin(array_merge($project->getAttribute('platforms', []), $console->getAttribute('platforms', [])));
$originValidator = new Origin($platforms);
if (!$originValidator->isValid($origin) && $project->getId() !== 'console') {
if (!empty($origin) && !$originValidator->isValid($origin) && $project->getId() !== 'console') {
throw new Exception(Exception::REALTIME_POLICY_VIOLATION, $originValidator->getDescription());
}
+1 -1
View File
@@ -15,7 +15,7 @@ $labelClass = '';
$buttons = [];
$protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS') == 'disabled' ? 'http' : 'https';
$hostname = System::getEnv('_APP_DOMAIN');
$hostname = System::getEnv('_APP_CONSOLE_DOMAIN', System::getEnv('_APP_DOMAIN', ''));
// TODO: remove this later
if (System::getEnv('_APP_ENV') === 'development') {
$hostname = 'localhost';
+1 -1
View File
@@ -864,7 +864,7 @@ $image = $this->getParam('image', '');
<<: *x-logging
restart: unless-stopped
stop_signal: SIGINT
image: openruntimes/executor:0.7.20
image: openruntimes/executor:0.7.22
networks:
- appwrite
- runtimes
+10 -11
View File
@@ -18,9 +18,7 @@ use Appwrite\Event\StatsUsage;
use Appwrite\Event\Webhook;
use Appwrite\Platform\Appwrite;
use Executor\Executor;
use Swoole\Process;
use Swoole\Runtime;
use Swoole\Timer;
use Utopia\Abuse\Adapters\TimeLimit\Redis as TimeLimitRedis;
use Utopia\Cache\Adapter\Pool as CachePool;
use Utopia\Cache\Adapter\Sharding;
@@ -249,10 +247,18 @@ Server::setResource('publisher', function (Group $pools) {
return new BrokerPool(publisher: $pools->get('publisher'));
}, ['pools']);
Server::setResource('publisherRedis', function () {
// Stub
});
Server::setResource('consumer', function (Group $pools) {
return new BrokerPool(consumer: $pools->get('consumer'));
}, ['pools']);
Server::setResource('consumerRedis', function () {
// Stub
});
Server::setResource('queueForStatsUsage', function (Publisher $publisher) {
return new StatsUsage($publisher);
}, ['publisher']);
@@ -484,15 +490,8 @@ $worker
});
$worker->workerStart()
->action(function () use ($worker, $workerName) {
Console::info("Worker $workerName started");
Process::signal(SIGTERM, function () use ($worker, $workerName) {
Console::info("Stopping worker $workerName.");
$worker->stop();
Timer::clearAll();
});
->action(function () use ($workerName) {
Console::info("Worker $workerName started");
});
$worker->start();
+1 -1
View File
@@ -1,3 +1,3 @@
#!/bin/sh
exec php /usr/src/code/app/cli.php doctor $@
php /usr/src/code/app/cli.php doctor $@
+1 -1
View File
@@ -1,3 +1,3 @@
#!/bin/sh
exec php /usr/src/code/app/cli.php install $@
php /usr/src/code/app/cli.php install $@
+1 -1
View File
@@ -1,3 +1,3 @@
#!/bin/sh
exec php /usr/src/code/app/cli.php maintenance $@
php /usr/src/code/app/cli.php maintenance $@
+1 -1
View File
@@ -1,3 +1,3 @@
#!/bin/sh
exec php /usr/src/code/app/cli.php migrate $@
php /usr/src/code/app/cli.php migrate $@
+1 -1
View File
@@ -1,3 +1,3 @@
#!/bin/sh
exec php /usr/src/code/app/cli.php queue-count --type=failed $@
php /usr/src/code/app/cli.php queue-count --type=failed $@
+1 -1
View File
@@ -1,3 +1,3 @@
#!/bin/sh
exec php /usr/src/code/app/cli.php queue-count --type=processing $@
php /usr/src/code/app/cli.php queue-count --type=processing $@
+1 -1
View File
@@ -1,3 +1,3 @@
#!/bin/sh
exec php /usr/src/code/app/cli.php queue-count --type=success $@
php /usr/src/code/app/cli.php queue-count --type=success $@
+1 -1
View File
@@ -1,3 +1,3 @@
#!/bin/sh
exec php /usr/src/code/app/cli.php queue-retry $@
php /usr/src/code/app/cli.php queue-retry $@
+1 -1
View File
@@ -1,3 +1,3 @@
#!/bin/sh
exec php /usr/src/code/app/realtime.php $@
php /usr/src/code/app/realtime.php $@
+1 -1
View File
@@ -1,3 +1,3 @@
#!/bin/sh
exec php /usr/src/code/app/cli.php schedule-executions $@
php /usr/src/code/app/cli.php schedule-executions $@
+1 -1
View File
@@ -1,3 +1,3 @@
#!/bin/sh
exec php /usr/src/code/app/cli.php schedule-functions $@
php /usr/src/code/app/cli.php schedule-functions $@
+1 -1
View File
@@ -1,3 +1,3 @@
#!/bin/sh
exec php /usr/src/code/app/cli.php schedule-messages $@
php /usr/src/code/app/cli.php schedule-messages $@

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