Compare commits

..

213 Commits

Author SHA1 Message Date
Matteo Pagliazzi 27263e9b2f 4.140.8 2020-04-18 17:41:40 +02:00
Matteo Pagliazzi 2d9715b657 fix(apple auth): add needed env var to client and encode redirect url 2020-04-18 17:41:25 +02:00
Matteo Pagliazzi 9f9da5632d 4.140.7 2020-04-18 16:02:23 +02:00
Matteo Pagliazzi 9364cdc2b4 fix(apple auth): do not try to parse name if it is missing, add query parameters to logs 2020-04-18 16:02:18 +02:00
Sabe Jones 484bae40cd 4.140.6 2020-04-17 14:24:42 -05:00
Sabe Jones c0b6353ded chore(analytics): change up drop tracking 2020-04-17 14:24:34 -05:00
Matteo Pagliazzi 8da36bf27c 4.140.5 2020-04-17 15:09:12 +02:00
Matteo Pagliazzi 1800fabaaa Merge pull request #129 from HabitRPG/cache-fixes-3
API Cache fixes
2020-04-17 15:08:15 +02:00
Matteo Pagliazzi cda5c6fbb0 res.header -> res.set 2020-04-17 14:57:53 +02:00
Matteo Pagliazzi 495d01f386 fix(static files): cache more static files (#12102) 2020-04-17 14:52:28 +02:00
Matteo Pagliazzi 24e1bfdfba add basic test, disable etag on post routes as well, paypal ipn: prevent set headers after response error 2020-04-17 14:50:09 +02:00
Matteo Pagliazzi f757e645b7 disable caching for the /status api route 2020-04-17 14:22:32 +02:00
Matteo Pagliazzi bf492933cc fix(cache): explicitly disable caching for most api routes 2020-04-17 14:22:20 +02:00
Sabe Jones cc7dac47c4 4.140.4 2020-04-16 15:18:00 -05:00
Sabe Jones c8189360d6 Merge branch 'develop' into release 2020-04-16 15:17:56 -05:00
Sabe Jones 88183149c5 chore(news): Bailey 2020-04-16 15:17:14 -05:00
Matteo Pagliazzi a8f397c674 fix(join group): do not throw if inviter has does not exist 2020-04-15 21:43:24 +02:00
Matteo Pagliazzi c5aeab652d Push Notifications Fixes - Part 2 (#12092)
* push notifications: handle some more error codes and when the user is loaded using .lean()

* fix lint

* do not send push notification if message is missing
2020-04-15 21:36:53 +02:00
Melior cc04761c24 Merge branch 'origin/develop' into Weblate. 2020-04-14 22:55:19 +02:00
Melior 29dccdd148 Translated using Weblate (Dutch)
Currently translated at 95.9% (666 of 694 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/nl/

Merge branch 'origin/develop' into Weblate.

Translated using Weblate (Swedish)

Currently translated at 95.0% (133 of 140 strings)

Translation: Habitica/Quests
Translate-URL: https://translate.habitica.com/projects/habitica/quests/sv/

Translated using Weblate (German)

Currently translated at 99.7% (2086 of 2091 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/de/

Translated using Weblate (Romanian)

Currently translated at 100.0% (298 of 298 strings)

Translation: Habitica/Generic
Translate-URL: https://translate.habitica.com/projects/habitica/generic/ro/

Translated using Weblate (Dutch)

Currently translated at 95.3% (662 of 694 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/nl/

Translated using Weblate (German)

Currently translated at 99.8% (693 of 694 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/de/

Translated using Weblate (German)

Currently translated at 99.8% (693 of 694 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/de/

Translated using Weblate (Romanian)

Currently translated at 100.0% (126 of 126 strings)

Translation: Habitica/Communityguidelines
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (211 of 211 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/ro/

Translated using Weblate (Japanese)

Currently translated at 100.0% (67 of 67 strings)

Translation: Habitica/Messages
Translate-URL: https://translate.habitica.com/projects/habitica/messages/ja/

Translated using Weblate (Japanese)

Currently translated at 100.0% (492 of 492 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ja/

Translated using Weblate (Japanese)

Currently translated at 100.0% (298 of 298 strings)

Translation: Habitica/Generic
Translate-URL: https://translate.habitica.com/projects/habitica/generic/ja/

Translated using Weblate (Romanian)

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (211 of 211 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/ro/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (492 of 492 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/pt_BR/

Translated using Weblate (German)

Currently translated at 99.4% (2080 of 2091 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/de/

Translated using Weblate (Russian)

Currently translated at 99.5% (691 of 694 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/ru/

Translated using Weblate (Japanese)

Currently translated at 90.3% (224 of 248 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ja/

Translated using Weblate (Russian)

Currently translated at 100.0% (140 of 140 strings)

Translation: Habitica/Quests
Translate-URL: https://translate.habitica.com/projects/habitica/quests/ru/

Translated using Weblate (Dutch)

Currently translated at 100.0% (140 of 140 strings)

Translation: Habitica/Quests
Translate-URL: https://translate.habitica.com/projects/habitica/quests/nl/

Translated using Weblate (Romanian)

Currently translated at 100.0% (8 of 8 strings)

Translation: Habitica/Overview
Translate-URL: https://translate.habitica.com/projects/habitica/overview/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (67 of 67 strings)

Translation: Habitica/Messages
Translate-URL: https://translate.habitica.com/projects/habitica/messages/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (31 of 31 strings)

Translation: Habitica/Maintenance
Translate-URL: https://translate.habitica.com/projects/habitica/maintenance/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (63 of 63 strings)

Translation: Habitica/Defaulttasks
Translate-URL: https://translate.habitica.com/projects/habitica/defaulttasks/ro/

Translated using Weblate (Russian)

Currently translated at 98.7% (685 of 694 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/ru/

Translated using Weblate (Dutch)

Currently translated at 94.6% (657 of 694 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/nl/

Translated using Weblate (French)

Currently translated at 100.0% (694 of 694 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (French)

Currently translated at 100.0% (358 of 358 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/fr/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (694 of 694 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/pt_BR/
2020-04-14 22:55:14 +02:00
Denys Dorokhov 186b929e59 API-v4 route added: 'api/v4/faq' fixes #11801 (#11905)
* feat(api-v4): new /faq route added

* refactor(server): change of function name in libs/content.js
2020-04-14 22:14:53 +02:00
Matteo Pagliazzi 551abf292c Removed loading screen tips, fixes #11834 (#12063)
* removed loading tip div

* removed loading tip number logic

* removed loadingScreenTips.json
2020-04-14 22:03:57 +02:00
Sabe Jones 1e1c058d82 Merge branch 'release' into develop 2020-04-14 14:50:46 -05:00
Sabe Jones 2ea9070a9b 4.140.3 2020-04-14 14:50:10 -05:00
Sabe Jones 168a3a6e89 Merge branch 'sabrecat/potion-time' into release 2020-04-14 14:49:18 -05:00
Sabe Jones 67bd2d9130 feat(content): enable spring avatar customizations 2020-04-14 14:49:11 -05:00
Matteo Pagliazzi cb0280ca8b fix(lint): move old migration to archive 2020-04-14 19:15:29 +02:00
Matteo Pagliazzi 259b15877b chore(deps): remove unused aws-sdk file and dependency 2020-04-14 17:03:42 +02:00
Matteo Pagliazzi dd31f559c7 onboarding guide improvements (#12068) 2020-04-13 16:19:46 +02:00
dependabot-preview[bot] 6c29ea8c4c build(deps): bump @vue/cli-plugin-unit-mocha in /website/client (#12081)
Bumps [@vue/cli-plugin-unit-mocha](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-unit-mocha) from 4.3.0 to 4.3.1.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.3.1/packages/@vue/cli-plugin-unit-mocha)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-13 14:53:29 +02:00
dependabot-preview[bot] dc316ad1c8 build(deps): bump @vue/cli-plugin-eslint in /website/client (#12076)
Bumps [@vue/cli-plugin-eslint](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-eslint) from 4.3.0 to 4.3.1.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.3.1/packages/@vue/cli-plugin-eslint)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-13 13:35:39 +02:00
dependabot-preview[bot] a5b37fcc02 build(deps): bump @vue/cli-service in /website/client (#12080)
Bumps [@vue/cli-service](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-service) from 4.3.0 to 4.3.1.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.3.1/packages/@vue/cli-service)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-13 13:31:25 +02:00
Matteo Pagliazzi 16f1c7286b Merge pull request #12084 from HabitRPG/dependabot/npm_and_yarn/website/client/vue/cli-plugin-router-4.3.1
build(deps): bump @vue/cli-plugin-router from 4.3.0 to 4.3.1 in /website/client
2020-04-13 13:28:15 +02:00
Matteo Pagliazzi d5b3e4ec9f Merge pull request #12075 from HabitRPG/dependabot/npm_and_yarn/website/client/bootstrap-vue-2.11.0
build(deps): bump bootstrap-vue from 2.10.1 to 2.11.0 in /website/client
2020-04-13 13:27:53 +02:00
Matteo Pagliazzi 47eb9bf3ff Merge pull request #12073 from HabitRPG/dependabot/npm_and_yarn/website/client/vue/cli-plugin-babel-4.3.1
build(deps): bump @vue/cli-plugin-babel from 4.3.0 to 4.3.1 in /website/client
2020-04-13 13:27:31 +02:00
Matteo Pagliazzi 2977346ccb Merge pull request #12074 from HabitRPG/dependabot/npm_and_yarn/website/client/amplitude-js-5.11.0
build(deps): bump amplitude-js from 5.10.0 to 5.11.0 in /website/client
2020-04-13 13:27:23 +02:00
Matteo Pagliazzi a545cc72d0 Merge pull request #12077 from HabitRPG/dependabot/npm_and_yarn/website/client/core-js-3.6.5
build(deps): bump core-js from 3.6.4 to 3.6.5 in /website/client
2020-04-13 13:27:08 +02:00
Matteo Pagliazzi 82548f69e5 Merge pull request #12078 from HabitRPG/dependabot/npm_and_yarn/website/client/jquery-3.5.0
build(deps): bump jquery from 3.4.1 to 3.5.0 in /website/client
2020-04-13 13:27:02 +02:00
Matteo Pagliazzi 5aacae3ead build(deps): bump aws-sdk from 2.653.0 to 2.656.0 (#12082)
Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.653.0 to 2.656.0.
- [Release notes](https://github.com/aws/aws-sdk-js/releases)
- [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js/compare/v2.653.0...v2.656.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-13 13:25:56 +02:00
dependabot-preview[bot] 9f8162b82c build(deps): bump @babel/preset-env from 7.9.0 to 7.9.5 (#12087)
Bumps [@babel/preset-env](https://github.com/babel/babel) from 7.9.0 to 7.9.5.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.9.0...v7.9.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-13 13:25:39 +02:00
dependabot-preview[bot] 98a749b239 build(deps): bump @vue/cli-plugin-router in /website/client
Bumps [@vue/cli-plugin-router](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-router) from 4.3.0 to 4.3.1.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.3.1/packages/@vue/cli-plugin-router)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-13 05:30:11 +00:00
dependabot-preview[bot] 0cef9eff87 build(deps): bump aws-sdk from 2.653.0 to 2.656.0
Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.653.0 to 2.656.0.
- [Release notes](https://github.com/aws/aws-sdk-js/releases)
- [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js/compare/v2.653.0...v2.656.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-13 05:29:33 +00:00
dependabot-preview[bot] 3189a944d7 build(deps): bump jquery from 3.4.1 to 3.5.0 in /website/client
Bumps [jquery](https://github.com/jquery/jquery) from 3.4.1 to 3.5.0.
- [Release notes](https://github.com/jquery/jquery/releases)
- [Commits](https://github.com/jquery/jquery/compare/3.4.1...3.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-13 05:26:48 +00:00
dependabot-preview[bot] 79066165e2 build(deps): bump core-js from 3.6.4 to 3.6.5 in /website/client
Bumps [core-js](https://github.com/zloirock/core-js) from 3.6.4 to 3.6.5.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/compare/v3.6.4...v3.6.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-13 05:25:49 +00:00
dependabot-preview[bot] c6f6df3f14 build(deps): bump bootstrap-vue from 2.10.1 to 2.11.0 in /website/client
Bumps [bootstrap-vue](https://github.com/bootstrap-vue/bootstrap-vue) from 2.10.1 to 2.11.0.
- [Release notes](https://github.com/bootstrap-vue/bootstrap-vue/releases)
- [Changelog](https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/bootstrap-vue/bootstrap-vue/compare/v2.10.1...v2.11.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-13 05:23:51 +00:00
dependabot-preview[bot] 7bfd6ceca1 build(deps): bump amplitude-js from 5.10.0 to 5.11.0 in /website/client
Bumps [amplitude-js](https://github.com/amplitude/amplitude-javascript) from 5.10.0 to 5.11.0.
- [Release notes](https://github.com/amplitude/amplitude-javascript/releases)
- [Changelog](https://github.com/amplitude/Amplitude-JavaScript/blob/master/CHANGELOG.md)
- [Commits](https://github.com/amplitude/amplitude-javascript/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-13 05:22:44 +00:00
dependabot-preview[bot] 400f4dfb01 build(deps): bump @vue/cli-plugin-babel in /website/client
Bumps [@vue/cli-plugin-babel](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-babel) from 4.3.0 to 4.3.1.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.3.1/packages/@vue/cli-plugin-babel)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-13 05:21:52 +00:00
Alys 57a9fb5241 add comment to contributor.critical flag in user model 2020-04-13 15:15:26 +10:00
Sabe Jones 08c63f94fc fix(shops): improve featured potion and quest 2020-04-10 16:17:15 -05:00
Sabe Jones 9c6c90a2e9 fix(potions): call out limited time 2020-04-10 15:15:23 -05:00
Sabe Jones 39765895ee fix(quest): call out limited time 2020-04-10 13:53:52 -05:00
Matteo Pagliazzi 2a8fc7aea2 Push Notifications Improvements (#12019)
* start fixing push notitifications

* push notifications: refactor error handling

* remove comment and improve logging

* improve emails errors

* wip: start improving webhooks tests

* add max length to push notifications and tests

* fix typos
2020-04-10 16:41:44 +02:00
Melior 0a86d04a15 Merge branch 'origin/develop' into Weblate. 2020-04-09 13:32:31 +02:00
Melior 3afa7e6da5 Translated using Weblate (Romanian)
Currently translated at 100.0% (248 of 248 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (140 of 140 strings)

Translation: Habitica/Quests
Translate-URL: https://translate.habitica.com/projects/habitica/quests/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (143 of 143 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (172 of 172 strings)

Translation: Habitica/Npc
Translate-URL: https://translate.habitica.com/projects/habitica/npc/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (8 of 8 strings)

Translation: Habitica/Overview
Translate-URL: https://translate.habitica.com/projects/habitica/overview/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (67 of 67 strings)

Translation: Habitica/Messages
Translate-URL: https://translate.habitica.com/projects/habitica/messages/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (31 of 31 strings)

Translation: Habitica/Maintenance
Translate-URL: https://translate.habitica.com/projects/habitica/maintenance/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (180 of 180 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (492 of 492 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (2091 of 2091 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (298 of 298 strings)

Translation: Habitica/Generic
Translate-URL: https://translate.habitica.com/projects/habitica/generic/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (328 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (63 of 63 strings)

Translation: Habitica/Defaulttasks
Translate-URL: https://translate.habitica.com/projects/habitica/defaulttasks/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (694 of 694 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (126 of 126 strings)

Translation: Habitica/Communityguidelines
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (358 of 358 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (522 of 522 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (77 of 77 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (211 of 211 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/ro/

Translated using Weblate (Japanese)

Currently translated at 100.0% (211 of 211 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/ja/

Translated using Weblate (Romanian)

Currently translated at 87.5% (7 of 8 strings)

Translation: Habitica/Overview
Translate-URL: https://translate.habitica.com/projects/habitica/overview/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (57 of 57 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/ro/

Translated using Weblate (Romanian)

Currently translated at 93.7% (134 of 143 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/ro/

Translated using Weblate (Romanian)

Currently translated at 87.5% (7 of 8 strings)

Translation: Habitica/Overview
Translate-URL: https://translate.habitica.com/projects/habitica/overview/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (6 of 6 strings)

Translation: Habitica/Inventory
Translate-URL: https://translate.habitica.com/projects/habitica/inventory/ro/

Translated using Weblate (Romanian)

Currently translated at 83.5% (1747 of 2091 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ro/

Translated using Weblate (Romanian)

Currently translated at 41.2% (26 of 63 strings)

Translation: Habitica/Defaulttasks
Translate-URL: https://translate.habitica.com/projects/habitica/defaulttasks/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (28 of 28 strings)

Translation: Habitica/Rebirth
Translate-URL: https://translate.habitica.com/projects/habitica/rebirth/ro/

Translated using Weblate (Romanian)

Currently translated at 96.7% (30 of 31 strings)

Translation: Habitica/Maintenance
Translate-URL: https://translate.habitica.com/projects/habitica/maintenance/ro/

Translated using Weblate (Romanian)

Currently translated at 98.7% (324 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/ro/

Translated using Weblate (Romanian)

Currently translated at 96.0% (121 of 126 strings)

Translation: Habitica/Communityguidelines
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (230 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/ro/

Translated using Weblate (Romanian)

Currently translated at 11.6% (9 of 77 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ro/

Translated using Weblate (Dutch)

Currently translated at 97.8% (137 of 140 strings)

Translation: Habitica/Quests
Translate-URL: https://translate.habitica.com/projects/habitica/quests/nl/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (694 of 694 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hant/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (694 of 694 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (694 of 694 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/en_GB/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (358 of 358 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/zh_Hant/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (358 of 358 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/zh_Hans/

Translated using Weblate (Dutch)

Currently translated at 100.0% (358 of 358 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/nl/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (230 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 98.8% (686 of 694 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/pt_BR/

Translated using Weblate (English (United Kingdom))

Currently translated at 99.4% (690 of 694 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/en_GB/

Translated using Weblate (German)

Currently translated at 99.1% (688 of 694 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/de/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (358 of 358 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/pt_BR/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (358 of 358 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/en_GB/

Translated using Weblate (German)

Currently translated at 100.0% (358 of 358 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/de/

Translated using Weblate (German)

Currently translated at 100.0% (522 of 522 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/de/
2020-04-09 13:32:17 +02:00
Sabe Jones 0ac0723be5 4.140.2 2020-04-09 06:28:11 -05:00
Sabe Jones 0f2d2ddad6 Merge branch 'develop' into release 2020-04-09 06:28:06 -05:00
Matteo Pagliazzi e19837f58e 4.140.1 2020-04-08 23:31:26 +02:00
Matteo Pagliazzi 0ea1ce9758 fix(logs): do not log mongoose object with id and no _id to avoid crashes, see https://github.com/davidmarkclements/fast-safe-stringify/issues/43 2020-04-08 23:31:17 +02:00
Phillip Thelen 9d16ab7dba Sign in with Apple (#11793)
* add date check

* achievements modal polishing

* refresh private-messages page when you are already on it

* add countbadge knob to change the example

* fix lint

* typos

* typos

* typos

* add toggle for achievements categories

* typo

* fix test

* fix edit avatar modal cannot be closed

* WIP(settings): subscriber page improvements

* WIP(subscriptions): more design build-out

* fix(css): disabled button styles

* fix(css): better Amazon targeting

* fix hide tooltip + align header correctly

* disable perfect scroll

* load messages on refresh event

* fix header label + conversation actions not breaking layout on hover

* WIP(g1g1): notif

* WIP(g1g1): notif cont'd

* fix(test): snowball change

* fix(event): feature NYE card

* chore(sprites): compile

* fix(bgs): include TT required field

* add gifting banner to the max height calculation

* chore(event): enable winter customizations

* WIP(gifting): partial modal implementation

* feat(gifting): select giftee modal

* fix(gifting): notification order, modal dismiss

* Begin implementing sign in with apple

# Conflicts:
#	package-lock.json
#	website/common/script/constants.js
#	website/server/libs/auth/social.js
#	website/server/models/user/schema.js

* Add apple sign in button to website

* fix lint errors

* fix config json

* fix(modals): correct some repops

* fix(gifting): style updates

* fix(buy): modal style changes

* fix(modals): also clean out "prev"

* Attempt workaround for sign in with apple on android

* temporarily log everything as error

* refactor(modals): hide in dismiss event

* fix temporary test failure

* changes to sign in with apple

* fix: first batch of layout issues for private messages + auto sizing textarea

* fix(modals): new dismiss logic

* fix(modals): new dismiss no go??

* Only use email scope

* print debugging

* .

* ..

* ...

* username second line - open profile on face-avatar/conversation name - fix textarea height

* temporarily disable apple auth and just return data for debugging

* Hopefully this works

* .....

* WIP(subscription): unsubscribed state

* .

* ..

* MAYBE THIS ACTUALLY WORKS???

* Implement apple sign in

* fix some urls

* fix urls

* fix redirect and auth

* attempt to also request name

* fix lint error

* WIP(subscription): partial subscribed

* chore(sprites): compile

* Change approach so that it actually works

* fix config error

* fix lint errors

* Fix

* fix lint error

* lint error

* WIP(subscription): finish subscribed

* refresh on sync

* new "you dont have any messages" style + changed min textarea height

* new conversationItem style / layout

* reset message unread on reload

* chore(npm): update package-locks

* fix styles / textarea height

* feat(subscription): revised sub page RC

* list optOut / chatRevoked informations for each conversation + show why its disabled

* Improve apple redirect view

* Fix apple icon on group task registration page

* WIP(adventure): prereqs

* Block / Unblock - correct disabled states - $gray-200 instead of 300/400

* canReceive not checking chatRevoked

* fix: faceAvatar / userLink open the selected conversation user

* check if the target user is blocking the logged-in user

* fix(subs): style tweaks

* fix(profiles): short circuit contributor
Attempted fix for #11830

* chore(sprites): compile

* fix(content): missing potion data

* fix(content): missing string

* WIP(drops): new modal

* fix(subs): moar style tweaks

* check if blocks is undefined

* max-height instead of height

* fix "no messages" state + canReceive on a new conversation

* WIP(adventure): analytics fixes etc

* Improve apple signin handling

* fixed conversations width (280px on max 768 width page)

* feat(adventure): random egg+potion on 2nd task

* fix(lint): noworkies

* fix(modal): correctly construct classes

* fix(tests): expectations and escape

* Fix typo

* use base url from env variables

* fix lint

* call autosize after message is sent

* fix urls

* always verify token

* throw error when social auth could not retrieve id

* Store emails correctly for apple auth

* Retrieve name when authenticating through apple

* Fix lint errors

* fix all lint errors

* fix(content): missing strings

* Revert "always verify token"

This reverts commit 8ac40c76bf.

# Conflicts:
#	website/server/libs/auth/social.js

* Correctly load name

* remove extra changes

* remove extra logger call

* reset package and package-lock

* add back missing packages

* use name from apple

* add support for multiple apple public keys

* add some unit and integration tests

* add apple auth integration test

* tweak social signup buttons

* pixel pushing

Co-authored-by: Matteo Pagliazzi <matteopagliazzi@gmail.com>
Co-authored-by: Sabe Jones <sabrecat@gmail.com>
Co-authored-by: negue <eugen.bolz@gmail.com>
Co-authored-by: Phillip Thelen <phillip@habitica.com>
2020-04-08 18:44:30 +02:00
Anoop Ravella 776e9834f3 removed loadingScreenTips.json 2020-04-08 11:18:18 -04:00
Melior 1d98929453 Merge branch 'origin/develop' into Weblate.
Merge branch 'origin/develop' into Weblate.

Translated using Weblate (Dutch)

Currently translated at 100.0% (248 of 248 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/nl/

Translated using Weblate (Dutch)

Currently translated at 100.0% (522 of 522 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/nl/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (2091 of 2091 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hant/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2091 of 2091 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2091 of 2091 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2091 of 2091 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/

Translated using Weblate (French)

Currently translated at 100.0% (2091 of 2091 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (2091 of 2091 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/en_GB/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (522 of 522 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hant/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (522 of 522 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hans/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (522 of 522 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt_BR/

Translated using Weblate (French)

Currently translated at 100.0% (522 of 522 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (522 of 522 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/en_GB/
2020-04-08 00:18:20 +02:00
Matteo Pagliazzi 80664b6c5f Merge pull request #12016 from inftp/ptsFix
stop 'pts' from overflowing to next line
2020-04-07 22:22:12 +02:00
Matteo Pagliazzi 01123367b1 Merge pull request #12045 from JohnJSal/patch-1
Removed an unnecessary word in quest completion text
2020-04-07 22:20:10 +02:00
Sabe Jones f6a80d18b6 Merge branch 'release' into develop 2020-04-07 14:08:41 -05:00
Sabe Jones 71af306f02 4.140.0 2020-04-07 14:08:17 -05:00
Sabe Jones 5ccd2ae262 chore(event): seeds and sprites 2020-04-07 14:08:09 -05:00
Sabe Jones a1a1fd939d Merge branch 'sabrecat/dessert-potions' into release 2020-04-07 13:59:36 -05:00
Matteo Pagliazzi 9ac7840940 chore(winston-loggly-bulk): upgrade 2020-04-07 15:18:52 +02:00
Anoop Ravella 100275f460 removed loading tip number logic 2020-04-06 17:20:40 -04:00
Anoop Ravella 489b9c4019 removed loading tip div 2020-04-06 17:05:25 -04:00
Sabe Jones ba61da4acb fix(stable): wacky sorting 2020-04-06 15:26:43 -05:00
Sabe Jones 903851f1fd fix(content): missing premium potion notes 2020-04-06 14:40:09 -05:00
Sabe Jones 371a1542e7 fix(content): feature items 2020-04-06 13:08:29 -05:00
Sabe Jones 0c640f07d1 fix(waffle): missing scroll 2020-04-06 12:19:40 -05:00
Melior cbc6e7aa0c Merge branch 'origin/develop' into Weblate. 2020-04-06 17:48:06 +02:00
Sabe Jones b6eab67e6a Merge branch 'release' into develop 2020-04-06 10:42:45 -05:00
Sabe Jones 99afefe953 4.139.0 2020-04-06 10:41:54 -05:00
Sabe Jones 9fea01b1f4 Merge branch 'sabrecat/armoire-202004' into release 2020-04-06 10:41:40 -05:00
Sabe Jones 978b78e57a feat(migration): script for adding all gear to a user 2020-04-06 14:29:29 +00:00
Melior f920a441a5 Translated using Weblate (Romanian)
Currently translated at 98.6% (227 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (36 of 36 strings)

Translation: Habitica/Loadingscreentips
Translate-URL: https://translate.habitica.com/projects/habitica/loadingscreentips/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (211 of 211 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/ro/

Translated using Weblate (Dutch)

Currently translated at 99.5% (247 of 248 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/nl/

Translated using Weblate (Romanian)

Currently translated at 100.0% (57 of 57 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/ro/

Translated using Weblate (Dutch)

Currently translated at 100.0% (28 of 28 strings)

Translation: Habitica/Rebirth
Translate-URL: https://translate.habitica.com/projects/habitica/rebirth/nl/

Translated using Weblate (Dutch)

Currently translated at 100.0% (143 of 143 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/nl/

Translated using Weblate (Dutch)

Currently translated at 100.0% (8 of 8 strings)

Translation: Habitica/Overview
Translate-URL: https://translate.habitica.com/projects/habitica/overview/nl/

Translated using Weblate (Romanian)

Currently translated at 100.0% (12 of 12 strings)

Translation: Habitica/Merch
Translate-URL: https://translate.habitica.com/projects/habitica/merch/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (27 of 27 strings)

Translation: Habitica/Loginincentives
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/ro/

Translated using Weblate (Romanian)

Currently translated at 98.7% (324 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/ro/

Translated using Weblate (Romanian)

Currently translated at 100.0% (15 of 15 strings)

Translation: Habitica/Death
Translate-URL: https://translate.habitica.com/projects/habitica/death/ro/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (485 of 485 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/zh_Hans/

Translated using Weblate (Russian)

Currently translated at 99.3% (142 of 143 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/ru/

Translated using Weblate (Russian)

Currently translated at 96.1% (173 of 180 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/ru/

Translated using Weblate (Russian)

Currently translated at 97.9% (2042 of 2085 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ru/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2085 of 2085 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/

Translated using Weblate (Russian)

Currently translated at 98.6% (508 of 515 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ru/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2085 of 2085 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (685 of 685 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (143 of 143 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/pt_BR/
2020-04-06 13:53:15 +02:00
Matteo Pagliazzi 12a9eec540 build(deps): bump @vue/cli-plugin-eslint in /website/client (#12054)
Bumps [@vue/cli-plugin-eslint](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-eslint) from 4.2.3 to 4.3.0.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.3.0/packages/@vue/cli-plugin-eslint)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-06 11:34:51 +02:00
dependabot-preview[bot] f83d86b7f3 build(deps): bump @vue/cli-plugin-unit-mocha in /website/client (#12058)
Bumps [@vue/cli-plugin-unit-mocha](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-unit-mocha) from 4.2.3 to 4.3.0.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.3.0/packages/@vue/cli-plugin-unit-mocha)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-06 11:34:41 +02:00
dependabot-preview[bot] 0410c97001 build(deps): bump @vue/cli-plugin-eslint in /website/client
Bumps [@vue/cli-plugin-eslint](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-eslint) from 4.2.3 to 4.3.0.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.3.0/packages/@vue/cli-plugin-eslint)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-06 09:33:11 +00:00
dependabot-preview[bot] 4482b734a5 build(deps): bump @vue/cli-plugin-router in /website/client (#12056)
Bumps [@vue/cli-plugin-router](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-router) from 4.2.3 to 4.3.0.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.3.0/packages/@vue/cli-plugin-router)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-06 11:30:38 +02:00
dependabot-preview[bot] 0131cc07bf build(deps): bump @vue/cli-service in /website/client (#12051)
Bumps [@vue/cli-service](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-service) from 4.2.3 to 4.3.0.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.3.0/packages/@vue/cli-service)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-06 11:30:26 +02:00
dependabot-preview[bot] 70a9f66dcd build(deps): bump @vue/cli-plugin-babel in /website/client (#12049)
Bumps [@vue/cli-plugin-babel](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-babel) from 4.2.3 to 4.3.0.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.3.0/packages/@vue/cli-plugin-babel)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-06 11:30:10 +02:00
dependabot-preview[bot] 3057fdbd4a build(deps): bump @storybook/addon-links in /website/client (#12047)
Bumps [@storybook/addon-links](https://github.com/storybookjs/storybook/tree/HEAD/addons/links) from 5.3.17 to 5.3.18.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v5.3.18/addons/links)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-06 11:01:56 +02:00
Matteo Pagliazzi cc48479c66 Merge branch 'release' into develop 2020-04-06 11:01:29 +02:00
Matteo Pagliazzi 8ad644ec3a remove comment and improve logging 2020-04-06 10:57:36 +02:00
Matteo Pagliazzi 6f2bf5659d improve emails errors 2020-04-06 10:56:39 +02:00
dependabot-preview[bot] f4e573f684 build(deps): bump bootstrap-vue from 2.9.0 to 2.10.1 in /website/client (#12050)
Bumps [bootstrap-vue](https://github.com/bootstrap-vue/bootstrap-vue) from 2.9.0 to 2.10.1.
- [Release notes](https://github.com/bootstrap-vue/bootstrap-vue/releases)
- [Changelog](https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/bootstrap-vue/bootstrap-vue/compare/v2.9.0...v2.10.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-06 10:53:56 +02:00
dependabot-preview[bot] a2e59d0920 build(deps): bump @storybook/addon-knobs in /website/client (#12048)
Bumps [@storybook/addon-knobs](https://github.com/storybookjs/storybook/tree/HEAD/addons/knobs) from 5.3.17 to 5.3.18.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v5.3.18/addons/knobs)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-06 10:53:48 +02:00
dependabot-preview[bot] 39fe86c688 build(deps): bump @storybook/addon-notes in /website/client (#12046)
Bumps [@storybook/addon-notes](https://github.com/storybookjs/storybook/tree/HEAD/addons/notes) from 5.3.17 to 5.3.18.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/v5.3.18/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v5.3.18/addons/notes)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-06 10:53:38 +02:00
dependabot-preview[bot] 78ceb427a3 build(deps): bump @storybook/addon-actions in /website/client (#12052)
Bumps [@storybook/addon-actions](https://github.com/storybookjs/storybook/tree/HEAD/addons/actions) from 5.3.17 to 5.3.18.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v5.3.18/addons/actions)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-06 10:50:15 +02:00
dependabot-preview[bot] 7c17a32bbb build(deps): bump @storybook/vue in /website/client (#12057)
Bumps [@storybook/vue](https://github.com/storybookjs/storybook/tree/HEAD/app/vue) from 5.3.17 to 5.3.18.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v5.3.18/app/vue)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-06 10:49:52 +02:00
dependabot-preview[bot] 9a34c16fa2 build(deps): bump aws-sdk from 2.648.0 to 2.653.0 (#12061)
Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.648.0 to 2.653.0.
- [Release notes](https://github.com/aws/aws-sdk-js/releases)
- [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js/compare/v2.648.0...v2.653.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-06 10:48:57 +02:00
dependabot-preview[bot] 38c24763fa build(deps): bump mongoose from 5.9.6 to 5.9.7 (#12062)
Bumps [mongoose](https://github.com/Automattic/mongoose) from 5.9.6 to 5.9.7.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/History.md)
- [Commits](https://github.com/Automattic/mongoose/compare/5.9.6...5.9.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-04-06 10:48:17 +02:00
JohnJSal 776f3d288b Removed an unnecessary word in quest completion text
Changed "Great job catching the that would-be arsonist..." to "Great job catching that would-be arsonist..." in the quest completion text for "Bye, Bye, Butterfry."
2020-04-05 12:09:17 -05:00
Matteo Pagliazzi e4661c3763 Merge branch 'release' into develop 2020-04-04 13:49:59 +02:00
Matteo Pagliazzi 5fcf3fba88 4.138.6 2020-04-04 13:47:14 +02:00
inftp 156d15c540 Merge remote-tracking branch 'upstream/develop' into ptsFix 2020-04-04 16:29:34 +11:00
inftp 7d9b8a5ceb use bootstrap native style rather than custom 2020-04-04 16:28:10 +11:00
Sabe Jones 23b19853b4 fix(image): filename 2020-04-03 20:36:31 -05:00
Sabe Jones c6839c4478 fix(content): stray comma 2020-04-03 19:31:58 -05:00
Sabe Jones 167f4f07b8 feat(content): Confection Pets 2020-04-03 19:25:43 -05:00
Matteo Pagliazzi 95c9dbaa73 Merge branch 'release' into develop 2020-04-04 00:19:17 +02:00
Matteo Pagliazzi c88af182c9 chore(deps): upgrade slack to v4 2020-04-04 00:19:00 +02:00
Matteo Pagliazzi d9f7772453 chore(deps): upgrade slack to v4 2020-04-04 00:03:28 +02:00
Sabe Jones 931d8814b6 chore(sprites): compile 2020-04-03 15:41:49 -05:00
Sabe Jones 25e5183370 feat(content): Armoire/BGs 2020-04 2020-04-03 15:41:35 -05:00
Matteo Pagliazzi 8e559da200 fix(dockerfile): expose EMAILS_COMMUNITY_MANAGER_EMAIL to client 2020-04-03 12:39:08 +02:00
Melior 8efed37241 Merge branch 'origin/develop' into Weblate. 2020-04-02 23:19:42 +02:00
Sabe Jones ed25afb0b1 4.138.5 2020-04-02 16:10:21 -05:00
Sabe Jones a2c91aae70 chore(news): Challenge and Blog Bailey 2020-04-02 16:09:36 -05:00
Sabe Jones 3ac69d5e75 Merge branch 'develop' into release 2020-04-02 15:09:54 -05:00
Sabe Jones 87b26c4cfb chore(event): end Foolishness 2020-04-02 15:09:30 -05:00
Matteo Pagliazzi 28bc843779 Misc Webhooks Fixes (#12038)
* fix(webhooks): don t parse response as json

* upgrade got to version 10

* remove old header

* fix tests

* fix email auth

* add migration

* update email error

* split migration in two
2020-04-02 21:48:47 +02:00
Matteo Pagliazzi e92ff9737a Automatically Logout Banned Users (#12037)
* wip

* logout banned users, fix and refactor language library and middleware

* req.locals -> res.locals

* fix tests

* redirect to login page
2020-04-02 21:46:01 +02:00
Melior 66422d4235 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (248 of 248 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hant/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (143 of 143 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/zh_Hant/

Translated using Weblate (Dutch)

Currently translated at 100.0% (172 of 172 strings)

Translation: Habitica/Npc
Translate-URL: https://translate.habitica.com/projects/habitica/npc/nl/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (2085 of 2085 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hant/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2085 of 2085 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (Dutch)

Currently translated at 98.8% (170 of 172 strings)

Translation: Habitica/Npc
Translate-URL: https://translate.habitica.com/projects/habitica/npc/nl/

Translated using Weblate (Dutch)

Currently translated at 100.0% (4 of 4 strings)

Translation: Habitica/Noscript
Translate-URL: https://translate.habitica.com/projects/habitica/noscript/nl/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (143 of 143 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/zh_Hans/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (143 of 143 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/en_GB/

Translated using Weblate (French)

Currently translated at 100.0% (248 of 248 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/fr/

Translated using Weblate (French)

Currently translated at 100.0% (143 of 143 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/fr/

Translated using Weblate (German)

Currently translated at 100.0% (143 of 143 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/de/

Translated using Weblate (French)

Currently translated at 100.0% (2085 of 2085 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/

Translated using Weblate (German)

Currently translated at 99.4% (2074 of 2085 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/de/
2020-04-02 13:30:18 +02:00
Sabe Jones c3343c9412 fix(news): Challenge link 2020-04-01 10:23:07 -05:00
Melior e9100c7132 Merge branch 'origin/develop' into Weblate. 2020-04-01 14:37:50 +02:00
Sabe Jones 11235685ca fix(avatar): adjust expected padding for always-on pets 2020-04-01 06:51:14 -05:00
Sabe Jones 49d6691f7d fix(avatar): adjust expected padding for always-on pets 2020-04-01 06:51:02 -05:00
Melior db4c4e6493 Merge branch 'origin/develop' into Weblate. 2020-04-01 13:37:37 +02:00
Sabe Jones 56b1f6371f Merge branch 'release' into develop 2020-04-01 06:32:15 -05:00
Sabe Jones 1b5bd8e1ab 4.138.4 2020-04-01 06:31:49 -05:00
Sabe Jones e39eafd3f0 feat(event): April Foolin 2020-04-01 06:31:39 -05:00
Melior 9213181ca2 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (248 of 248 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hans/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (248 of 248 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/en_GB/

Translated using Weblate (German)

Currently translated at 100.0% (248 of 248 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/de/

Translated using Weblate (German)

Currently translated at 100.0% (180 of 180 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/de/

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.9% (2083 of 2085 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (2085 of 2085 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/en_GB/

Translated using Weblate (German)

Currently translated at 100.0% (357 of 357 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/de/

Translated using Weblate (German)

Currently translated at 100.0% (77 of 77 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/de/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (248 of 248 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2085 of 2085 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/
2020-04-01 00:41:29 +02:00
Calvin 3e50469ed5 Switched to Click to Hatch (#11989) 2020-03-31 17:20:51 +02:00
Matheus Bernardes 7e9d3062f3 fix(achievements modal): fixes hide achievements button formatting (#12013) 2020-03-31 16:11:37 +02:00
Melior 6376e57614 Merge branch 'origin/develop' into Weblate. 2020-03-30 23:19:42 +02:00
Sabe Jones 84ad270436 Merge branch 'release' into develop 2020-03-30 16:14:17 -05:00
Sabe Jones 92cf506bad 4.138.3 2020-03-30 16:12:20 -05:00
Sabe Jones 5f97cb31b8 chore(sprites): compile 2020-03-30 16:12:11 -05:00
Sabe Jones 6d26fbc5f2 feat(content): April subscriber items 2020-03-30 16:12:03 -05:00
Sabe Jones bb9912de89 fix(analytics): problems 2020-03-30 15:38:41 -05:00
Sabe Jones 7a51b7593f fix(analytics): problems (#12032) 2020-03-30 15:37:01 -05:00
Melior 1bfc55ece1 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (2081 of 2081 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (Latin)

Currently translated at 100.0% (126 of 126 strings)

Translation: Habitica/Communityguidelines
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/la/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (247 of 247 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (172 of 172 strings)

Translation: Habitica/Npc
Translate-URL: https://translate.habitica.com/projects/habitica/npc/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (485 of 485 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (298 of 298 strings)

Translation: Habitica/Generic
Translate-URL: https://translate.habitica.com/projects/habitica/generic/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (126 of 126 strings)

Translation: Habitica/Communityguidelines
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/zh_Hans/

Translated using Weblate (Dutch)

Currently translated at 100.0% (180 of 180 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/nl/

Translated using Weblate (Dutch)

Currently translated at 90.0% (1873 of 2081 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (Dutch)

Currently translated at 100.0% (77 of 77 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/nl/

Translated using Weblate (Latin)

Currently translated at 96.5% (475 of 492 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/la/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (180 of 180 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (685 of 685 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/
2020-03-30 19:33:38 +02:00
Matteo Pagliazzi e21f64edaf fix(exports): disable non-working code and throw errors earlier when using the xml export (#12031) 2020-03-30 19:04:55 +02:00
dependabot-preview[bot] a08b419411 build(deps): bump webpack from 4.42.0 to 4.42.1 in /website/client (#12029)
Bumps [webpack](https://github.com/webpack/webpack) from 4.42.0 to 4.42.1.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v4.42.0...v4.42.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-30 10:29:18 +02:00
dependabot-preview[bot] 4a752c3347 build(deps): bump helmet from 3.21.3 to 3.22.0 (#12023)
Bumps [helmet](https://github.com/helmetjs/helmet) from 3.21.3 to 3.22.0.
- [Release notes](https://github.com/helmetjs/helmet/releases)
- [Changelog](https://github.com/helmetjs/helmet/blob/master/CHANGELOG.md)
- [Commits](https://github.com/helmetjs/helmet/compare/v3.21.3...v3.22.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-30 10:28:10 +02:00
dependabot-preview[bot] 8609aae1b4 build(deps): bump aws-sdk from 2.643.0 to 2.648.0 (#12024)
Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.643.0 to 2.648.0.
- [Release notes](https://github.com/aws/aws-sdk-js/releases)
- [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js/compare/v2.643.0...v2.648.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-30 10:27:59 +02:00
dependabot-preview[bot] d35fd9d90d build(deps): bump bootstrap-vue from 2.8.0 to 2.9.0 in /website/client (#12027)
Bumps [bootstrap-vue](https://github.com/bootstrap-vue/bootstrap-vue) from 2.8.0 to 2.9.0.
- [Release notes](https://github.com/bootstrap-vue/bootstrap-vue/releases)
- [Changelog](https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/bootstrap-vue/bootstrap-vue/compare/v2.8.0...v2.9.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-30 10:27:23 +02:00
dependabot-preview[bot] 11103813f5 build(deps): bump mongoose from 5.9.5 to 5.9.6 (#12028)
Bumps [mongoose](https://github.com/Automattic/mongoose) from 5.9.5 to 5.9.6.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/History.md)
- [Commits](https://github.com/Automattic/mongoose/compare/5.9.5...5.9.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-30 10:26:52 +02:00
Matteo Pagliazzi 1a75c6a696 fix(gulp): do not use common code in imports when it has not been transpiled yet 2020-03-29 16:37:57 +02:00
Matteo Pagliazzi 6bef105cf6 fix(gulp): tasks order 2020-03-29 16:26:58 +02:00
Matteo Pagliazzi 3fffe7aa5c Content API Cache improvements (#12020)
* content api improvements

* add content cache to build step

* add tests
2020-03-29 16:15:23 +02:00
Matteo Pagliazzi 9ab9b0f553 IP Blocking (#12015)
* start implementing an ip blocker

* fix comments and add to list of middlewares

* fix code, comment code and improve response

* wip tests

* fix order

* fixes and tests
2020-03-28 15:44:54 +01:00
Melior a00add46a7 Merge branch 'origin/develop' into Weblate. 2020-03-26 21:18:04 +01:00
Melior b9d8da44de Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (357 of 357 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/pt_BR/

Translated using Weblate (Latin)

Currently translated at 97.4% (75 of 77 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/la/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (492 of 492 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (328 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (77 of 77 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pt_BR/

Translated using Weblate (Dutch)

Currently translated at 89.9% (1871 of 2081 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2081 of 2081 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (172 of 172 strings)

Translation: Habitica/Npc
Translate-URL: https://translate.habitica.com/projects/habitica/npc/pt_BR/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (685 of 685 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (77 of 77 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pt_BR/

Translated using Weblate (Dutch)

Currently translated at 89.4% (1862 of 2081 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (77 of 77 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/en_GB/

Merge branch 'origin/develop' into Weblate.

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (230 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/zh_Hans/

Translated using Weblate (Dutch)

Currently translated at 99.5% (246 of 247 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/nl/

Translated using Weblate (Dutch)

Currently translated at 90.6% (224 of 247 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/nl/

Translated using Weblate (Dutch)

Currently translated at 94.1% (162 of 172 strings)

Translation: Habitica/Npc
Translate-URL: https://translate.habitica.com/projects/habitica/npc/nl/

Translated using Weblate (Dutch)

Currently translated at 100.0% (6 of 6 strings)

Translation: Habitica/Inventory
Translate-URL: https://translate.habitica.com/projects/habitica/inventory/nl/

Translated using Weblate (Dutch)

Currently translated at 89.0% (1853 of 2081 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (Japanese)

Currently translated at 100.0% (134 of 134 strings)

Translation: Habitica/Challenge
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/ja/

Translated using Weblate (Swedish)

Currently translated at 99.4% (512 of 515 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/sv/

Translated using Weblate (Swedish)

Currently translated at 99.2% (511 of 515 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/sv/

Translated using Weblate (Swedish)

Currently translated at 88.3% (68 of 77 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/sv/

Translated using Weblate (French)

Currently translated at 100.0% (180 of 180 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/fr/

Translated using Weblate (French)

Currently translated at 100.0% (2081 of 2081 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/

Translated using Weblate (French)

Currently translated at 100.0% (77 of 77 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/fr/

Translated using Weblate (French)

Currently translated at 100.0% (357 of 357 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/fr/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (180 of 180 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/zh_Hant/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (2081 of 2081 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hant/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2081 of 2081 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.7% (2076 of 2081 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.7% (2075 of 2081 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (Latin)

Currently translated at 30.7% (44 of 143 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/la/

Translated using Weblate (Latin)

Currently translated at 87.1% (449 of 515 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/la/

Translated using Weblate (Latin)

Currently translated at 98.7% (76 of 77 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/la/

Translated using Weblate (French)

Currently translated at 99.4% (179 of 180 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/fr/

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.6% (2053 of 2081 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (Chinese (Traditional))

Currently translated at 82.7% (149 of 180 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/zh_Hant/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (27 of 27 strings)

Translation: Habitica/Loginincentives
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/pt_BR/

Translated using Weblate (Chinese (Traditional))

Currently translated at 98.6% (2053 of 2081 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hant/

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.6% (2053 of 2081 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hant/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (230 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/zh_Hant/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (36 of 36 strings)

Translation: Habitica/Loadingscreentips
Translate-URL: https://translate.habitica.com/projects/habitica/loadingscreentips/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (211 of 211 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/pt_BR/

Translated using Weblate (Dutch)

Currently translated at 98.6% (141 of 143 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/nl/

Translated using Weblate (Chinese (Traditional))

Currently translated at 82.7% (149 of 180 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/zh_Hant/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (180 of 180 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/zh_Hans/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (180 of 180 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/pt_BR/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (180 of 180 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/en_GB/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2081 of 2081 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/

Translated using Weblate (Dutch)

Currently translated at 88.7% (1847 of 2081 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (2081 of 2081 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/en_GB/

Translated using Weblate (English (Pirate))

Currently translated at 87.2% (1816 of 2081 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/en@pirate/

Translated using Weblate (Dutch)

Currently translated at 95.7% (656 of 685 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/nl/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (357 of 357 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/zh_Hant/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (357 of 357 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/zh_Hans/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (357 of 357 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/pt_BR/

Translated using Weblate (Dutch)

Currently translated at 100.0% (357 of 357 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/nl/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (357 of 357 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/en_GB/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (230 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/pt_BR/

Translated using Weblate (Dutch)

Currently translated at 100.0% (77 of 77 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/nl/

Translated using Weblate (English (Pirate))

Currently translated at 100.0% (77 of 77 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/en@pirate/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (211 of 211 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/pt_BR/

Translated using Weblate (Portuguese)

Currently translated at 92.8% (196 of 211 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/pt/

Translated using Weblate (Dutch)

Currently translated at 100.0% (211 of 211 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/nl/

Merge branch 'origin/develop' into Weblate.

Translated using Weblate (Japanese)

Currently translated at 100.0% (134 of 134 strings)

Translation: Habitica/Challenge
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/ja/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (211 of 211 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (6 of 6 strings)

Translation: Habitica/Inventory
Translate-URL: https://translate.habitica.com/projects/habitica/inventory/pt_BR/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (685 of 685 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hant/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (685 of 685 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (685 of 685 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/en_GB/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (77 of 77 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/zh_Hant/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (77 of 77 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/zh_Hans/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (77 of 77 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/en_GB/

Translated using Weblate (English (Pirate))

Currently translated at 96.1% (74 of 77 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/en@pirate/

Translated using Weblate (German)

Currently translated at 97.4% (75 of 77 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/de/

Translated using Weblate (Latin)

Currently translated at 94.3% (199 of 211 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/la/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (211 of 211 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (140 of 140 strings)

Translation: Habitica/Quests
Translate-URL: https://translate.habitica.com/projects/habitica/quests/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (172 of 172 strings)

Translation: Habitica/Npc
Translate-URL: https://translate.habitica.com/projects/habitica/npc/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (6 of 6 strings)

Translation: Habitica/Inventory
Translate-URL: https://translate.habitica.com/projects/habitica/inventory/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (211 of 211 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/pt_BR/

Translated using Weblate (Latin)

Currently translated at 91.2% (157 of 172 strings)

Translation: Habitica/Npc
Translate-URL: https://translate.habitica.com/projects/habitica/npc/la/

Translated using Weblate (Latin)

Currently translated at 98.6% (227 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/la/

Translated using Weblate (Latin)

Currently translated at 100.0% (211 of 211 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/la/

Translated using Weblate (Latin)

Currently translated at 81.7% (202 of 247 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/la/

Translated using Weblate (Latin)

Currently translated at 90.7% (127 of 140 strings)

Translation: Habitica/Quests
Translate-URL: https://translate.habitica.com/projects/habitica/quests/la/

Translated using Weblate (Latin)

Currently translated at 94.0% (63 of 67 strings)

Translation: Habitica/Messages
Translate-URL: https://translate.habitica.com/projects/habitica/messages/la/

Translated using Weblate (Latin)

Currently translated at 86.8% (152 of 175 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/la/

Translated using Weblate (Latin)

Currently translated at 96.5% (475 of 492 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/la/

Translated using Weblate (Latin)

Currently translated at 98.9% (295 of 298 strings)

Translation: Habitica/Generic
Translate-URL: https://translate.habitica.com/projects/habitica/generic/la/

Translated using Weblate (Latin)

Currently translated at 84.9% (1745 of 2053 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/la/

Translated using Weblate (Latin)

Currently translated at 100.0% (70 of 70 strings)

Translation: Habitica/Contrib
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/la/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (172 of 172 strings)

Translation: Habitica/Npc
Translate-URL: https://translate.habitica.com/projects/habitica/npc/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (77 of 77 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (211 of 211 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/pt_BR/

Merge branch 'origin/develop' into Weblate.

Translated using Weblate (Japanese)

Currently translated at 100.0% (492 of 492 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ja/

Translated using Weblate (German)

Currently translated at 100.0% (685 of 685 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/de/

Translated using Weblate (Japanese)

Currently translated at 100.0% (492 of 492 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ja/

Translated using Weblate (Dutch)

Currently translated at 89.5% (1839 of 2053 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (Swedish)

Currently translated at 94.6% (53 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/sv/

Translated using Weblate (Dutch)

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/nl/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (685 of 685 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/pt_BR/

Translated using Weblate (French)

Currently translated at 100.0% (685 of 685 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (Czech)

Currently translated at 86.4% (64 of 74 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/cs/

Merge branch 'origin/develop' into Weblate.

Translated using Weblate (Latin)

Currently translated at 87.1% (449 of 515 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/la/

Translated using Weblate (French)

Currently translated at 100.0% (211 of 211 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/fr/

Translated using Weblate (Vietnamese)

Currently translated at 48.6% (36 of 74 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/vi/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (143 of 143 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/pt_BR/

Translated using Weblate (Japanese)

Currently translated at 99.3% (142 of 143 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/ja/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (8 of 8 strings)

Translation: Habitica/Overview
Translate-URL: https://translate.habitica.com/projects/habitica/overview/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (492 of 492 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (6 of 6 strings)

Translation: Habitica/Inventory
Translate-URL: https://translate.habitica.com/projects/habitica/inventory/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2053 of 2053 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/

Translated using Weblate (Dutch)

Currently translated at 98.2% (55 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/nl/

Translated using Weblate (Japanese)

Currently translated at 91.8% (68 of 74 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ja/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (211 of 211 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/pt_BR/

Translated using Weblate (Vietnamese)

Currently translated at 25.6% (19 of 74 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/vi/

Translated using Weblate (Vietnamese)

Currently translated at 87.3% (311 of 356 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/vi/

Translated using Weblate (Japanese)

Currently translated at 100.0% (492 of 492 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ja/

Translated using Weblate (Japanese)

Currently translated at 100.0% (6 of 6 strings)

Translation: Habitica/Inventory
Translate-URL: https://translate.habitica.com/projects/habitica/inventory/ja/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (328 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/zh_Hans/

Translated using Weblate (Dutch)

Currently translated at 96.4% (54 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/nl/

Translated using Weblate (Japanese)

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ja/

Translated using Weblate (Japanese)

Currently translated at 100.0% (356 of 356 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/ja/

Translated using Weblate (Swedish)

Currently translated at 89.1% (66 of 74 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/sv/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (211 of 211 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/zh_Hant/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (211 of 211 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/zh_Hans/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (211 of 211 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/en_GB/

Translated using Weblate (German)

Currently translated at 100.0% (211 of 211 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/de/
2020-03-26 21:17:54 +01:00
Sabe Jones 947e8a1836 4.138.2 2020-03-26 15:15:42 -05:00
Sabe Jones 7bdc974704 Merge branch 'develop' into release 2020-03-26 15:15:38 -05:00
Sabe Jones fe8780d49c chore(news): Bailey 2020-03-26 15:15:25 -05:00
Matteo Pagliazzi 2fc4d0f00c fix(logger): only two arguments to logger when logging an unhandled promise rejection 2020-03-26 17:10:19 +01:00
inftp eb4e382ecf stop 'pts' from overflowing to next line 2020-03-26 14:52:25 +11:00
Matteo Pagliazzi 4300c7b1bf Merge branch 'develop' of github.com:HabitRPG/habitica into develop 2020-03-24 20:31:27 +01:00
Matteo Pagliazzi 2cd0ed5973 fix(logger): improve logging and make sure no data is lost 2020-03-24 20:29:31 +01:00
Sabe Jones 6e8bdf4cdf Merge branch 'release' into develop 2020-03-24 13:14:15 -05:00
Sabe Jones 0bac1102cc 4.138.1 2020-03-24 13:13:55 -05:00
Sabe Jones 3e96e54ad8 feat(event): eggy eggy 2020-03-24 13:13:50 -05:00
Matteo Pagliazzi 3458d89c1d fix(webhook tests): do not rely on toLocaleString when checking for two dates to be close 2020-03-24 12:28:15 +01:00
Denys Dorokhov 25e72ad907 Reward with negative cost can no longer be created, fixes #11855 (#11870)
* Minor refactoring in scoreTask.js

* Reward value validation added (should be >= 0)
2020-03-24 12:10:10 +01:00
Bence László 5cf6a67a36 (website/client/src/components/settings/site.vue): Fix refresh the de-register social media buttons. (#11992) 2020-03-23 17:49:00 +01:00
Matteo Pagliazzi 9dcce382a3 fix(webhook tests): more reliable date test 2020-03-23 17:17:27 +01:00
chan_gami f6484c872a Fixes Japanese conversion bugs on Safari and Chrome (#11917)
decided to fix using flags since KeyboardEvent.isComposing behaves differently depending on the browser
2020-03-23 16:35:17 +01:00
Alys 249ba77c01 edit string to say Pet Food, not food (#11994)
Also capitalise terms that are usually capitalised these days.
2020-03-23 16:32:37 +01:00
dependabot-preview[bot] 7ff590cd88 build(deps): bump mongoose from 5.9.3 to 5.9.5 (#12001)
Bumps [mongoose](https://github.com/Automattic/mongoose) from 5.9.3 to 5.9.5.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/History.md)
- [Commits](https://github.com/Automattic/mongoose/compare/5.9.3...5.9.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-23 10:58:24 +01:00
dependabot-preview[bot] f297fef89e build(deps): bump @babel/preset-env from 7.8.7 to 7.9.0 (#12007)
Bumps [@babel/preset-env](https://github.com/babel/babel) from 7.8.7 to 7.9.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.8.7...v7.9.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-23 10:49:47 +01:00
dependabot-preview[bot] b037cb0722 build(deps): bump @babel/register from 7.8.6 to 7.9.0 (#12009)
Bumps [@babel/register](https://github.com/babel/babel) from 7.8.6 to 7.9.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.8.6...v7.9.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-23 10:36:18 +01:00
dependabot-preview[bot] b8c58a7e4f build(deps): bump morgan from 1.9.1 to 1.10.0 (#12000)
Bumps [morgan](https://github.com/expressjs/morgan) from 1.9.1 to 1.10.0.
- [Release notes](https://github.com/expressjs/morgan/releases)
- [Changelog](https://github.com/expressjs/morgan/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/morgan/compare/1.9.1...1.10.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-23 10:35:30 +01:00
dependabot-preview[bot] f973bf1038 build(deps): [security] bump acorn in /website/client (#11996)
Bumps [acorn](https://github.com/acornjs/acorn) from 6.3.0 to 6.4.1. **This update includes a security fix.**
- [Release notes](https://github.com/acornjs/acorn/releases)
- [Commits](https://github.com/acornjs/acorn/compare/6.3.0...6.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-23 10:35:10 +01:00
dependabot-preview[bot] aaea985cf2 build(deps): bump bootstrap-vue from 2.7.0 to 2.8.0 in /website/client (#11997)
Bumps [bootstrap-vue](https://github.com/bootstrap-vue/bootstrap-vue) from 2.7.0 to 2.8.0.
- [Release notes](https://github.com/bootstrap-vue/bootstrap-vue/releases)
- [Changelog](https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/bootstrap-vue/bootstrap-vue/compare/v2.7.0...v2.8.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-23 10:34:57 +01:00
dependabot-preview[bot] 1d0e08419f build(deps): bump @babel/core from 7.8.7 to 7.9.0 (#12003)
Bumps [@babel/core](https://github.com/babel/babel) from 7.8.7 to 7.9.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.8.7...v7.9.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-23 10:34:20 +01:00
dependabot-preview[bot] fd6244eb15 build(deps): bump aws-sdk from 2.639.0 to 2.643.0 (#12004)
Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.639.0 to 2.643.0.
- [Release notes](https://github.com/aws/aws-sdk-js/releases)
- [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js/compare/v2.639.0...v2.643.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-23 10:34:03 +01:00
Matteo Pagliazzi f8aa756d52 Disable Failing Webhooks (#11966)
* todo comment

* add failures field to webhooks and sanitize

* implement logic

* use update instead of save

* specify timeout and maximum number of retries

* add tests
2020-03-20 23:26:21 +01:00
Matteo Pagliazzi ae7df804cb fix(promise): make sure every promise is handled 2020-03-20 20:07:13 +01:00
Sabe Jones de37eb1bb2 Merge branch 'release' into develop 2020-03-19 08:12:00 -05:00
Sabe Jones cf03261bbf 4.138.0 2020-03-19 08:11:37 -05:00
Sabe Jones 3ec95ad821 fix(event): feature something from 2020 2020-03-19 08:11:30 -05:00
Sabe Jones 57d11d5b20 Merge branch 'develop' into release 2020-03-19 08:10:56 -05:00
Matteo Pagliazzi 039e7d40b8 fix(tests): do not rely on emails order when user joins group plan 2020-03-18 23:31:01 +01:00
Matteo Pagliazzi 4389a9b478 Merge branch 'release' into develop 2020-03-18 20:39:14 +01:00
Matteo Pagliazzi 289032047c 4.137.1 2020-03-18 19:39:37 +01:00
Matteo Pagliazzi 6f5515214a update mongoose options 2020-03-18 19:36:10 +01:00
Sabe Jones fd2c4e3265 fix(sprites): CUBBB 2020-03-18 13:35:53 -05:00
Matteo Pagliazzi dd91bada8f Merge branch 'release' into develop 2020-03-18 19:30:11 +01:00
Matteo Pagliazzi d724933640 update mongoose options 2020-03-18 19:20:09 +01:00
Sabe Jones e4b74bc347 fix(content): feature shinies 2020-03-18 11:15:49 -05:00
Sabe Jones c609db09c1 fix(content): feature shinies 2020-03-18 11:15:10 -05:00
Sabe Jones 55feebdf9e Merge branch 'release' into develop 2020-03-17 15:36:35 -05:00
Sabe Jones d8a99647e7 chore(sprites): compile 2020-03-17 15:35:49 -05:00
Sabe Jones 353b4aed05 feat(content): Magic Hatching Potions 2020-03-17 15:35:38 -05:00
Sabe Jones 411f82202b feat(content): Spring Fling 2020 2020-03-17 14:49:22 -05:00
Sabe Jones 5a5a6e4c5d feat(content): Spring Fling 2020 2020-03-17 14:48:49 -05:00
Sabe Jones 914eee015e Merge branch 'release' into develop 2020-03-17 09:12:29 -05:00
tsukimi2 a301f817e9 Fix for party members missing from header after viewing private messages / inbox / PMs (#11912)
* Fix bug in missing party members in app header

* Modified by running lint

* Change code for handling missing party members in app header from within computed hiddenHeader property to watcher function on hiddenHeader

Co-authored-by: osiris <eynsan@yahoo.co.uk>
2020-03-16 22:17:52 +01:00
tsukimi2 519af8f1b6 Fix for search guilds result being inconsistent between "My Guilds" and "Discover Guilds" (#11903)
* Fix bug to allow guild summary and description to match against search term in MyGuilds component

* Add unit test to groupUtilities to test filterGroup function

* Changes made after running npm:run:lint

* Fix bug when filter guild function does not match against guild size correctly when the guild has member count = 100 or 1000

According to habitica wiki Guilds Guide, gold-tier guilds are guilds with 1000 or more members.  However, under the current code of filter guild function, it matches guilds as gold-tier as strictly more than 1000 members, excluding 1000 members.  Similar silver-tier guilds should have 100 to 999 members, but the current code it matches guilds as silver-tier for members between 101 and 999 members.

* Added unit tests to test the newly added code in the groupsUtilities mixin for the current issue

* Add unit testing to test search guild name, summary, and description in myGuilds component

* Add suggestions from lint

* Added searching by guild summary and white space handling in search terms.

For discover guilds component, added the following:
1) handling of searching by guild summary
2) preventing white space in search terms to display all guilds
3) added test cases for testing the search functionality in discove guilds to ensure consistent behaviour between the searching in MyGuilds and public guilds.

* Remove console statements from test file

* Implement suggestions from lint.

Co-authored-by: osiris <eynsan@yahoo.co.uk>
2020-03-16 20:03:48 +01:00
dependabot-preview[bot] a71abea032 build(deps): bump @storybook/addon-knobs in /website/client (#11977)
Bumps [@storybook/addon-knobs](https://github.com/storybookjs/storybook/tree/HEAD/addons/knobs) from 5.3.14 to 5.3.17.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v5.3.17/addons/knobs)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-16 15:26:27 +01:00
dependabot-preview[bot] 3c623b08c4 build(deps): [security] bump acorn from 6.3.0 to 6.4.1 (#11970)
Bumps [acorn](https://github.com/acornjs/acorn) from 6.3.0 to 6.4.1. **This update includes a security fix.**
- [Release notes](https://github.com/acornjs/acorn/releases)
- [Commits](https://github.com/acornjs/acorn/compare/6.3.0...6.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-16 15:24:30 +01:00
dependabot-preview[bot] ddfa3f8a91 build(deps): bump @storybook/vue in /website/client (#11984)
Bumps [@storybook/vue](https://github.com/storybookjs/storybook/tree/HEAD/app/vue) from 5.3.14 to 5.3.17.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v5.3.17/app/vue)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-16 15:22:52 +01:00
dependabot-preview[bot] e2d1de0cf0 build(deps): bump @storybook/addon-links in /website/client (#11975)
Bumps [@storybook/addon-links](https://github.com/storybookjs/storybook/tree/HEAD/addons/links) from 5.3.14 to 5.3.17.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v5.3.17/addons/links)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-16 15:22:36 +01:00
dependabot-preview[bot] 9281de1801 build(deps): bump regenerator-runtime from 0.13.3 to 0.13.5 (#11976)
Bumps [regenerator-runtime](https://github.com/facebook/regenerator) from 0.13.3 to 0.13.5.
- [Release notes](https://github.com/facebook/regenerator/releases)
- [Commits](https://github.com/facebook/regenerator/compare/regenerator-runtime@0.13.3...regenerator-runtime@0.13.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-16 15:20:11 +01:00
dependabot-preview[bot] 4960171565 build(deps): bump sass from 1.26.2 to 1.26.3 in /website/client (#11973)
Bumps [sass](https://github.com/sass/dart-sass) from 1.26.2 to 1.26.3.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.26.2...1.26.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-16 15:19:54 +01:00
dependabot-preview[bot] d063a57faa build(deps): bump aws-sdk from 2.635.0 to 2.639.0 (#11978)
Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.635.0 to 2.639.0.
- [Release notes](https://github.com/aws/aws-sdk-js/releases)
- [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js/compare/v2.635.0...v2.639.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-16 15:19:41 +01:00
dependabot-preview[bot] 0960eaf571 build(deps): bump amplitude-js from 5.9.0 to 5.10.0 in /website/client (#11979)
Bumps [amplitude-js](https://github.com/amplitude/amplitude-javascript) from 5.9.0 to 5.10.0.
- [Release notes](https://github.com/amplitude/amplitude-javascript/releases)
- [Changelog](https://github.com/amplitude/Amplitude-JavaScript/blob/master/CHANGELOG.md)
- [Commits](https://github.com/amplitude/amplitude-javascript/compare/v5.9.0...v5.10.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-16 15:19:33 +01:00
dependabot-preview[bot] fd0ec41c53 build(deps): bump vue2-perfect-scrollbar in /website/client (#11983)
Bumps [vue2-perfect-scrollbar](https://github.com/mercs600/vue2-perfect-scrollbar) from 1.3.0 to 1.4.0.
- [Release notes](https://github.com/mercs600/vue2-perfect-scrollbar/releases)
- [Commits](https://github.com/mercs600/vue2-perfect-scrollbar/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-16 15:18:53 +01:00
dependabot-preview[bot] 1420e1c8d7 build(deps): bump bootstrap-vue from 2.6.1 to 2.7.0 in /website/client (#11985)
Bumps [bootstrap-vue](https://github.com/bootstrap-vue/bootstrap-vue) from 2.6.1 to 2.7.0.
- [Release notes](https://github.com/bootstrap-vue/bootstrap-vue/releases)
- [Changelog](https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/bootstrap-vue/bootstrap-vue/compare/v2.6.1...v2.7.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-16 15:18:40 +01:00
Matteo Pagliazzi c7c854664f build(deps): bump @storybook/addon-notes in /website/client (#11986)
Bumps [@storybook/addon-notes](https://github.com/storybookjs/storybook/tree/HEAD/addons/notes) from 5.3.14 to 5.3.17.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/v5.3.17/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v5.3.17/addons/notes)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-16 15:18:31 +01:00
dependabot-preview[bot] 68e5679340 build(deps): bump @storybook/addon-actions in /website/client (#11987)
Bumps [@storybook/addon-actions](https://github.com/storybookjs/storybook/tree/HEAD/addons/actions) from 5.3.14 to 5.3.17.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v5.3.17/addons/actions)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-16 15:18:25 +01:00
dependabot-preview[bot] 32a9dda2c6 build(deps): bump @storybook/addon-notes in /website/client
Bumps [@storybook/addon-notes](https://github.com/storybookjs/storybook/tree/HEAD/addons/notes) from 5.3.14 to 5.3.17.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/v5.3.17/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v5.3.17/addons/notes)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-16 08:29:26 +00:00
Sabe Jones 8b19c0ad69 Merge branch 'release' into develop 2020-03-14 06:50:23 -05:00
Alys 33e8b64df6 remove excess 'the' from two locales strings 2020-03-14 20:47:50 +10:00
Sabe Jones 427251ed1d fix(test): food expectation, sigh 2020-03-13 11:10:08 -05:00
508 changed files with 38384 additions and 33094 deletions
+1
View File
@@ -37,6 +37,7 @@ yarn.lock
.elasticbeanstalk/*
!.elasticbeanstalk/*.cfg.yml
!.elasticbeanstalk/*.global.yml
/.vscode
# webstorm fake webpack for path intellisense
webpack.webstorm.config
+3
View File
@@ -1,4 +1,6 @@
node_modules/**
content_cache
content_cache/**
website/client/**
test/**
.git/**
@@ -7,3 +9,4 @@ test/**
*.swp
*.swx
website/raw_sprites/**
content_cache/**
+2
View File
@@ -1,6 +1,7 @@
FROM node:12
ENV ADMIN_EMAIL admin@habitica.com
ENV EMAILS_COMMUNITY_MANAGER_EMAIL admin@habitica.com
ENV AMAZON_PAYMENTS_CLIENT_ID amzn1.application-oa2-client.68ed9e6904ef438fbc1bf86bf494056e
ENV AMAZON_PAYMENTS_SELLER_ID AMQ3SB4SG5E91
ENV AMPLITUDE_KEY e8d4c24b3d6ef3ee73eeba715023dd43
@@ -11,6 +12,7 @@ ENV GOOGLE_CLIENT_ID 1035232791481-32vtplgnjnd1aufv3mcu1lthf31795fq.apps.googleu
ENV LOGGLY_CLIENT_TOKEN ab5663bf-241f-4d14-8783-7d80db77089a
ENV NODE_ENV production
ENV STRIPE_PUB_KEY pk_85fQ0yMECHNfHTSsZoxZXlPSwSNfA
ENV APPLE_AUTH_CLIENT_ID 9Q9SMRMCNN.com.habitrpg.ios.Habitica
# Install global packages
RUN npm install -g gulp-cli mocha
+8 -3
View File
@@ -32,7 +32,7 @@
"LOGGLY_SUBDOMAIN": "example-subdomain",
"LOGGLY_TOKEN": "example-token",
"MAINTENANCE_MODE": "false",
"NODE_DB_URI": "mongodb://localhost/habitrpg",
"NODE_DB_URI": "mongodb://localhost:27017/habitrpg",
"MONGODB_POOL_SIZE": "10",
"NODE_ENV": "development",
"PATH": "bin:node_modules/.bin:/usr/local/bin:/usr/bin:/bin",
@@ -70,9 +70,14 @@
"SLACK_URL": "https://hooks.slack.com/services/some-url",
"STRIPE_API_KEY": "aaaabbbbccccddddeeeeffff00001111",
"STRIPE_PUB_KEY": "22223333444455556666777788889999",
"TEST_DB_URI": "mongodb://localhost/habitrpg_test",
"TEST_DB_URI": "mongodb://localhost:27017/habitrpg_test",
"TRANSIFEX_SLACK_CHANNEL": "transifex",
"WEB_CONCURRENCY": 1,
"SKIP_SSL_CHECK_KEY": "key",
"ENABLE_STACKDRIVER_TRACING": "false"
"ENABLE_STACKDRIVER_TRACING": "false",
"APPLE_AUTH_PRIVATE_KEY": "",
"APPLE_TEAM_ID": "",
"APPLE_AUTH_CLIENT_ID": "",
"APPLE_AUTH_KEY_ID": "",
"BLOCKED_IPS": ""
}
+5 -4
View File
@@ -1,19 +1,20 @@
import gulp from 'gulp';
import babel from 'gulp-babel';
gulp.task('build:src', () => gulp.src('website/server/**/*.js')
gulp.task('build:babel:server', () => gulp.src('website/server/**/*.js')
.pipe(babel())
.pipe(gulp.dest('website/transpiled-babel/')));
gulp.task('build:common', () => gulp.src('website/common/script/**/*.js')
gulp.task('build:babel:common', () => gulp.src('website/common/script/**/*.js')
.pipe(babel())
.pipe(gulp.dest('website/common/transpiled-babel/')));
gulp.task('build:server', gulp.series('build:src', 'build:common', done => done()));
gulp.task('build:babel', gulp.parallel('build:babel:server', 'build:babel:common', done => done()));
gulp.task('build:prod', gulp.series(
'build:server',
'build:babel',
'apidoc',
'content:cache',
done => done(),
));
+34
View File
@@ -0,0 +1,34 @@
import gulp from 'gulp';
import fs from 'fs';
// TODO parallelize, use gulp file helpers
gulp.task('content:cache', done => {
// Requiring at runtime because these files access `common`
// code which in production works only if transpiled so after
// gulp build:babel:common has run
const { CONTENT_CACHE_PATH, getLocalizedContentResponse } = require('../website/server/libs/content'); // eslint-disable-line global-require
const { langCodes } = require('../website/server/libs/i18n'); // eslint-disable-line global-require
try {
// create the cache folder (if it doesn't exist)
try {
fs.mkdirSync(CONTENT_CACHE_PATH);
} catch (err) {
if (err.code !== 'EEXIST') throw err;
}
// clone the content for each language and save
// localize it
// save the result
langCodes.forEach(langCode => {
fs.writeFileSync(
`${CONTENT_CACHE_PATH}${langCode}.json`,
getLocalizedContentResponse(langCode),
'utf8',
);
});
done();
} catch (err) {
done(err);
}
});
+9 -1
View File
@@ -13,8 +13,16 @@ const gulp = require('gulp');
if (process.env.NODE_ENV === 'production') { // eslint-disable-line no-process-env
require('./gulp/gulp-apidoc'); // eslint-disable-line global-require
require('./gulp/gulp-content'); // eslint-disable-line global-require
require('./gulp/gulp-build'); // eslint-disable-line global-require
} else {
require('glob').sync('./gulp/gulp-*').forEach(require); // eslint-disable-line global-require
require('./gulp/gulp-apidoc'); // eslint-disable-line global-require
require('./gulp/gulp-content'); // eslint-disable-line global-require
require('./gulp/gulp-build'); // eslint-disable-line global-require
require('./gulp/gulp-console'); // eslint-disable-line global-require
require('./gulp/gulp-sprites'); // eslint-disable-line global-require
require('./gulp/gulp-start'); // eslint-disable-line global-require
require('./gulp/gulp-tests'); // eslint-disable-line global-require
require('./gulp/gulp-transifex-test'); // eslint-disable-line global-require
require('gulp').task('default', gulp.series('test')); // eslint-disable-line global-require
}
@@ -0,0 +1,69 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '20200402_webhooks_add_protocol';
import { model as User } from '../../../website/server/models/user';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count++;
const set = {
migration: MIGRATION_NAME,
};
if (user && user.webhooks && user.webhooks.length > 0) {
user.webhooks.forEach(webhook => {
// Make sure the protocol is set and valid
if (webhook.url.startsWith('ftp')) {
webhook.url = webhook.url.replace('ftp', 'https');
}
if (!webhook.url.startsWith('http://') && !webhook.url.startsWith('https://')) {
// the default in got 9 was https
// see https://github.com/sindresorhus/got/commit/92bc8082137d7d085750359bbd76c801e213d7d2#diff-0730bb7c2e8f9ea2438b52e419dd86c9L111
webhook.url = `https://${webhook.url}`;
}
});
set.webhooks = user.webhooks;
}
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return await User.update({ _id: user._id }, { $set: set }).exec();
}
module.exports = async function processUsers () {
let query = {
migration: { $ne: MIGRATION_NAME },
webhooks: { $exists: true, $not: { $size: 0 } },
};
const fields = {
_id: 1,
webhooks: 1,
};
while (true) { // eslint-disable-line no-constant-condition
const users = await User // eslint-disable-line no-await-in-loop
.find(query)
.limit(250)
.sort({_id: 1})
.select(fields)
.lean()
.exec();
if (users.length === 0) {
console.warn('All appropriate users found and modified.');
console.warn(`\n${count} users processed\n`);
break;
} else {
query._id = {
$gt: users[users.length - 1]._id,
};
}
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
}
};
@@ -0,0 +1,63 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '20200402_webhooks_reenable';
import { model as User } from '../../../website/server/models/user';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count++;
const set = {
migration: MIGRATION_NAME,
};
if (user && user.webhooks && user.webhooks.length > 0) {
user.webhooks.forEach(webhook => {
// Re-enable webhooks disabled because of too many failures
if (webhook.enabled === false && webhook.lastFailureAt === null) {
webhook.enabled = true;
}
});
set.webhooks = user.webhooks;
}
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return await User.update({ _id: user._id }, { $set: set }).exec();
}
module.exports = async function processUsers () {
let query = {
migration: { $ne: MIGRATION_NAME },
webhooks: { $exists: true, $not: { $size: 0 } },
};
const fields = {
_id: 1,
webhooks: 1,
};
while (true) { // eslint-disable-line no-constant-condition
const users = await User // eslint-disable-line no-await-in-loop
.find(query)
.limit(250)
.sort({_id: 1})
.select(fields)
.lean()
.exec();
if (users.length === 0) {
console.warn('All appropriate users found and modified.');
console.warn(`\n${count} users processed\n`);
break;
} else {
query._id = {
$gt: users[users.length - 1]._id,
};
}
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
}
};
+1 -1
View File
@@ -18,7 +18,7 @@ function setUpServer () {
setUpServer();
// Replace this with your migration
const processUsers = () => {}; // require('').default;
const processUsers = require().default;
processUsers()
.then(() => {
@@ -0,0 +1,54 @@
// @migrationName = 'RewardsMigrationFlipNegativeCostsValues';
// @authorName = 'hamboomger';
// @authorUuid = '80b61b73-2278-4947-b713-a10112cfe7f5';
/*
* For each reward with negative cost, make it positive
* by assigning it an absolute value of itself
*/
import { Task } from '../../website/server/models/task';
async function flipNegativeCostsValues () {
const query = {
type: 'reward',
value: { $lt: 0 },
};
const fields = {
_id: 1,
value: 1,
};
// eslint-disable-next-line no-constant-condition
while (true) {
// eslint-disable-next-line no-await-in-loop
const rewards = await Task
.find(query)
.limit(250)
.sort({ _id: 1 })
.select(fields)
.lean()
.exec();
if (rewards.length === 0) {
break;
}
const promises = rewards.map(reward => {
const positiveValue = Math.abs(reward.value);
return Task.update({ _id: reward._id }, { $set: { value: positiveValue } }).exec();
});
// eslint-disable-next-line no-await-in-loop
await Promise.all(promises);
query._id = {
$gt: rewards[rewards.length - 1]._id,
};
}
console.log('All rewards with negative values were updated, migration finished');
}
export default flipNegativeCostsValues;
+64
View File
@@ -0,0 +1,64 @@
/* eslint-disable no-console */
import each from 'lodash/each';
import keys from 'lodash/keys';
import content from '../../website/common/script/content/index';
import { model as User } from '../../website/server/models/user';
const MIGRATION_NAME = 'full-gear';
const progressCount = 1000;
let count = 0;
/*
* Award users every extant pet and mount
*/
async function updateUser (user) {
count += 1;
const set = {};
set.migration = MIGRATION_NAME;
each(keys(content.gear.flat), gearItem => {
set[`items.gear.owned.${gearItem}`] = true;
});
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return User.update({ _id: user._id }, { $set: set }).exec();
}
export default async function processUsers () {
const query = {
migration: { $ne: MIGRATION_NAME },
'auth.local.lowerCaseUsername': 'olson1',
};
const fields = {
_id: 1,
};
while (true) { // eslint-disable-line no-constant-condition
const users = await User // eslint-disable-line no-await-in-loop
.find(query)
.limit(250)
.sort({ _id: 1 })
.select(fields)
.lean()
.exec();
if (users.length === 0) {
console.warn('All appropriate users found and modified.');
console.warn(`\n${count} users processed\n`);
break;
} else {
query._id = {
$gt: users[users.length - 1],
};
}
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
}
}
+4 -1
View File
@@ -33,6 +33,9 @@ async function updateUser (user) {
each(keys(content.specialPets), pet => {
set[`items.pets.${pet}`] = 5;
});
each(keys(content.wackyPets), pet => {
set[`items.pets.${pet}`] = 5;
});
each(keys(content.mounts), mount => {
set[`items.mounts.${mount}`] = true;
});
@@ -54,7 +57,7 @@ async function updateUser (user) {
export default async function processUsers () {
const query = {
migration: { $ne: MIGRATION_NAME },
'auth.local.username': 'olson22',
'auth.local.username': 'SabreTest',
};
const fields = {
+1226 -1160
View File
File diff suppressed because it is too large Load Diff
+15 -13
View File
@@ -1,20 +1,20 @@
{
"name": "habitica",
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
"version": "4.137.0",
"version": "4.140.8",
"main": "./website/server/index.js",
"dependencies": {
"@babel/core": "^7.8.7",
"@babel/preset-env": "^7.8.7",
"@babel/register": "^7.8.6",
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.5",
"@babel/register": "^7.9.0",
"@google-cloud/trace-agent": "^4.2.5",
"@slack/client": "^3.8.1",
"@slack/client": "^4.12.0",
"accepts": "^1.3.5",
"amazon-payments": "^0.2.8",
"amplitude": "^3.5.0",
"apidoc": "^0.17.5",
"apn": "^2.2.0",
"aws-sdk": "^2.635.0",
"apple-auth": "^1.0.5",
"bcrypt": "^3.0.8",
"body-parser": "^1.18.3",
"compression": "^1.7.4",
@@ -30,27 +30,29 @@
"express-basic-auth": "^1.1.5",
"express-validator": "^5.2.0",
"glob": "^7.1.6",
"got": "^9.0.0",
"got": "^10.7.0",
"gulp": "^4.0.0",
"gulp-babel": "^8.0.0",
"gulp-imagemin": "^6.2.0",
"gulp-nodemon": "^2.5.0",
"gulp.spritesmith": "^6.9.0",
"habitica-markdown": "^1.3.2",
"helmet": "^3.21.3",
"helmet": "^3.22.0",
"image-size": "^0.8.3",
"in-app-purchase": "^1.11.3",
"js2xmlparser": "^4.0.1",
"jsonwebtoken": "^8.5.1",
"jwks-rsa": "^1.7.0",
"lodash": "^4.17.15",
"merge-stream": "^2.0.0",
"method-override": "^3.0.0",
"moment": "^2.24.0",
"moment-recur": "^1.0.7",
"mongoose": "^5.9.3",
"morgan": "^1.7.0",
"mongoose": "^5.9.7",
"morgan": "^1.10.0",
"nconf": "^0.10.0",
"node-gcm": "^1.0.2",
"pageres": "^5.1.0",
"on-headers": "^1.0.2",
"passport": "^0.4.1",
"passport-facebook": "^3.0.0",
"passport-google-oauth2": "^0.2.0",
@@ -58,7 +60,7 @@
"paypal-ipn": "3.0.0",
"paypal-rest-sdk": "^1.8.1",
"ps-tree": "^1.0.0",
"regenerator-runtime": "^0.13.3",
"regenerator-runtime": "^0.13.5",
"remove-markdown": "^0.3.0",
"rimraf": "^3.0.2",
"short-uuid": "^3.0.0",
@@ -70,7 +72,7 @@
"validator": "^11.0.0",
"vinyl-buffer": "^1.0.1",
"winston": "^3.2.1",
"winston-loggly-bulk": "^3.0.1",
"winston-loggly-bulk": "^3.1.0",
"xml2js": "^0.4.23"
},
"private": true,
+17
View File
@@ -0,0 +1,17 @@
import * as contentLib from '../../../../website/server/libs/content';
import content from '../../../../website/common/script/content';
describe('contentLib', () => {
describe('CONTENT_CACHE_PATH', () => {
it('exports CONTENT_CACHE_PATH', () => {
expect(contentLib.CONTENT_CACHE_PATH).to.be.a.string;
});
});
describe('getLocalizedContentResponse', () => {
it('clones, not modify, the original content data', () => {
contentLib.getLocalizedContentResponse();
expect(typeof content.backgrounds.backgrounds062014.beach.text).to.equal('function');
});
});
});
+51 -6
View File
@@ -18,6 +18,16 @@ function getUser () {
value: 'email@facebook',
}],
},
google: {
emails: [{
value: 'email@google',
}],
},
apple: {
emails: [{
value: 'email@apple',
}],
},
},
profile: {
name: 'profile name',
@@ -58,6 +68,8 @@ describe('emails', () => {
const user = getUser();
delete user.profile.name;
delete user.auth.local.email;
delete user.auth.google.emails;
delete user.auth.apple.emails;
const data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
@@ -67,12 +79,48 @@ describe('emails', () => {
expect(data).to.have.property('canSend', true);
});
it('returns correct user data [google users]', () => {
const attachEmail = requireAgain(pathToEmailLib);
const { getUserInfo } = attachEmail;
const user = getUser();
delete user.profile.name;
delete user.auth.local.email;
delete user.auth.facebook.emails;
delete user.auth.apple.emails;
const data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
expect(data).to.have.property('name', user.auth.local.username);
expect(data).to.have.property('email', user.auth.google.emails[0].value);
expect(data).to.have.property('_id', user._id);
expect(data).to.have.property('canSend', true);
});
it('returns correct user data [apple users]', () => {
const attachEmail = requireAgain(pathToEmailLib);
const { getUserInfo } = attachEmail;
const user = getUser();
delete user.profile.name;
delete user.auth.local.email;
delete user.auth.google.emails;
delete user.auth.facebook.emails;
const data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
expect(data).to.have.property('name', user.auth.local.username);
expect(data).to.have.property('email', user.auth.apple.emails[0].value);
expect(data).to.have.property('_id', user._id);
expect(data).to.have.property('canSend', true);
});
it('has fallbacks for missing data', () => {
const attachEmail = requireAgain(pathToEmailLib);
const { getUserInfo } = attachEmail;
const user = getUser();
delete user.auth.local.email;
delete user.auth.facebook;
delete user.auth.google;
delete user.auth.apple;
const data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
@@ -121,8 +169,7 @@ describe('emails', () => {
sendTxnEmail(mailingInfo, emailType);
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
json: true,
body: {
json: {
data: {
emailType: sinon.match.same(emailType),
to: sinon.match(value => Array.isArray(value) && value[0].name === mailingInfo.name, 'matches mailing info array'),
@@ -154,8 +201,7 @@ describe('emails', () => {
sendTxnEmail(mailingInfo, emailType);
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
json: true,
body: {
json: {
data: {
emailType: sinon.match.same(emailType),
to: sinon.match(val => val[0]._id === mailingInfo._id),
@@ -177,8 +223,7 @@ describe('emails', () => {
sendTxnEmail(mailingInfo, emailType, variables);
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
json: true,
body: {
json: {
data: {
variables: sinon.match(value => value[0].name === 'BASE_URL', 'matches variables'),
personalVariables: sinon.match(value => value[0].rcpt === mailingInfo.email
+27
View File
@@ -3,6 +3,7 @@ import {
CustomError,
NotAuthorized,
BadRequest,
Forbidden,
InternalServerError,
NotFound,
NotificationNotFound,
@@ -113,6 +114,32 @@ describe('Custom Errors', () => {
});
});
describe('Forbidden', () => {
it('is an instance of CustomError', () => {
const forbiddenError = new Forbidden();
expect(forbiddenError).to.be.an.instanceOf(CustomError);
});
it('it returns an http code of 401', () => {
const forbiddenError = new Forbidden();
expect(forbiddenError.httpCode).to.eql(403);
});
it('returns a default message', () => {
const forbiddenError = new Forbidden();
expect(forbiddenError.message).to.eql('Access forbidden.');
});
it('allows a custom message', () => {
const forbiddenError = new Forbidden('Custom Error Message');
expect(forbiddenError.message).to.eql('Custom Error Message');
});
});
describe('InternalServerError', () => {
it('is an instance of CustomError', () => {
const internalServerError = new InternalServerError();
+111
View File
@@ -0,0 +1,111 @@
import {
getLanguageFromBrowser,
getLanguageFromUser,
} from '../../../../website/server/libs/language';
import {
generateReq,
} from '../../../helpers/api-unit.helper';
describe('language lib', () => {
let req;
beforeEach(() => {
req = generateReq();
});
describe('getLanguageFromUser', () => {
it('uses the user preferred language if avalaible', () => {
const user = {
preferences: {
language: 'it',
},
};
expect(getLanguageFromUser(user, req)).to.equal('it');
});
it('falls back to english if the user preferred language is not avalaible', () => {
const user = {
preferences: {
language: 'bla',
},
};
expect(getLanguageFromUser(user, req)).to.equal('en');
});
});
describe('getLanguageFromBrowser', () => {
it('uses browser specificed language', () => {
req.headers['accept-language'] = 'pt';
expect(getLanguageFromBrowser(req)).to.equal('pt');
});
it('uses first language in series if browser specifies multiple', () => {
req.headers['accept-language'] = 'he, pt, it';
expect(getLanguageFromBrowser(req)).to.equal('he');
});
it('skips invalid lanaguages and uses first language in series if browser specifies multiple', () => {
req.headers['accept-language'] = 'blah, he, pt, it';
expect(getLanguageFromBrowser(req)).to.equal('he');
});
it('uses normal version of language if specialized locale is passed in', () => {
req.headers['accept-language'] = 'fr-CA';
expect(getLanguageFromBrowser(req)).to.equal('fr');
});
it('uses normal version of language if specialized locale is passed in', () => {
req.headers['accept-language'] = 'fr-CA';
expect(getLanguageFromBrowser(req)).to.equal('fr');
});
it('uses es if es is passed in', () => {
req.headers['accept-language'] = 'es';
expect(getLanguageFromBrowser(req)).to.equal('es');
});
it('uses es_419 if applicable es-languages are passed in', () => {
req.headers['accept-language'] = 'es-mx';
expect(getLanguageFromBrowser(req)).to.equal('es_419');
});
it('uses es_419 if multiple es languages are passed in', () => {
req.headers['accept-language'] = 'es-GT, es-MX, es-CR';
expect(getLanguageFromBrowser(req)).to.equal('es_419');
});
it('zh', () => {
req.headers['accept-language'] = 'zh-TW';
expect(getLanguageFromBrowser(req)).to.equal('zh_TW');
});
it('uses english if browser specified language is not compatible', () => {
req.headers['accept-language'] = 'blah';
expect(getLanguageFromBrowser(req)).to.equal('en');
});
it('uses english if browser does not specify', () => {
req.headers['accept-language'] = '';
expect(getLanguageFromBrowser(req)).to.equal('en');
});
it('uses english if browser does not supply an accept-language header', () => {
delete req.headers['accept-language'];
expect(getLanguageFromBrowser(req)).to.equal('en');
});
});
});
+22
View File
@@ -0,0 +1,22 @@
import faq from '../../../../website/common/script/content/faq';
import common from '../../../../website/common';
import { localizeContentData } from '../../../../website/server/libs/content';
const { i18n } = common;
describe('localizeContentData', () => {
it('Should take a an object with localization identifiers and '
+ 'return an object with actual translations in English', () => {
const faqInEnglish = localizeContentData(faq, 'en');
expect(faqInEnglish).to.have.property('stillNeedHelp');
expect(faqInEnglish.stillNeedHelp.ios).to.equal(i18n.t('iosFaqStillNeedHelp', 'en'));
});
it('Should take an object with localization identifiers and '
+ 'return an object with actual translations in German', () => {
const faqInEnglish = localizeContentData(faq, 'de');
expect(faqInEnglish).to.have.property('stillNeedHelp');
expect(faqInEnglish.stillNeedHelp.ios).to.equal(i18n.t('iosFaqStillNeedHelp', 'de'));
});
});
+65 -35
View File
@@ -30,18 +30,52 @@ describe('logger', () => {
describe('info', () => {
it('calls winston\'s info log', () => {
logger.info(1, 2, 3);
logger.info('1', 2);
expect(infoSpy).to.be.calledOnce;
expect(infoSpy).to.be.calledWith(1, 2, 3);
expect(infoSpy).to.be.calledWith('1', { extraData: 2 });
});
it('allows up to two arguments', () => {
expect(() => logger.info('1', 2, 3)).to.throw;
expect(infoSpy).to.not.be.called;
});
it('has default message', () => {
logger.info(1);
expect(infoSpy).to.be.calledOnce;
expect(infoSpy).to.be.calledWith('No message provided for log.', { extraData: 1 });
});
it('wraps non objects', () => {
logger.info('message', [1, 2]);
expect(infoSpy).to.be.calledOnce;
expect(infoSpy).to.be.calledWithMatch('message', { extraData: [1, 2] });
});
it('does not wrap objects', () => {
logger.info('message', { a: 1, b: 2 });
expect(infoSpy).to.be.calledOnce;
expect(infoSpy).to.be.calledWithMatch('message', { a: 1, b: 2 });
});
it('throws if two arguments and no message', () => {
expect(() => logger.info({ a: 1 }, { b: 2 })).to.throw;
expect(infoSpy).to.not.be.called;
});
});
describe('error', () => {
context('non-error object', () => {
it('passes through arguments if the first arg is not an error object', () => {
logger.error(1, 2, 3, 4);
expect(errorSpy).to.be.calledOnce;
expect(errorSpy).to.be.calledWith(1, 2, 3, 4);
it('allows up to two arguments', () => {
expect(() => logger.error('1', 2, 3)).to.throw;
expect(errorSpy).to.not.be.called;
});
it('handled non-error object', () => {
logger.error(1, 2);
expect(errorSpy).to.be.calledOnce;
expect(errorSpy).to.be.calledWithMatch('logger.error expects an Error instance', {
invalidErr: 1,
extraData: 2,
});
});
@@ -50,14 +84,12 @@ describe('logger', () => {
const errInstance = new Error('An error.');
logger.error(errInstance, {
data: 1,
}, 2, 3);
});
expect(errorSpy).to.be.calledOnce;
expect(errorSpy).to.be.calledWith(
errInstance.stack,
{ data: 1, fullError: errInstance },
2,
3,
);
});
@@ -68,56 +100,60 @@ describe('logger', () => {
logger.error(errInstance, {
data: 1,
fullError: anotherError,
}, 2, 3);
});
expect(errorSpy).to.be.calledOnce;
expect(errorSpy).to.be.calledWith(
errInstance.stack,
{ data: 1, fullError: anotherError },
2,
3,
);
});
it('logs the error when errorData is null', () => {
const errInstance = new Error('An error.');
logger.error(errInstance, null, 2, 3);
logger.error(errInstance, null);
expect(errorSpy).to.be.calledOnce;
expect(errorSpy).to.be.calledWith(
expect(errorSpy).to.be.calledWithMatch(
errInstance.stack,
null,
2,
3,
{ },
);
});
it('logs the error when errorData is not an object', () => {
const errInstance = new Error('An error.');
logger.error(errInstance, true, 2, 3);
logger.error(errInstance, true);
expect(errorSpy).to.be.calledOnce;
expect(errorSpy).to.be.calledWith(
expect(errorSpy).to.be.calledWithMatch(
errInstance.stack,
true,
2,
3,
{ extraData: true },
);
});
it('logs the error when errorData is a string', () => {
const errInstance = new Error('An error.');
logger.error(errInstance, 'a string');
expect(errorSpy).to.be.calledOnce;
expect(errorSpy).to.be.calledWithMatch(
errInstance.stack,
{ extraMessage: 'a string' },
);
});
it('logs the error when errorData does not include isHandledError property', () => {
const errInstance = new Error('An error.');
logger.error(errInstance, { httpCode: 400 }, 2, 3);
logger.error(errInstance, { httpCode: 400 });
expect(errorSpy).to.be.calledOnce;
expect(errorSpy).to.be.calledWith(
errInstance.stack,
{ httpCode: 400, fullError: errInstance },
2,
3,
);
});
@@ -127,14 +163,12 @@ describe('logger', () => {
logger.error(errInstance, {
isHandledError: true,
httpCode: 502,
}, 2, 3);
});
expect(errorSpy).to.be.calledOnce;
expect(errorSpy).to.be.calledWith(
errInstance.stack,
{ httpCode: 502, isHandledError: true, fullError: errInstance },
2,
3,
);
});
@@ -144,14 +178,12 @@ describe('logger', () => {
logger.error(errInstance, {
isHandledError: true,
httpCode: 403,
}, 2, 3);
});
expect(warnSpy).to.be.calledOnce;
expect(warnSpy).to.be.calledWith(
errInstance.stack,
{ httpCode: 403, isHandledError: true, fullError: errInstance },
2,
3,
);
});
@@ -160,7 +192,7 @@ describe('logger', () => {
errInstance.customField = 'Some interesting data';
logger.error(errInstance, {}, 2, 3);
logger.error(errInstance, {});
expect(errorSpy).to.be.calledOnce;
expect(errorSpy).to.be.calledWith(
@@ -170,8 +202,6 @@ describe('logger', () => {
customField: 'Some interesting data',
},
},
2,
3,
);
});
});
@@ -11,7 +11,6 @@ import { model as User } from '../../../../../../website/server/models/user';
import { model as Group } from '../../../../../../website/server/models/group';
import {
generateGroup,
sleep,
} from '../../../../../helpers/api-unit.helper';
describe('Purchasing a group plan for group', () => {
@@ -293,7 +292,7 @@ describe('Purchasing a group plan for group', () => {
});
it('sends appropriate emails when subscribed member of group must manually cancel recurring Android subscription', async () => {
const TECH_ASSISTANCE_EMAIL = nconf.get('TECH_ASSISTANCE_EMAIL');
const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL');
plan.customerId = 'random';
plan.paymentMethod = api.constants.GOOGLE_PAYMENT_METHOD;
@@ -308,26 +307,46 @@ describe('Purchasing a group plan for group', () => {
data.groupId = group._id;
await api.createSubscription(data);
await sleep(0.5);
expect(sender.sendTxn).to.have.callCount(4);
expect(sender.sendTxn.args[0][0]._id).to.equal(TECH_ASSISTANCE_EMAIL);
expect(sender.sendTxn.args[0][1]).to.equal('admin-user-subscription-details');
expect(sender.sendTxn.args[1][0]._id).to.equal(recipient._id);
expect(sender.sendTxn.args[1][1]).to.equal('group-member-join');
expect(sender.sendTxn.args[1][2]).to.eql([
const adminUserSubscriptionDetails = sender.sendTxn.args.find(sendTxnArgs => {
const emailType = sendTxnArgs[1];
return emailType === 'admin-user-subscription-details';
});
expect(adminUserSubscriptionDetails).to.exist;
expect(adminUserSubscriptionDetails[0].email).to.equal(TECH_ASSISTANCE_EMAIL);
const groupMemberJoinOne = sender.sendTxn.args.find(sendTxnArgs => {
const emailType = sendTxnArgs[1];
const emailRecipient = sendTxnArgs[0];
return emailType === 'group-member-join' && emailRecipient._id === recipient._id;
});
expect(groupMemberJoinOne).to.exist;
expect(groupMemberJoinOne[0]._id).to.equal(recipient._id);
expect(groupMemberJoinOne[2]).to.eql([
{ name: 'LEADER', content: groupLeaderName },
{ name: 'GROUP_NAME', content: groupName },
{ name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_GOOGLE },
]);
expect(sender.sendTxn.args[2][0]._id).to.equal(group.leader);
expect(sender.sendTxn.args[2][1]).to.equal('group-member-join');
expect(sender.sendTxn.args[3][0]._id).to.equal(group.leader);
expect(sender.sendTxn.args[3][1]).to.equal('group-subscription-begins');
const groupMemberJoinTwo = sender.sendTxn.args.find(sendTxnArgs => {
const emailType = sendTxnArgs[1];
const emailRecipient = sendTxnArgs[0];
return emailType === 'group-member-join' && emailRecipient._id === group.leader;
});
expect(groupMemberJoinTwo).to.exist;
expect(groupMemberJoinTwo[0]._id).to.equal(group.leader);
const groupSubscriptionBegins = sender.sendTxn.args.find(sendTxnArgs => {
const emailType = sendTxnArgs[1];
return emailType === 'group-subscription-begins';
});
expect(groupSubscriptionBegins).to.exist;
expect(groupSubscriptionBegins[0]._id).to.equal(group.leader);
});
it('sends appropriate emails when subscribed member of group must manually cancel recurring iOS subscription', async () => {
const TECH_ASSISTANCE_EMAIL = nconf.get('TECH_ASSISTANCE_EMAIL');
const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL');
plan.customerId = 'random';
plan.paymentMethod = api.constants.IOS_PAYMENT_METHOD;
@@ -342,22 +361,43 @@ describe('Purchasing a group plan for group', () => {
data.groupId = group._id;
await api.createSubscription(data);
await sleep(0.5);
expect(sender.sendTxn).to.have.callCount(4);
expect(sender.sendTxn.args[0][0]._id).to.equal(TECH_ASSISTANCE_EMAIL);
expect(sender.sendTxn.args[0][1]).to.equal('admin-user-subscription-details');
expect(sender.sendTxn.args[1][0]._id).to.equal(recipient._id);
expect(sender.sendTxn.args[1][1]).to.equal('group-member-join');
expect(sender.sendTxn.args[1][2]).to.eql([
const adminUserSubscriptionDetails = sender.sendTxn.args.find(sendTxnArgs => {
const emailType = sendTxnArgs[1];
return emailType === 'admin-user-subscription-details';
});
expect(adminUserSubscriptionDetails).to.exist;
expect(adminUserSubscriptionDetails[0].email).to.equal(TECH_ASSISTANCE_EMAIL);
const groupMemberJoinOne = sender.sendTxn.args.find(sendTxnArgs => {
const emailType = sendTxnArgs[1];
const emailRecipient = sendTxnArgs[0];
return emailType === 'group-member-join' && emailRecipient._id === recipient._id;
});
expect(groupMemberJoinOne).to.exist;
expect(groupMemberJoinOne[0]._id).to.equal(recipient._id);
expect(groupMemberJoinOne[2]).to.eql([
{ name: 'LEADER', content: groupLeaderName },
{ name: 'GROUP_NAME', content: groupName },
{ name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_IOS },
]);
expect(sender.sendTxn.args[2][0]._id).to.equal(group.leader);
expect(sender.sendTxn.args[2][1]).to.equal('group-member-join');
expect(sender.sendTxn.args[3][0]._id).to.equal(group.leader);
expect(sender.sendTxn.args[3][1]).to.equal('group-subscription-begins');
const groupMemberJoinTwo = sender.sendTxn.args.find(sendTxnArgs => {
const emailType = sendTxnArgs[1];
const emailRecipient = sendTxnArgs[0];
return emailType === 'group-member-join' && emailRecipient._id === group.leader;
});
expect(groupMemberJoinTwo).to.exist;
expect(groupMemberJoinTwo[0]._id).to.equal(group.leader);
const groupSubscriptionBegins = sender.sendTxn.args.find(sendTxnArgs => {
const emailType = sendTxnArgs[1];
return emailType === 'group-subscription-begins';
});
expect(groupSubscriptionBegins).to.exist;
expect(groupSubscriptionBegins[0]._id).to.equal(group.leader);
});
it('adds months to members with existing gift subscription', async () => {
+66 -5
View File
@@ -1,13 +1,15 @@
import requireAgain from 'require-again';
import apn from 'apn/mock';
import _ from 'lodash';
import nconf from 'nconf';
import gcmLib from 'node-gcm'; // works with FCM notifications too
import { model as User } from '../../../../website/server/models/user';
import {
sendNotification as sendPushNotification,
MAX_MESSAGE_LENGTH,
} from '../../../../website/server/libs/pushNotifications';
describe('pushNotifications', () => {
let user;
let sendPushNotification;
const pathToPushNotifications = '../../../../website/server/libs/pushNotifications';
let fcmSendSpy;
let apnSendSpy;
@@ -28,8 +30,6 @@ describe('pushNotifications', () => {
on: () => null,
send: apnSendSpy,
});
sendPushNotification = requireAgain(pathToPushNotifications).sendNotification;
});
afterEach(() => {
@@ -86,6 +86,67 @@ describe('pushNotifications', () => {
expect(apnSendSpy).to.not.have.been.called;
});
it('cuts the message to 300 chars', () => {
const longMessage = `12345 12345 12345 12345 12345 12345 12345
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345`;
expect(longMessage.length > MAX_MESSAGE_LENGTH).to.equal(true);
const details = {
identifier,
title,
message: longMessage,
payload: {
message: longMessage,
},
};
sendPushNotification(user, details);
expect(details.message).to.equal(_.truncate(longMessage, { length: MAX_MESSAGE_LENGTH }));
expect(details.payload.message)
.to.equal(_.truncate(longMessage, { length: MAX_MESSAGE_LENGTH }));
expect(details.message.length).to.equal(MAX_MESSAGE_LENGTH);
expect(details.payload.message.length).to.equal(MAX_MESSAGE_LENGTH);
});
it('cuts the message to 300 chars (no payload)', () => {
const longMessage = `12345 12345 12345 12345 12345 12345 12345
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345
12345 12345 12345 12345 12345 12345 12345 12345 12345 12345`;
expect(longMessage.length > MAX_MESSAGE_LENGTH).to.equal(true);
const details = {
identifier,
title,
message: longMessage,
};
sendPushNotification(user, details);
expect(details.message).to.equal(_.truncate(longMessage, { length: MAX_MESSAGE_LENGTH }));
expect(details.message.length).to.equal(MAX_MESSAGE_LENGTH);
});
// TODO disabled because APN relies on a Promise
xit('uses APN for iOS devices', () => {
user.pushDevices.push({
+112 -28
View File
@@ -1,4 +1,5 @@
import got from 'got';
import moment from 'moment';
import {
WebhookSender,
taskScoredWebhook,
@@ -13,8 +14,9 @@ import {
import {
generateUser,
defer,
sleep,
} from '../../../helpers/api-unit.helper';
import logger from '../../../../website/server/libs/logger';
describe('webhooks', () => {
let webhooks; let
@@ -99,8 +101,7 @@ describe('webhooks', () => {
expect(WebhookSender.defaultTransformData).to.be.calledOnce;
expect(got.post).to.be.calledOnce;
expect(got.post).to.be.calledWithMatch('http://custom-url.com', {
json: true,
body,
json: body,
});
});
@@ -120,7 +121,7 @@ describe('webhooks', () => {
expect(sendWebhook.attachDefaultData).to.be.calledOnce;
expect(got.post).to.be.calledOnce;
expect(got.post).to.be.calledWithMatch('http://custom-url.com', {
json: true,
json: body,
});
expect(body).to.eql({
@@ -151,8 +152,7 @@ describe('webhooks', () => {
expect(WebhookSender.defaultTransformData).to.not.be.called;
expect(got.post).to.be.calledOnce;
expect(got.post).to.be.calledWithMatch('http://custom-url.com', {
json: true,
body: {
json: {
foo: 'bar',
baz: 'biz',
},
@@ -269,8 +269,7 @@ describe('webhooks', () => {
expect(got.post).to.be.calledOnce;
expect(got.post).to.be.calledWithMatch('http://custom-url.com', {
body,
json: true,
json: body,
});
});
@@ -290,8 +289,7 @@ describe('webhooks', () => {
expect(got.post).to.be.calledOnce;
expect(got.post).to.be.calledWithMatch('http://custom-url.com', {
body,
json: true,
json: body,
});
});
@@ -314,12 +312,105 @@ describe('webhooks', () => {
expect(got.post).to.be.calledTwice;
expect(got.post).to.be.calledWithMatch('http://custom-url.com', {
body,
json: true,
json: body,
});
expect(got.post).to.be.calledWithMatch('http://other-url.com', {
body,
json: true,
json: body,
});
});
describe('failures', () => {
let sendWebhook;
beforeEach(async () => {
sandbox.restore();
sandbox.stub(got, 'post').returns(Promise.reject());
sendWebhook = new WebhookSender({ type: 'taskActivity' });
user.webhooks = [{
url: 'http://custom-url.com', enabled: true, type: 'taskActivity',
}];
await user.save();
expect(user.webhooks[0].failures).to.equal(0);
expect(user.webhooks[0].lastFailureAt).to.equal(undefined);
});
it('does not increase failures counter if request is successfull', async () => {
sandbox.restore();
sandbox.stub(got, 'post').returns(Promise.resolve());
const body = {};
sendWebhook.send(user, body);
expect(got.post).to.be.calledOnce;
expect(got.post).to.be.calledWithMatch('http://custom-url.com', {
json: body,
});
await sleep(0.1);
user = await User.findById(user._id).exec();
expect(user.webhooks[0].failures).to.equal(0);
expect(user.webhooks[0].lastFailureAt).to.equal(undefined);
});
it('records failures', async () => {
sinon.stub(logger, 'error');
const body = {};
sendWebhook.send(user, body);
expect(got.post).to.be.calledOnce;
expect(got.post).to.be.calledWithMatch('http://custom-url.com', {
json: body,
});
await sleep(0.1);
user = await User.findById(user._id).exec();
expect(user.webhooks[0].failures).to.equal(1);
expect((Date.now() - user.webhooks[0].lastFailureAt.getTime()) < 10000).to.be.true;
expect(logger.error).to.be.calledOnce;
logger.error.restore();
});
it('disables a webhook after 10 failures', async () => {
const times = 10;
for (let i = 0; i < times; i += 1) {
sendWebhook.send(user, {});
await sleep(0.1); // eslint-disable-line no-await-in-loop
user = await User.findById(user._id).exec(); // eslint-disable-line no-await-in-loop
}
expect(got.post).to.be.callCount(10);
expect(got.post).to.be.calledWithMatch('http://custom-url.com');
await sleep(0.1);
user = await User.findById(user._id).exec();
expect(user.webhooks[0].enabled).to.equal(false);
expect(user.webhooks[0].failures).to.equal(0);
});
it('resets failures after a month ', async () => {
const oneMonthAgo = moment().subtract(1, 'months').subtract(1, 'days').toDate();
user.webhooks[0].lastFailureAt = oneMonthAgo;
user.webhooks[0].failures = 9;
await user.save();
sendWebhook.send(user, []);
expect(got.post).to.be.calledOnce;
expect(got.post).to.be.calledWithMatch('http://custom-url.com');
await sleep(0.1);
user = await User.findById(user._id).exec();
expect(user.webhooks[0].failures).to.equal(1);
// Check that the stored date is whitin 10s from now
expect((Date.now() - user.webhooks[0].lastFailureAt.getTime()) < 10000).to.be.true;
});
});
});
@@ -364,8 +455,7 @@ describe('webhooks', () => {
expect(got.post).to.be.calledOnce;
expect(got.post).to.be.calledWithMatch(webhooks[0].url, {
json: true,
body: {
json: {
type: 'scored',
webhookType: 'taskActivity',
user: {
@@ -402,8 +492,7 @@ describe('webhooks', () => {
expect(got.post).to.be.calledOnce;
expect(got.post).to.be.calledWithMatch('http://global-activity.com', {
json: true,
body: {
json: {
type: 'scored',
webhookType: 'taskActivity',
user: {
@@ -456,8 +545,7 @@ describe('webhooks', () => {
expect(got.post).to.be.calledOnce;
expect(got.post).to.be.calledWithMatch(webhooks[0].url, {
json: true,
body: {
json: {
type,
webhookType: 'taskActivity',
user: {
@@ -497,8 +585,7 @@ describe('webhooks', () => {
expect(got.post).to.be.calledOnce;
expect(got.post).to.be.calledWithMatch(webhooks[0].url, {
json: true,
body: {
json: {
webhookType: 'taskActivity',
user: {
_id: user._id,
@@ -538,8 +625,7 @@ describe('webhooks', () => {
expect(got.post).to.be.calledOnce;
expect(got.post).to.be.calledWithMatch(webhooks[2].url, {
json: true,
body: {
json: {
type,
webhookType: 'userActivity',
user: {
@@ -585,8 +671,7 @@ describe('webhooks', () => {
expect(got.post).to.be.calledOnce;
expect(got.post).to.be.calledWithMatch(webhooks[1].url, {
json: true,
body: {
json: {
type,
webhookType: 'questActivity',
user: {
@@ -632,8 +717,7 @@ describe('webhooks', () => {
expect(got.post).to.be.calledOnce;
expect(got.post).to.be.calledWithMatch(webhooks[webhooks.length - 1].url, {
json: true,
body: {
json: {
webhookType: 'groupChatReceived',
user: {
_id: user._id,
+1 -1
View File
@@ -19,7 +19,7 @@ describe('analytics middleware', () => {
next = generateNext();
});
it('attaches analytics object res.locals', () => {
it('attaches analytics object to res', () => {
const attachAnalytics = requireAgain(pathToAnalyticsMiddleware).default;
attachAnalytics(req, res, next);
+31
View File
@@ -0,0 +1,31 @@
import {
generateRes,
generateReq,
generateNext,
} from '../../../helpers/api-unit.helper';
import {
disableCache,
} from '../../../../website/server/middlewares/cache';
describe('cache middlewares', () => {
let res; let req; let
next;
beforeEach(() => {
req = generateReq();
res = generateRes();
next = generateNext();
});
describe('disableCache', () => {
it('sets the correct headers', () => {
disableCache(req, res, next);
expect(res.set).to.have.been.calledWith('Cache-Control', 'no-store');
expect(next).to.have.been.calledOnce;
});
xit('removes the etag header', () => {
// @TODO how to stub onHeaders
});
});
});
+3 -20
View File
@@ -21,28 +21,11 @@ describe('cron middleware', () => {
req;
let user;
beforeEach(done => {
beforeEach(async () => {
res = generateRes();
req = generateReq();
user = new User({
auth: {
local: {
username: 'username',
lowerCaseUsername: 'username',
email: 'email@email.email',
salt: 'salt',
hashed_password: 'hashed_password', // eslint-disable-line camelcase
},
},
});
user.save()
.then(savedUser => {
res.locals.user = savedUser;
res.analytics = analyticsService;
done();
})
.catch(done);
user = await res.locals.user.save();
res.analytics = analyticsService;
});
afterEach(() => {
@@ -170,6 +170,7 @@ describe('errorHandler', () => {
originalUrl: req.originalUrl,
headers: req.headers,
body: req.body,
query: req.query,
httpCode: 400,
isHandledError: true,
});
@@ -0,0 +1,94 @@
import nconf from 'nconf';
import requireAgain from 'require-again';
import {
generateRes,
generateReq,
generateNext,
} from '../../../helpers/api-unit.helper';
import { Forbidden } from '../../../../website/server/libs/errors';
import apiError from '../../../../website/server/libs/apiError';
function checkErrorThrown (next) {
expect(next).to.have.been.calledOnce;
const calledWith = next.getCall(0).args;
expect(calledWith[0].message).to.equal(apiError('ipAddressBlocked'));
expect(calledWith[0] instanceof Forbidden).to.equal(true);
}
function checkErrorNotThrown (next) {
expect(next).to.have.been.calledOnce;
const calledWith = next.getCall(0).args;
expect(typeof calledWith[0] === 'undefined').to.equal(true);
}
describe('ipBlocker middleware', () => {
const pathToIpBlocker = '../../../../website/server/middlewares/ipBlocker';
let res; let req; let next;
beforeEach(() => {
res = generateRes();
req = generateReq();
next = generateNext();
});
it('is disabled when the env var is not defined', () => {
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns(undefined);
const attachIpBlocker = requireAgain(pathToIpBlocker).default;
attachIpBlocker(req, res, next);
checkErrorNotThrown(next);
});
it('is disabled when the env var is an empty string', () => {
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns('');
const attachIpBlocker = requireAgain(pathToIpBlocker).default;
attachIpBlocker(req, res, next);
checkErrorNotThrown(next);
});
it('is disabled when the env var contains comma separated empty strings', () => {
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns(' , , ');
const attachIpBlocker = requireAgain(pathToIpBlocker).default;
attachIpBlocker(req, res, next);
checkErrorNotThrown(next);
});
it('does not throw when the ip does not match', () => {
req.headers['x-forwarded-for'] = '192.168.1.1';
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns('192.168.1.2');
const attachIpBlocker = requireAgain(pathToIpBlocker).default;
attachIpBlocker(req, res, next);
checkErrorNotThrown(next);
});
it('throws when a matching ip exist in x-forwarded-for', () => {
req.headers['x-forwarded-for'] = '192.168.1.1';
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns('192.168.1.1');
const attachIpBlocker = requireAgain(pathToIpBlocker).default;
attachIpBlocker(req, res, next);
checkErrorThrown(next);
});
it('trims ips in x-forwarded-for', () => {
req.headers['x-forwarded-for'] = '192.168.1.1';
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns(', 192.168.1.1 , 192.168.1.4, ');
const attachIpBlocker = requireAgain(pathToIpBlocker).default;
attachIpBlocker(req, res, next);
checkErrorThrown(next);
});
it('works when multiple ips are passed in x-forwarded-for', () => {
req.headers['x-forwarded-for'] = '192.168.1.4';
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns('192.168.1.1, 192.168.1.4, 192.168.1.3');
const attachIpBlocker = requireAgain(pathToIpBlocker).default;
attachIpBlocker(req, res, next);
checkErrorThrown(next);
});
});
+11 -4
View File
@@ -12,6 +12,9 @@ import { model as User } from '../../../../website/server/models/user';
const { i18n } = common;
// TODO some of the checks here can be simplified to simply check
// that the right parameters are passed to the functions in libs/language
describe('language middleware', () => {
describe('res.t', () => {
let res; let req; let
@@ -19,6 +22,8 @@ describe('language middleware', () => {
beforeEach(() => {
res = generateRes();
// remove the defaul user
res.locals.user = undefined;
req = generateReq();
next = generateNext();
@@ -57,6 +62,8 @@ describe('language middleware', () => {
beforeEach(() => {
res = generateRes();
// remove the defaul user
res.locals.user = undefined;
req = generateReq();
next = generateNext();
attachTranslateFunction(req, res, next);
@@ -88,7 +95,7 @@ describe('language middleware', () => {
lang: 'es',
};
req.locals = {
res.locals = {
user: {
preferences: {
language: 'it',
@@ -108,7 +115,7 @@ describe('language middleware', () => {
context('authorized request', () => {
it('uses the user preferred language if avalaible', () => {
req.locals = {
res.locals = {
user: {
preferences: {
language: 'it',
@@ -122,7 +129,7 @@ describe('language middleware', () => {
});
it('falls back to english if the user preferred language is not avalaible', done => {
req.locals = {
res.locals = {
user: {
preferences: {
language: 'bla',
@@ -138,7 +145,7 @@ describe('language middleware', () => {
});
it('uses the user preferred language even if a session is included in request', () => {
req.locals = {
res.locals = {
user: {
preferences: {
language: 'it',
@@ -11,7 +11,9 @@ import apiError from '../../../../../website/server/libs/apiError';
describe('GET /groups', () => {
let user;
let userInGuild;
const NUMBER_OF_PUBLIC_GUILDS = 3; // 2 + the tavern
const NUMBER_OF_PUBLIC_GUILDS_USER_IS_LEADER = 2;
const NUMBER_OF_PUBLIC_GUILDS_USER_IS_MEMBER = 1;
const NUMBER_OF_USERS_PRIVATE_GUILDS = 1;
const NUMBER_OF_GROUPS_USER_CAN_VIEW = 5;
@@ -33,14 +35,20 @@ describe('GET /groups', () => {
name: 'public guild - is member',
type: 'guild',
privacy: 'public',
summary: 'ohayou kombonwa',
description: 'oyasumi',
});
await leader.post(`/groups/${publicGuildUserIsMemberOf._id}/invite`, { uuids: [user._id] });
await user.post(`/groups/${publicGuildUserIsMemberOf._id}/join`);
userInGuild = await generateUser({ guilds: [publicGuildUserIsMemberOf._id] });
publicGuildNotMember = await generateGroup(leader, {
name: 'public guild - is not member',
type: 'guild',
privacy: 'public',
summary: 'Natsume Soseki',
description: 'Kinnosuke no Hondana',
categories,
});
@@ -150,6 +158,35 @@ describe('GET /groups', () => {
expect(guilds.length).to.equal(0);
});
it('filters public guilds by leader role', async () => {
const guilds = await user.get('/groups?type=publicGuilds&leader=true');
expect(guilds.length).to.equal(NUMBER_OF_PUBLIC_GUILDS_USER_IS_LEADER);
});
it('filters public guilds by member role', async () => {
const guilds = await userInGuild.get('/groups?type=publicGuilds&member=true');
expect(guilds.length).to.equal(1);
expect(guilds[0].name).to.have.string('is member');
});
it('filters public guilds by single-word search term', async () => {
const guilds = await user.get('/groups?type=publicGuilds&search=kom');
expect(guilds.length).to.equal(1);
expect(guilds[0].summary).to.have.string('ohayou kombonwa');
});
it('filters public guilds by single-word search term left and right-padded by spaces', async () => {
const guilds = await user.get('/groups?type=publicGuilds&search=++++ohayou+kombonwa+++++');
expect(guilds.length).to.equal(1);
expect(guilds[0].summary).to.have.string('ohayou kombonwa');
});
it('filters public guilds by two-words search term separated by multiple spaces', async () => {
const guilds = await user.get('/groups?type=publicGuilds&search=kinnosuke+++++hon');
expect(guilds.length).to.equal(1);
expect(guilds[0].description).to.have.string('Kinnosuke');
});
});
describe('public guilds pagination', () => {
@@ -55,6 +55,18 @@ describe('POST /tasks/user', () => {
});
});
it('returns an error if reward value is a negative number', async () => {
await expect(user.post('/tasks/user', {
type: 'reward',
text: 'reward with negative value',
value: -10,
})).to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: 'reward validation failed',
});
});
it('does not update user.tasksOrder.{taskType} when the task is not saved because invalid', async () => {
const originalHabitsOrder = (await user.get('/user')).tasksOrder.habits;
await expect(user.post('/tasks/user', {
@@ -530,5 +530,15 @@ describe('PUT /tasks/:id', () => {
expect(savedReward.value).to.eql(100);
});
it('returns an error if reward value is a negative number', async () => {
await expect(user.put(`/tasks/${reward._id}`, {
value: -10,
})).to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: 'reward validation failed',
});
});
});
});
@@ -346,4 +346,23 @@ describe('DELETE /user', () => {
await expect(checkExistence('users', user._id)).to.eventually.eql(false);
});
});
context('user with Apple auth', async () => {
beforeEach(async () => {
user = await generateUser({
auth: {
apple: {
id: 'apple-id',
},
},
});
});
it('deletes a Apple user', async () => {
await user.del('/user', {
password: DELETE_CONFIRMATION,
});
await expect(checkExistence('users', user._id)).to.eventually.eql(false);
});
});
});
@@ -95,4 +95,42 @@ describe('DELETE social registration', () => {
expect(user.auth.goodl).to.be.undefined;
});
});
context('Apple', () => {
it('fails if user does not have an alternative registration method', async () => {
await user.update({
'auth.apple.id': 'some-apple-id',
'auth.local': { ok: true },
});
await expect(user.del('/user/auth/social/apple')).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('cantDetachSocial'),
});
});
it('succeeds if user has a local registration', async () => {
await user.update({
'auth.apple.id': 'some-apple-id',
});
const response = await user.del('/user/auth/social/apple');
expect(response).to.eql({});
await user.sync();
expect(user.auth.apple).to.be.undefined;
});
it('succeeds if user has a facebook registration', async () => {
await user.update({
'auth.apple.id': 'some-apple-id',
'auth.facebook.id': 'some-facebook-id',
'auth.local': { ok: true },
});
const response = await user.del('/user/auth/social/apple');
expect(response).to.eql({});
await user.sync();
expect(user.auth.goodl).to.be.undefined;
});
});
});
@@ -0,0 +1,50 @@
import {
generateUser,
requester,
getProperty,
} from '../../../../../helpers/api-integration/v3';
import * as appleAuth from '../../../../../../website/server/libs/auth/apple';
describe('GET /user/auth/apple', () => {
let api;
let user;
const appleEndpoint = '/user/auth/apple';
before(async () => {
const expectedResult = { id: 'appleId', name: 'an apple user' };
sandbox.stub(appleAuth, 'appleProfile').returns(Promise.resolve(expectedResult));
});
beforeEach(async () => {
api = requester();
user = await generateUser();
});
it('registers a new user', async () => {
const response = await api.get(appleEndpoint);
expect(response.apiToken).to.exist;
expect(response.id).to.exist;
expect(response.newUser).to.be.true;
await expect(getProperty('users', response.id, 'auth.apple.id')).to.eventually.equal('appleId');
await expect(getProperty('users', response.id, 'profile.name')).to.eventually.equal('an apple user');
});
it('logs an existing user in', async () => {
const registerResponse = await api.get(appleEndpoint);
const response = await api.get(appleEndpoint);
expect(response.apiToken).to.eql(registerResponse.apiToken);
expect(response.id).to.eql(registerResponse.id);
expect(response.newUser).to.be.false;
});
it('add social auth to an existing user', async () => {
const response = await user.get(appleEndpoint);
expect(response.apiToken).to.exist;
expect(response.id).to.exist;
expect(response.newUser).to.be.false;
});
});
@@ -492,6 +492,74 @@ describe('POST /user/auth/local/register', () => {
});
});
context('attach to google user', () => {
let user;
const email = 'some@email-google.net';
const username = 'some-username-google';
const password = 'some-password';
beforeEach(async () => {
user = await generateUser();
});
it('checks onlySocialAttachLocal', async () => {
await expect(user.post('/user/auth/local/register', {
email,
username,
password,
confirmPassword: password,
})).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('onlySocialAttachLocal'),
});
});
it('succeeds', async () => {
await user.update({ 'auth.google.id': 'some-google-id', 'auth.local': { ok: true } });
await user.post('/user/auth/local/register', {
username,
email,
password,
confirmPassword: password,
});
await user.sync();
expect(user.auth.local.username).to.eql(username);
expect(user.auth.local.email).to.eql(email);
});
});
context('attach to apple user', () => {
let user;
const email = 'some@email-apple.net';
const username = 'some-username-apple';
const password = 'some-password';
beforeEach(async () => {
user = await generateUser();
});
it('checks onlySocialAttachLocal', async () => {
await expect(user.post('/user/auth/local/register', {
email,
username,
password,
confirmPassword: password,
})).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('onlySocialAttachLocal'),
});
});
it('succeeds', async () => {
await user.update({ 'auth.apple.id': 'some-apple-id', 'auth.local': { ok: true } });
await user.post('/user/auth/local/register', {
username,
email,
password,
confirmPassword: password,
});
await user.sync();
expect(user.auth.local.username).to.eql(username);
expect(user.auth.local.email).to.eql(email);
});
});
context('login is already taken', () => {
let username; let email; let
api;
@@ -51,6 +51,7 @@ describe('POST /user/auth/social', () => {
await expect(getProperty('users', response.id, 'profile.name')).to.eventually.equal('a facebook user');
await expect(getProperty('users', response.id, 'auth.local.lowerCaseUsername')).to.exist;
await expect(getProperty('users', response.id, 'auth.facebook.id')).to.eventually.equal(facebookId);
});
it('logs an existing user in', async () => {
@@ -106,6 +107,7 @@ describe('POST /user/auth/social', () => {
expect(response.apiToken).to.exist;
expect(response.id).to.exist;
expect(response.newUser).to.be.true;
await expect(getProperty('users', response.id, 'auth.google.id')).to.eventually.equal(googleId);
await expect(getProperty('users', response.id, 'profile.name')).to.eventually.equal('a google user');
});
@@ -81,6 +81,16 @@ describe('POST /user/webhook', () => {
expect(webhook.type).to.eql('taskActivity');
});
it('ignores protected fields', async () => {
body.failures = 3;
body.lastFailureAt = new Date();
const webhook = await user.post('/user/webhook', body);
expect(webhook.failures).to.eql(0);
expect(webhook.lastFailureAt).to.eql(undefined);
});
it('successfully adds the webhook', async () => {
expect(user.webhooks).to.eql([]);
@@ -63,6 +63,21 @@ describe('PUT /user/webhook/:id', () => {
expect(webhook.options).to.eql(options);
});
it('ignores protected fields', async () => {
const failures = 3;
const lastFailureAt = new Date();
await user.put(`/user/webhook/${webhookToUpdate.id}`, {
failures, lastFailureAt,
});
await user.sync();
const webhook = user.webhooks.find(hook => webhookToUpdate.id === hook.id);
expect(webhook.failures).to.eql(0);
expect(webhook.lastFailureAt).to.eql(undefined);
});
it('updates a webhook with empty label', async () => {
const url = 'http://a-new-url.com';
const type = 'groupChatReceived';
+65
View File
@@ -0,0 +1,65 @@
import {
requester,
translate,
} from '../../../helpers/api-integration/v4';
import i18n from '../../../../website/common/script/i18n';
describe('GET /faq', () => {
describe('language parameter', () => {
it('returns faq (and does not require authentication)', async () => {
const res = await requester().get('/faq');
expect(res).to.have.property('stillNeedHelp');
expect(res.stillNeedHelp.ios).to.equal(translate('iosFaqStillNeedHelp'));
expect(res).to.have.property('questions');
expect(res.questions[0].question).to.equal(translate('faqQuestion0'));
});
it('returns faq not in English', async () => {
const res = await requester().get('/faq?language=de');
expect(res).to.have.nested.property('stillNeedHelp.ios');
expect(res.stillNeedHelp.ios).to.equal(i18n.t('iosFaqStillNeedHelp', 'de'));
});
it('falls back to English if the desired language is not found', async () => {
const res = await requester().get('/faq?language=wrong');
expect(res).to.have.nested.property('stillNeedHelp.ios');
expect(res.stillNeedHelp.ios).to.equal(translate('iosFaqStillNeedHelp'));
});
});
describe('platform parameter', () => {
it('returns faq with answers for ios platform only', async () => {
const res = await requester().get('/faq?platform=ios');
expect(res).to.have.property('stillNeedHelp');
expect(res.stillNeedHelp).to.eql({ ios: translate('iosFaqStillNeedHelp') });
expect(res).to.have.property('questions');
expect(res.questions[0]).to.eql({
question: translate('faqQuestion0'),
ios: translate('iosFaqAnswer0'),
});
});
it('returns an error when invalid platform parameter is specified', async () => {
const request = requester().get('/faq?platform=wrong');
await expect(request)
.to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: i18n.t('invalidReqParams'),
});
});
it('falls back to "web" description if there is no description for specified platform', async () => {
const res = await requester().get('/faq?platform=android');
expect(res).to.have.property('stillNeedHelp');
expect(res.stillNeedHelp).to.eql({ web: translate('webFaqStillNeedHelp') });
expect(res).to.have.property('questions');
expect(res.questions[0]).to.eql({
question: translate('faqQuestion0'),
android: translate('androidFaqAnswer0'),
});
});
});
});
@@ -457,6 +457,74 @@ describe('POST /user/auth/local/register', () => {
});
});
context('attach to google user', () => {
let user;
const email = 'some-google@email.net';
const username = 'some-username-google';
const password = 'some-password';
beforeEach(async () => {
user = await generateUser();
});
it('checks onlySocialAttachLocal', async () => {
await expect(user.post('/user/auth/local/register', {
email,
username,
password,
confirmPassword: password,
})).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('onlySocialAttachLocal'),
});
});
it('succeeds', async () => {
await user.update({ 'auth.google.id': 'some-google-id', 'auth.local': { ok: true } });
await user.post('/user/auth/local/register', {
username,
email,
password,
confirmPassword: password,
});
await user.sync();
expect(user.auth.local.username).to.eql(username);
expect(user.auth.local.email).to.eql(email);
});
});
context('attach to apple user', () => {
let user;
const email = 'some-apple@email.net';
const username = 'some-username-apple';
const password = 'some-password';
beforeEach(async () => {
user = await generateUser();
});
it('checks onlySocialAttachLocal', async () => {
await expect(user.post('/user/auth/local/register', {
email,
username,
password,
confirmPassword: password,
})).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('onlySocialAttachLocal'),
});
});
it('succeeds', async () => {
await user.update({ 'auth.apple.id': 'some-apple-id', 'auth.local': { ok: true } });
await user.post('/user/auth/local/register', {
username,
email,
password,
confirmPassword: password,
});
await user.sync();
expect(user.auth.local.username).to.eql(username);
expect(user.auth.local.email).to.eql(email);
});
});
context('login is already taken', () => {
let username; let email; let
api;
+2354 -1939
View File
File diff suppressed because it is too large Load Diff
+17 -17
View File
@@ -13,25 +13,25 @@
"test:unit": "vue-cli-service test:unit --require ./tests/unit/helpers.js"
},
"dependencies": {
"@vue/cli-plugin-babel": "^4.2.3",
"@vue/cli-plugin-eslint": "^4.2.3",
"@vue/cli-plugin-router": "^4.2.3",
"@vue/cli-plugin-unit-mocha": "^4.2.3",
"@vue/cli-service": "^4.2.3",
"@storybook/addon-actions": "^5.3.14",
"@storybook/addon-knobs": "^5.3.14",
"@storybook/addon-links": "^5.3.14",
"@storybook/addon-notes": "^5.3.14",
"@storybook/vue": "^5.3.14",
"@vue/cli-plugin-babel": "^4.3.1",
"@vue/cli-plugin-eslint": "^4.3.1",
"@vue/cli-plugin-router": "^4.3.1",
"@vue/cli-plugin-unit-mocha": "^4.3.1",
"@vue/cli-service": "^4.3.1",
"@storybook/addon-actions": "^5.3.18",
"@storybook/addon-knobs": "^5.3.18",
"@storybook/addon-links": "^5.3.18",
"@storybook/addon-notes": "^5.3.18",
"@storybook/vue": "^5.3.18",
"@vue/test-utils": "1.0.0-beta.29",
"amplitude-js": "^5.9.0",
"amplitude-js": "^5.11.0",
"axios": "^0.19.2",
"axios-progress-bar": "^1.2.0",
"babel-eslint": "^10.1.0",
"bootstrap": "^4.4.1",
"bootstrap-vue": "^2.6.1",
"bootstrap-vue": "^2.11.0",
"chai": "^4.1.2",
"core-js": "^3.6.4",
"core-js": "^3.6.5",
"eslint": "^6.8.0",
"eslint-config-habitrpg": "^6.2.0",
"eslint-plugin-mocha": "^5.3.0",
@@ -40,11 +40,11 @@
"hellojs": "^1.18.4",
"inspectpack": "^4.4.0",
"intro.js": "^2.9.3",
"jquery": "^3.4.1",
"jquery": "^3.5.0",
"lodash": "^4.17.15",
"moment": "^2.24.0",
"nconf": "^0.10.0",
"sass": "^1.26.2",
"sass": "^1.26.3",
"sass-loader": "^8.0.2",
"smartbanner.js": "^1.15.0",
"svg-inline-loader": "^0.8.2",
@@ -58,9 +58,9 @@
"vue-mugen-scroll": "^0.2.6",
"vue-router": "^3.1.6",
"vue-template-compiler": "^2.6.11",
"vue2-perfect-scrollbar": "^1.3.0",
"vue2-perfect-scrollbar": "^1.4.0",
"vuedraggable": "^2.23.1",
"vuejs-datepicker": "git://github.com/habitrpg/vuejs-datepicker.git#5d237615463a84a23dd6f3f77c6ab577d68593ec",
"webpack": "^4.42.0"
"webpack": "^4.42.1"
}
}
+13
View File
@@ -0,0 +1,13 @@
The files in the following subfolders:
- audio
- emails
- icons
- merch
- presskit
are not processed by Webpack so their filenames don't get hashed, but given that they almost never change, they're still cached for 1 week.
In case one of the files needs to be updated the filename should be changed if possible.
For more information see `website/server/middlewares/static.js`.
+9 -22
View File
@@ -20,10 +20,6 @@
</svg>
<!-- eslint-enable max-len -->
</div>
<div class="col-12 text-center">
<h2>{{ $t('tipTitle', {tipNumber: currentTipNumber}) }}</h2>
<p>{{ currentTip }}</p>
</div>
</div>
</div>
<div
@@ -33,7 +29,7 @@
'resting': showRestingBanner
}"
>
<banned-account-modal />
<!-- <banned-account-modal /> -->
<amazon-payments-modal v-if="!isStaticPage" />
<payments-success-modal />
<sub-cancel-modal-confirm v-if="isUserLoaded" />
@@ -266,7 +262,6 @@ import {
} from '@/libs/userlocalManager';
import svgClose from '@/assets/svg/close.svg';
import bannedAccountModal from '@/components/bannedAccountModal';
const COMMUNITY_MANAGER_EMAIL = process.env.EMAILS_COMMUNITY_MANAGER_EMAIL; // eslint-disable-line
@@ -281,7 +276,6 @@ export default {
BuyModal,
SelectMembersModal,
amazonPaymentsModal,
bannedAccountModal,
paymentsSuccessModal,
subCancelModalConfirm,
subCanceledModal,
@@ -299,7 +293,6 @@ export default {
audioSuffix: null,
loading: true,
currentTipNumber: 0,
bannerHidden: false,
};
},
@@ -312,15 +305,6 @@ export default {
castingSpell () {
return this.$store.state.spellOptions.castingSpell;
},
currentTip () {
const numberOfTips = 35 + 1;
const min = 1;
const randomNumber = Math.random() * (numberOfTips - min) + min;
const tipNumber = Math.floor(randomNumber);
this.currentTipNumber = tipNumber; // eslint-disable-line vue/no-side-effects-in-computed-properties, max-len
return this.$t(`tip${tipNumber}`);
},
showRestingBanner () {
return !this.bannerHidden && this.user && this.user.preferences.sleep;
},
@@ -385,7 +369,8 @@ export default {
return response;
}, error => {
if (error.response.status >= 400) {
this.checkForBannedUser(error);
const isBanned = this.checkForBannedUser(error);
if (isBanned === true) return null; // eslint-disable-line consistent-return
// Don't show errors from getting user details. These users have delete their account,
// but their chat message still exists.
@@ -403,7 +388,8 @@ export default {
// TODO use a specific error like NotificationNotFound instead of checking for the string
const invalidUserMessage = [this.$t('invalidCredentials'), 'Missing authentication headers.'];
if (invalidUserMessage.indexOf(errorMessage) !== -1) {
this.$store.dispatch('auth:logout');
this.$store.dispatch('auth:logout', { redirectToLogin: true });
return null;
}
// Most server errors should return is click to dismiss errors, with some exceptions
@@ -553,7 +539,7 @@ export default {
// Case where user is not logged in
if (!parseSettings) {
return;
return false;
}
const bannedMessage = this.$t('accountSuspended', {
@@ -561,9 +547,10 @@ export default {
userId: parseSettings.auth.apiId,
});
if (errorMessage !== bannedMessage) return;
if (errorMessage !== bannedMessage) return false;
this.$root.$emit('bv::show::modal', 'banned-account');
this.$store.dispatch('auth:logout', { redirectToLogin: true });
return true;
},
initializeModalStack () {
// Manage modals
@@ -4,6 +4,12 @@
height: 219px;
}
.Pet_HatchingPotion_Dessert {
background: url("~@/assets/images/animated/Pet_HatchingPotion_Dessert.gif") no-repeat;
width: 68px;
height: 68px;
}
.Pet_HatchingPotion_Veggie {
background: url("~@/assets/images/animated/Pet_HatchingPotion_Veggie.gif") no-repeat;
width: 68px;
@@ -1,60 +1,84 @@
.promo_achievement_CottonCandyPink {
.promo_april_fools_2020 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -328px -316px;
width: 204px;
height: 102px;
}
.promo_armoire_backgrounds_202003 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -445px;
background-position: -445px -184px;
width: 423px;
height: 147px;
}
.promo_cosplay {
.promo_armoire_backgrounds_202004 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px 0px;
width: 623px;
height: 167px;
}
.promo_hugabug_bundle {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -424px -445px;
width: 420px;
background-position: 0px -500px;
width: 423px;
height: 147px;
}
.promo_mystery_202003 {
.promo_egg_quest {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -624px -211px;
background-position: -355px -648px;
width: 354px;
height: 147px;
}
.promo_mystery_202004 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -875px 0px;
width: 282px;
height: 147px;
}
.promo_pi_day {
.promo_pastel_skin_hair {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -593px;
width: 273px;
background-position: 0px -648px;
width: 354px;
height: 147px;
}
.customize-option.promo_pastel_skin_hair {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -25px -663px;
width: 60px;
height: 60px;
}
.promo_seasonal_shop_spring {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -875px -299px;
width: 162px;
height: 138px;
}
.promo_shiny_seeds {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -424px -500px;
width: 360px;
height: 147px;
}
.promo_spring_2019 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -337px;
width: 432px;
height: 162px;
}
.promo_spring_2020 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -445px 0px;
width: 429px;
height: 183px;
}
.promo_spring_potions_2020 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -433px -337px;
width: 423px;
height: 147px;
}
.promo_take_this {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -624px -359px;
background-position: -1026px -148px;
width: 96px;
height: 69px;
}
.scene_dailies {
.scene_hat_guild {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -168px;
width: 327px;
height: 276px;
background-position: 0px 0px;
width: 444px;
height: 336px;
}
.scene_gaining_achievement {
.scene_meditation {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -624px 0px;
width: 339px;
height: 210px;
}
.scene_shanaqui {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -328px -168px;
width: 282px;
height: 147px;
background-position: -875px -148px;
width: 150px;
height: 150px;
}
@@ -478,739 +478,739 @@
width: 60px;
height: 60px;
}
.background_apple_picking {
.background_animal_clouds {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1278px -1036px;
width: 141px;
height: 147px;
}
.background_aquarium {
.background_apple_picking {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: 0px -1184px;
width: 141px;
height: 147px;
}
.background_archaeological_dig {
.background_aquarium {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -142px -1184px;
width: 141px;
height: 147px;
}
.background_archery_range {
.background_archaeological_dig {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -284px -1184px;
width: 141px;
height: 147px;
}
.background_at_the_docks {
.background_archery_range {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -426px -1184px;
width: 141px;
height: 147px;
}
.background_aurora {
.background_at_the_docks {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -568px -1184px;
width: 141px;
height: 147px;
}
.background_autumn_flower_garden {
.background_aurora {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -710px -1184px;
width: 141px;
height: 147px;
}
.customize-option.background_autumn_flower_garden {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -735px -1199px;
width: 60px;
height: 60px;
}
.background_autumn_forest {
.background_autumn_flower_garden {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -852px -1184px;
width: 141px;
height: 147px;
}
.background_avalanche {
.customize-option.background_autumn_flower_garden {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -877px -1199px;
width: 60px;
height: 60px;
}
.background_autumn_forest {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -994px -1184px;
width: 141px;
height: 147px;
}
.background_back_alley {
.background_avalanche {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1136px -1184px;
width: 141px;
height: 147px;
}
.background_back_of_giant_beast {
.background_back_alley {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1278px -1184px;
width: 141px;
height: 147px;
}
.background_bamboo_forest {
.background_back_of_giant_beast {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1420px 0px;
width: 141px;
height: 147px;
}
.background_bayou {
.background_bamboo_forest {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1420px -148px;
width: 141px;
height: 147px;
}
.background_beach {
.background_bayou {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1420px -296px;
width: 141px;
height: 147px;
}
.background_beehive {
.background_beach {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1420px -444px;
width: 141px;
height: 147px;
}
.background_bell_tower {
.background_beehive {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1420px -592px;
width: 141px;
height: 147px;
}
.background_beside_well {
.background_bell_tower {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1420px -740px;
width: 141px;
height: 147px;
}
.background_birch_forest {
.background_beside_well {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1420px -888px;
width: 141px;
height: 147px;
}
.background_birthday_party {
.background_birch_forest {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1420px -1036px;
width: 141px;
height: 147px;
}
.background_blacksmithy {
.background_birthday_party {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1420px -1184px;
width: 141px;
height: 147px;
}
.background_blizzard {
.background_blacksmithy {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: 0px 0px;
width: 141px;
height: 147px;
}
.background_blossoming_desert {
.background_blizzard {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -142px -1332px;
width: 141px;
height: 147px;
}
.background_blue {
.background_blossoming_desert {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -284px -1332px;
width: 141px;
height: 147px;
}
.background_bridge {
.background_blue {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -426px -1332px;
width: 141px;
height: 147px;
}
.background_bug_covered_log {
.background_bridge {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -568px -1332px;
width: 141px;
height: 147px;
}
.background_buried_treasure {
.background_bug_covered_log {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -710px -1332px;
width: 141px;
height: 147px;
}
.background_butterfly_garden {
.background_buried_treasure {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -852px -1332px;
width: 141px;
height: 147px;
}
.background_champions_colosseum {
.background_butterfly_garden {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -994px -1332px;
width: 141px;
height: 147px;
}
.background_cherry_trees {
.background_champions_colosseum {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1136px -1332px;
width: 141px;
height: 147px;
}
.background_chessboard_land {
.background_cherry_trees {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1278px -1332px;
width: 141px;
height: 147px;
}
.background_clouds {
.background_chessboard_land {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1420px -1332px;
width: 141px;
height: 147px;
}
.background_coral_reef {
.background_clouds {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1562px 0px;
width: 141px;
height: 147px;
}
.background_cornfields {
.background_coral_reef {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1562px -148px;
width: 141px;
height: 147px;
}
.background_cozy_barn {
.background_cornfields {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1562px -296px;
width: 141px;
height: 147px;
}
.background_cozy_bedroom {
.background_cozy_barn {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1562px -444px;
width: 141px;
height: 147px;
}
.background_cozy_library {
.background_cozy_bedroom {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1562px -592px;
width: 141px;
height: 147px;
}
.background_creepy_castle {
.background_cozy_library {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1562px -740px;
width: 141px;
height: 147px;
}
.background_crosscountry_ski_trail {
.background_creepy_castle {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1562px -888px;
width: 141px;
height: 147px;
}
.background_crystal_cave {
.background_crosscountry_ski_trail {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1562px -1036px;
width: 141px;
height: 147px;
}
.background_dark_deep {
.background_crystal_cave {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1562px -1184px;
width: 141px;
height: 147px;
}
.background_deep_mine {
.background_dark_deep {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1562px -1332px;
width: 141px;
height: 147px;
}
.background_deep_sea {
.background_deep_mine {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: 0px -1480px;
width: 141px;
height: 147px;
}
.background_desert_dunes {
.background_deep_sea {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -142px -1480px;
width: 141px;
height: 147px;
}
.background_desert_with_snow {
.background_desert_dunes {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -284px -1480px;
width: 141px;
height: 147px;
}
.background_dilatory_castle {
.background_desert_with_snow {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -426px -1480px;
width: 141px;
height: 147px;
}
.background_dilatory_city {
.background_dilatory_castle {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: 0px -1332px;
width: 141px;
height: 147px;
}
.background_dilatory_ruins {
.background_dilatory_city {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1278px -296px;
width: 141px;
height: 147px;
}
.background_distant_castle {
.background_dilatory_ruins {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1278px -148px;
width: 141px;
height: 147px;
}
.background_dojo {
.background_distant_castle {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1278px 0px;
width: 141px;
height: 147px;
}
.background_drifting_raft {
.background_dojo {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1136px -1036px;
width: 141px;
height: 147px;
}
.background_driving_a_coach {
.background_drifting_raft {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -994px -1036px;
width: 141px;
height: 147px;
}
.background_driving_a_sleigh {
.background_driving_a_coach {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -852px -1036px;
width: 141px;
height: 147px;
}
.background_duck_pond {
.background_driving_a_sleigh {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -710px -1036px;
width: 141px;
height: 147px;
}
.background_dungeon {
.background_duck_pond {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -568px -1036px;
width: 141px;
height: 147px;
}
.background_dusty_canyons {
.background_dungeon {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -426px -1036px;
width: 141px;
height: 147px;
}
.background_elegant_balcony {
.background_dusty_canyons {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -284px -1036px;
width: 141px;
height: 147px;
}
.background_elegant_ballroom {
.background_elegant_balcony {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -142px -1036px;
width: 141px;
height: 147px;
}
.background_fairy_ring {
.background_elegant_ballroom {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: 0px -1036px;
width: 141px;
height: 147px;
}
.background_fantastical_shoe_store {
.background_fairy_ring {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1136px -888px;
width: 141px;
height: 147px;
}
.background_farmers_market {
.background_fantastical_shoe_store {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1136px -740px;
width: 141px;
height: 147px;
}
.background_farmhouse {
.background_farmers_market {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1136px -592px;
width: 141px;
height: 147px;
}
.background_fiber_arts_room {
.background_farmhouse {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1136px -444px;
width: 141px;
height: 147px;
}
.background_field_with_colored_eggs {
.background_fiber_arts_room {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1136px -296px;
width: 141px;
height: 147px;
}
.background_floating_islands {
.background_field_with_colored_eggs {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1136px -148px;
width: 141px;
height: 147px;
}
.background_floral_meadow {
.background_floating_islands {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1136px 0px;
width: 141px;
height: 147px;
}
.background_flower_market {
.background_floral_meadow {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -994px -888px;
width: 141px;
height: 147px;
}
.customize-option.background_flower_market {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -1019px -903px;
width: 60px;
height: 60px;
}
.background_flying_in_a_thunderstorm {
.background_flower_market {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -852px -888px;
width: 141px;
height: 147px;
}
.background_flying_over_a_field_of_wildflowers {
.customize-option.background_flower_market {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -877px -903px;
width: 60px;
height: 60px;
}
.background_flying_in_a_thunderstorm {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -710px -888px;
width: 141px;
height: 147px;
}
.customize-option.background_flying_over_a_field_of_wildflowers {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -735px -903px;
width: 60px;
height: 60px;
}
.background_flying_over_an_ancient_forest {
.background_flying_over_a_field_of_wildflowers {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -568px -888px;
width: 141px;
height: 147px;
}
.background_flying_over_icy_steppes {
.customize-option.background_flying_over_a_field_of_wildflowers {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -593px -903px;
width: 60px;
height: 60px;
}
.background_flying_over_an_ancient_forest {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -426px -888px;
width: 141px;
height: 147px;
}
.background_flying_over_rocky_canyon {
.background_flying_over_icy_steppes {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -284px -888px;
width: 141px;
height: 147px;
}
.background_flying_over_snowy_mountains {
.background_flying_over_rocky_canyon {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -142px -888px;
width: 141px;
height: 147px;
}
.background_flying_over_tropical_islands {
.background_flying_over_snowy_mountains {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: 0px -888px;
width: 141px;
height: 147px;
}
.background_foggy_moor {
.background_flying_over_tropical_islands {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -994px -740px;
width: 141px;
height: 147px;
}
.background_forest {
.background_foggy_moor {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -994px -592px;
width: 141px;
height: 147px;
}
.background_frigid_peak {
.background_forest {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -994px -444px;
width: 141px;
height: 147px;
}
.background_frosty_forest {
.background_frigid_peak {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -994px -296px;
width: 141px;
height: 147px;
}
.background_frozen_lake {
.background_frosty_forest {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -994px -148px;
width: 141px;
height: 147px;
}
.background_garden_shed {
.background_frozen_lake {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -994px 0px;
width: 141px;
height: 147px;
}
.background_gazebo {
.background_garden_shed {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -852px -740px;
width: 141px;
height: 147px;
}
.background_giant_birdhouse {
.background_gazebo {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -710px -740px;
width: 141px;
height: 147px;
}
.background_giant_book {
.background_giant_birdhouse {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -568px -740px;
width: 141px;
height: 147px;
}
.background_giant_dandelions {
.background_giant_book {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -426px -740px;
width: 141px;
height: 147px;
}
.background_giant_florals {
.background_giant_dandelions {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -284px -740px;
width: 141px;
height: 147px;
}
.background_giant_seashell {
.background_giant_florals {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -142px -740px;
width: 141px;
height: 147px;
}
.background_giant_wave {
.background_giant_seashell {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: 0px -740px;
width: 141px;
height: 147px;
}
.background_glowing_mushroom_cave {
.background_giant_wave {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -852px -592px;
width: 141px;
height: 147px;
}
.background_gorgeous_greenhouse {
.background_glowing_mushroom_cave {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -852px -444px;
width: 141px;
height: 147px;
}
.background_grand_staircase {
.background_gorgeous_greenhouse {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -852px -296px;
width: 141px;
height: 147px;
}
.background_graveyard {
.background_grand_staircase {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -852px -148px;
width: 141px;
height: 147px;
}
.background_green {
.background_graveyard {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -852px 0px;
width: 141px;
height: 147px;
}
.background_guardian_statues {
.background_green {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -710px -592px;
width: 141px;
height: 147px;
}
.background_gumdrop_land {
.background_guardian_statues {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -568px -592px;
width: 141px;
height: 147px;
}
.background_habit_city_streets {
.background_gumdrop_land {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -426px -592px;
width: 141px;
height: 147px;
}
.background_halflings_house {
.background_habit_city_streets {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -284px -592px;
width: 141px;
height: 147px;
}
.background_hall_of_heroes {
.background_halflings_house {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -142px -592px;
width: 141px;
height: 147px;
}
.background_harvest_feast {
.background_hall_of_heroes {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: 0px -592px;
width: 141px;
height: 147px;
}
.background_harvest_fields {
.background_harvest_feast {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -710px -444px;
width: 141px;
height: 147px;
}
.background_harvest_moon {
.background_harvest_fields {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -710px -296px;
width: 141px;
height: 147px;
}
.background_haunted_house {
.background_harvest_moon {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -710px -148px;
width: 141px;
height: 147px;
}
.background_holiday_market {
.background_haunted_house {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -710px 0px;
width: 141px;
height: 147px;
}
.background_holiday_wreath {
.background_heather_field {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -568px -444px;
width: 141px;
height: 147px;
}
.background_ice_cave {
.background_holiday_market {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -426px -444px;
width: 141px;
height: 147px;
}
.background_iceberg {
.background_holiday_wreath {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -284px -444px;
width: 141px;
height: 147px;
}
.background_idyllic_cabin {
.background_ice_cave {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -142px -444px;
width: 141px;
height: 147px;
}
.background_in_a_classroom {
.background_iceberg {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: 0px -444px;
width: 141px;
height: 147px;
}
.background_in_an_ancient_tomb {
.background_idyllic_cabin {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -568px -296px;
width: 141px;
height: 147px;
}
.background_island_waterfalls {
.background_in_a_classroom {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -568px -148px;
width: 141px;
height: 147px;
}
.background_kelp_forest {
.background_in_an_ancient_tomb {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -568px 0px;
width: 141px;
height: 147px;
}
.background_lake_with_floating_lanterns {
.background_island_waterfalls {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -426px -296px;
width: 141px;
height: 147px;
}
.background_lighthouse_shore {
.background_kelp_forest {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -284px -296px;
width: 141px;
height: 147px;
}
.background_lilypad {
.background_lake_with_floating_lanterns {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -142px -296px;
width: 141px;
height: 147px;
}
.background_magic_beanstalk {
.background_lighthouse_shore {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: 0px -296px;
width: 141px;
height: 147px;
}
.background_magical_candles {
.background_lilypad {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -426px -148px;
width: 141px;
height: 147px;
}
.background_magical_museum {
.background_magic_beanstalk {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -426px 0px;
width: 141px;
height: 147px;
}
.background_marble_temple {
.background_magical_candles {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -284px -148px;
width: 141px;
height: 147px;
}
.background_market {
.background_magical_museum {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -142px -148px;
width: 141px;
height: 147px;
}
.background_meandering_cave {
.background_marble_temple {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: 0px -148px;
width: 141px;
height: 147px;
}
.background_medieval_kitchen {
.background_market {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -284px 0px;
width: 141px;
height: 147px;
}
.background_midnight_castle {
.background_meandering_cave {
background-image: url('~@/assets/images/sprites/spritesmith-main-0.png');
background-position: -142px 0px;
width: 141px;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,768 +1,396 @@
.quest_TEMPLATE_FOR_MISSING_IMAGE {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -553px -1543px;
background-position: -502px -1519px;
width: 221px;
height: 39px;
}
.quest_dolphin {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -220px 0px;
width: 219px;
height: 219px;
}
.quest_dustbunnies {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1320px -660px;
width: 219px;
height: 219px;
}
.quest_egg {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1762px -362px;
width: 165px;
height: 207px;
}
.quest_evilsanta {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1762px -1023px;
width: 118px;
height: 131px;
}
.quest_evilsanta2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -220px -232px;
width: 219px;
height: 219px;
}
.quest_falcon {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -440px -232px;
width: 219px;
height: 219px;
}
.quest_ferret {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -660px 0px;
width: 219px;
height: 219px;
}
.quest_frog {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1540px 0px;
width: 221px;
height: 213px;
}
.quest_ghost_stag {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: 0px -452px;
width: 219px;
height: 219px;
}
.quest_goldenknight1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -220px -452px;
width: 219px;
height: 219px;
}
.quest_goldenknight2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: 0px -1519px;
width: 250px;
height: 150px;
}
.quest_goldenknight3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: 0px 0px;
width: 219px;
height: 231px;
}
.quest_gryphon {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -880px -1326px;
background-position: -443px -1332px;
width: 216px;
height: 177px;
}
.quest_guineapig {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -440px -446px;
background-position: -880px -220px;
width: 219px;
height: 219px;
}
.quest_harpy {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1323px 0px;
background-position: -880px -440px;
width: 219px;
height: 219px;
}
.quest_hedgehog {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -437px -1326px;
background-position: 0px -1332px;
width: 219px;
height: 186px;
}
.quest_hippo {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: 0px -226px;
background-position: -220px -672px;
width: 219px;
height: 219px;
}
.quest_horse {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -220px -226px;
background-position: -440px -672px;
width: 219px;
height: 219px;
}
.quest_kangaroo {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -440px -226px;
background-position: -660px -672px;
width: 219px;
height: 219px;
}
.quest_kraken {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1097px -1326px;
background-position: -1311px -1332px;
width: 216px;
height: 177px;
}
.quest_lostMasterclasser1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -663px -220px;
background-position: -1100px 0px;
width: 219px;
height: 219px;
}
.quest_lostMasterclasser2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: 0px -446px;
background-position: -1100px -220px;
width: 219px;
height: 219px;
}
.quest_lostMasterclasser3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -220px -446px;
background-position: -1100px -440px;
width: 219px;
height: 219px;
}
.quest_mayhemMistiflying1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1543px -1249px;
background-position: -1762px -570px;
width: 150px;
height: 150px;
}
.quest_mayhemMistiflying2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -660px -446px;
background-position: 0px -892px;
width: 219px;
height: 219px;
}
.quest_mayhemMistiflying3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -883px 0px;
background-position: -220px -892px;
width: 219px;
height: 219px;
}
.quest_monkey {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -883px -220px;
background-position: -440px -892px;
width: 219px;
height: 219px;
}
.quest_moon1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1308px -1106px;
background-position: -1540px -1082px;
width: 216px;
height: 216px;
}
.quest_moon2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: 0px -666px;
background-position: -880px -892px;
width: 219px;
height: 219px;
}
.quest_moon3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -220px -666px;
background-position: -1100px -892px;
width: 219px;
height: 219px;
}
.quest_moonstone1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -440px -666px;
background-position: -1320px 0px;
width: 219px;
height: 219px;
}
.quest_moonstone2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -660px -666px;
background-position: -1320px -220px;
width: 219px;
height: 219px;
}
.quest_moonstone3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -880px -666px;
background-position: -1320px -440px;
width: 219px;
height: 219px;
}
.quest_nudibranch {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: 0px -1326px;
background-position: -1540px -865px;
width: 216px;
height: 216px;
}
.quest_octopus {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -657px -1326px;
background-position: -220px -1332px;
width: 222px;
height: 177px;
}
.quest_owl {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1103px -440px;
background-position: 0px -1112px;
width: 219px;
height: 219px;
}
.quest_peacock {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1091px -1106px;
background-position: -1540px -648px;
width: 216px;
height: 216px;
}
.quest_penguin {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1543px -1065px;
background-position: -1762px -178px;
width: 190px;
height: 183px;
}
.quest_pterodactyl {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -220px -886px;
background-position: -660px -1112px;
width: 219px;
height: 219px;
}
.quest_rat {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -440px -886px;
background-position: -880px -1112px;
width: 219px;
height: 219px;
}
.quest_robot {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -660px -886px;
background-position: -1100px -1112px;
width: 219px;
height: 219px;
}
.quest_rock {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -657px -1106px;
background-position: -1540px -214px;
width: 216px;
height: 216px;
}
.quest_rooster {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1543px -712px;
background-position: -1528px -1332px;
width: 213px;
height: 174px;
}
.quest_ruby {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -223px 0px;
background-position: -440px -1112px;
width: 219px;
height: 219px;
}
.quest_sabretooth {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1323px -220px;
background-position: -220px -1112px;
width: 219px;
height: 219px;
}
.quest_seaserpent {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1323px -440px;
background-position: -1320px -880px;
width: 219px;
height: 219px;
}
.quest_sheep {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1323px -660px;
background-position: -660px -892px;
width: 219px;
height: 219px;
}
.quest_silver {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1323px -880px;
background-position: -1100px -660px;
width: 219px;
height: 219px;
}
.quest_slime {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: 0px -1106px;
background-position: -880px -672px;
width: 219px;
height: 219px;
}
.quest_sloth {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -220px -1106px;
background-position: 0px -672px;
width: 219px;
height: 219px;
}
.quest_snail {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -217px -1326px;
background-position: -1320px -1112px;
width: 219px;
height: 213px;
}
.quest_snake {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1543px 0px;
background-position: -660px -1332px;
width: 216px;
height: 177px;
}
.quest_spider {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: 0px -1543px;
background-position: -251px -1519px;
width: 250px;
height: 150px;
}
.quest_squirrel {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1100px -886px;
background-position: -880px 0px;
width: 219px;
height: 219px;
}
.quest_stoikalmCalamity1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -402px -1543px;
background-position: -1762px -872px;
width: 150px;
height: 150px;
}
.quest_stoikalmCalamity2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -880px -886px;
background-position: -440px -452px;
width: 219px;
height: 219px;
}
.quest_stoikalmCalamity3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: 0px -886px;
background-position: -660px -220px;
width: 219px;
height: 219px;
}
.quest_taskwoodsTerror1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -251px -1543px;
background-position: -1762px -721px;
width: 150px;
height: 150px;
}
.quest_taskwoodsTerror2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -874px -1106px;
background-position: -1540px -431px;
width: 216px;
height: 216px;
}
.quest_taskwoodsTerror3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1103px -660px;
background-position: 0px -232px;
width: 219px;
height: 219px;
}
.quest_treeling {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1314px -1326px;
background-position: -1094px -1332px;
width: 216px;
height: 177px;
}
.quest_trex {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1543px -887px;
background-position: -1762px 0px;
width: 204px;
height: 177px;
}
.quest_trex_undead {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1543px -534px;
background-position: -877px -1332px;
width: 216px;
height: 177px;
}
.quest_triceratops {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1103px -220px;
background-position: -440px 0px;
width: 219px;
height: 219px;
}
.quest_turtle {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1103px 0px;
background-position: -660px -452px;
width: 219px;
height: 219px;
}
.quest_unicorn {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -883px -440px;
width: 219px;
height: 219px;
}
.quest_velociraptor {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: 0px 0px;
width: 222px;
height: 225px;
}
.quest_vice1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1543px -178px;
width: 216px;
height: 177px;
}
.quest_vice2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -663px 0px;
width: 219px;
height: 219px;
}
.quest_vice3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1543px -356px;
width: 216px;
height: 177px;
}
.quest_whale {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -443px 0px;
width: 219px;
height: 219px;
}
.quest_yarn {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -440px -1106px;
width: 216px;
height: 216px;
}
.quest_atom1_soapBars {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -1356px;
width: 48px;
height: 51px;
}
.quest_dilatoryDistress1_blueFins {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -1408px;
width: 51px;
height: 48px;
}
.quest_dilatoryDistress1_fireCoral {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -1509px;
width: 48px;
height: 51px;
}
.quest_egg_plainEgg {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -1304px;
width: 48px;
height: 51px;
}
.quest_evilsanta2_branches {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: 0px -1694px;
width: 48px;
height: 51px;
}
.quest_evilsanta2_tracks {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -1035px;
width: 54px;
height: 60px;
}
.quest_goldenknight1_testimony {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -196px -1694px;
width: 48px;
height: 51px;
}
.quest_lostMasterclasser1_ancientTome {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1726px -1583px;
width: 33px;
height: 42px;
}
.quest_lostMasterclasser1_forbiddenTome {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -285px -1694px;
width: 33px;
height: 42px;
}
.quest_lostMasterclasser1_hiddenTome {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -319px -1694px;
width: 33px;
height: 42px;
}
.quest_mayhemMistiflying2_mistifly1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -147px -1694px;
width: 48px;
height: 51px;
}
.quest_mayhemMistiflying2_mistifly2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -98px -1694px;
width: 48px;
height: 51px;
}
.quest_mayhemMistiflying2_mistifly3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -49px -1694px;
width: 48px;
height: 51px;
}
.quest_moon1_shard {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1694px -1353px;
width: 42px;
height: 42px;
}
.quest_moonstone1_moonstone {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -855px -1543px;
width: 30px;
height: 30px;
}
.quest_robot_bolt {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1694px -1249px;
width: 48px;
height: 51px;
}
.quest_robot_gear {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -1613px;
width: 48px;
height: 51px;
}
.quest_robot_spring {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -1096px;
width: 48px;
height: 51px;
}
.quest_ruby_aquariusRune {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -594px -1652px;
width: 39px;
height: 40px;
}
.quest_ruby_rubyGem {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -1457px;
width: 48px;
height: 51px;
}
.quest_ruby_venusRune {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -775px -1543px;
width: 39px;
height: 39px;
}
.quest_silver_cancerRune {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -815px -1543px;
width: 39px;
height: 39px;
}
.quest_silver_moonRune {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -245px -1694px;
width: 39px;
height: 42px;
}
.quest_silver_silverIngot {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -1252px;
width: 48px;
height: 51px;
}
.quest_stoikalmCalamity2_icicleCoin {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -1200px;
width: 48px;
height: 51px;
}
.quest_taskwoodsTerror2_brownie {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -1148px;
width: 48px;
height: 51px;
}
.quest_taskwoodsTerror2_dryad {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -1561px;
width: 48px;
height: 51px;
}
.quest_taskwoodsTerror2_pixie {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1694px -1301px;
width: 48px;
height: 51px;
}
.quest_vice2_lightCrystal {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -553px -1652px;
width: 40px;
height: 40px;
}
.inventory_quest_scroll_alligator {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -414px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_amber {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -483px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_armadillo {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -552px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_atom1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -690px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_atom1_locked {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -621px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_atom2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -828px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_atom2_locked {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -759px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_atom3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -966px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_atom3_locked {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -897px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_axolotl {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -345px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_badger {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -276px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_basilist {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -207px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_beetle {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -138px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_bronze {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px -69px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_bunny {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1760px 0px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_butterfly {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1657px -1583px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_cheetah {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1588px -1583px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_cow {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1519px -1583px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_dilatoryDistress1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1381px -1583px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_dilatoryDistress2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1243px -1583px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_dilatoryDistress2_locked {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1312px -1583px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_dilatoryDistress3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1105px -1583px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_dilatoryDistress3_locked {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1174px -1583px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_dilatory_derby {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1450px -1583px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_dolphin {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1036px -1583px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_dustbunnies {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -967px -1583px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_egg {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -898px -1583px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_evilsanta {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -829px -1583px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_evilsanta2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -760px -1583px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_falcon {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -691px -1583px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_ferret {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -622px -1583px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_frog {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -553px -1583px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_ghost_stag {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1681px -1469px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_goldenknight1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1681px -1400px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_goldenknight1_locked {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1612px -1469px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_goldenknight2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1543px -1400px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_goldenknight2_locked {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1612px -1400px;
width: 68px;
height: 68px;
}
.inventory_quest_scroll_goldenknight3_locked {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1543px -1469px;
width: 68px;
height: 68px;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 473 KiB

After

Width:  |  Height:  |  Size: 469 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 658 KiB

After

Width:  |  Height:  |  Size: 643 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 286 KiB

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 353 KiB

After

Width:  |  Height:  |  Size: 424 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 KiB

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 143 KiB

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