From 464e4f10b20c77fe1b8a13f2c4741203452af3a7 Mon Sep 17 00:00:00 2001 From: SabreCat Date: Fri, 11 Aug 2023 14:34:27 -0500 Subject: [PATCH 01/39] feat(chats): increase chat entries to 400 --- website/server/models/group.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/server/models/group.js b/website/server/models/group.js index fd01b440b3..c41aa0320b 100644 --- a/website/server/models/group.js +++ b/website/server/models/group.js @@ -67,7 +67,7 @@ export const SPAM_MESSAGE_LIMIT = 2; export const SPAM_WINDOW_LENGTH = 60000; // 1 minute export const SPAM_MIN_EXEMPT_CONTRIB_LEVEL = 4; -export const MAX_CHAT_COUNT = 200; +export const MAX_CHAT_COUNT = 400; export const MAX_SUBBED_GROUP_CHAT_COUNT = 400; export const schema = new Schema({ From b679cfb935b96bf8697572e7067995770ffd48a4 Mon Sep 17 00:00:00 2001 From: negue Date: Fri, 11 Aug 2023 22:34:59 +0200 Subject: [PATCH 02/39] Split Vue.Router routes (#14812) --- .../client/src/router/deprecated-routes.js | 22 +++ website/client/src/router/index.js | 183 +----------------- .../client/src/router/shared-route-imports.js | 3 + website/client/src/router/static-routes.js | 86 ++++++++ website/client/src/router/user-routes.js | 71 +++++++ 5 files changed, 189 insertions(+), 176 deletions(-) create mode 100644 website/client/src/router/deprecated-routes.js create mode 100644 website/client/src/router/shared-route-imports.js create mode 100644 website/client/src/router/static-routes.js create mode 100644 website/client/src/router/user-routes.js diff --git a/website/client/src/router/deprecated-routes.js b/website/client/src/router/deprecated-routes.js new file mode 100644 index 0000000000..6ed1668264 --- /dev/null +++ b/website/client/src/router/deprecated-routes.js @@ -0,0 +1,22 @@ +import { NotFoundPage } from './shared-route-imports'; + +export const DEPRECATED_ROUTES = { + path: '/groups', + component: NotFoundPage, + children: [ + { name: 'tavern', path: 'tavern' }, + { + name: 'myGuilds', + path: 'myGuilds', + }, + { + name: 'guildsDiscovery', + path: 'discovery', + }, + { + name: 'guild', + path: 'guild/:groupId', + props: true, + }, + ], +}; diff --git a/website/client/src/router/index.js b/website/client/src/router/index.js index 7b4ce20bfe..ea8cceb6e9 100644 --- a/website/client/src/router/index.js +++ b/website/client/src/router/index.js @@ -4,52 +4,17 @@ import * as Analytics from '@/libs/analytics'; import getStore from '@/store'; import handleRedirect from './handleRedirect'; -import ParentPage from '@/components/parentPage'; import { PAGES } from '@/libs/consts'; +import { STATIC_ROUTES } from './static-routes'; +import { USER_ROUTES } from './user-routes'; +import { DEPRECATED_ROUTES } from '@/router/deprecated-routes'; +import { ProfilePage } from './shared-route-imports'; // NOTE: when adding a page make sure to implement the `common:setTitle` action -// Static Pages -const StaticWrapper = () => import(/* webpackChunkName: "entry" */'@/components/static/staticWrapper'); -const HomePage = () => import(/* webpackChunkName: "entry" */'@/components/static/home'); - -const AppPage = () => import(/* webpackChunkName: "static" */'@/components/static/app'); -const AppleRedirectPage = () => import(/* webpackChunkName: "static" */'@/components/static/appleRedirect'); -const ClearBrowserDataPage = () => import(/* webpackChunkName: "static" */'@/components/static/clearBrowserData'); -const CommunityGuidelinesPage = () => import(/* webpackChunkName: "static" */'@/components/static/communityGuidelines'); -const ContactPage = () => import(/* webpackChunkName: "static" */'@/components/static/contact'); -const FAQPage = () => import(/* webpackChunkName: "static" */'@/components/static/faq'); -const FeaturesPage = () => import(/* webpackChunkName: "static" */'@/components/static/features'); -const GroupPlansPage = () => import(/* webpackChunkName: "static" */'@/components/static/groupPlans'); -// Commenting out merch page see -// https://github.com/HabitRPG/habitica/issues/12039 -// const MerchPage = () => import(/* webpackChunkName: "static" */'@/components/static/merch'); -const NewsPage = () => import(/* webpackChunkName: "static" */'@/components/static/newStuff'); -const OverviewPage = () => import(/* webpackChunkName: "static" */'@/components/static/overview'); -const PressKitPage = () => import(/* webpackChunkName: "static" */'@/components/static/pressKit'); -const PrivacyPage = () => import(/* webpackChunkName: "static" */'@/components/static/privacy'); -const ChatSunsetFaq = () => import(/* webpackChunkName: "static" */'@/components/static/chatSunsetFaq'); -const TermsPage = () => import(/* webpackChunkName: "static" */'@/components/static/terms'); - const RegisterLoginReset = () => import(/* webpackChunkName: "auth" */'@/components/auth/registerLoginReset'); const Logout = () => import(/* webpackChunkName: "auth" */'@/components/auth/logout'); -// User Pages -// const StatsPage = () => import(/* webpackChunkName: "user" */'./components/userMenu/stats'); -// const AchievementsPage = -// () => import(/* webpackChunkName: "user" */'./components/userMenu/achievements'); -const ProfilePage = () => import(/* webpackChunkName: "user" */'@/components/userMenu/profilePage'); - -// Settings -const Settings = () => import(/* webpackChunkName: "settings" */'@/components/settings/index'); -const API = () => import(/* webpackChunkName: "settings" */'@/components/settings/api'); -const DataExport = () => import(/* webpackChunkName: "settings" */'@/components/settings/dataExport'); -const Notifications = () => import(/* webpackChunkName: "settings" */'@/components/settings/notifications'); -const PromoCode = () => import(/* webpackChunkName: "settings" */'@/components/settings/promoCode'); -const Site = () => import(/* webpackChunkName: "settings" */'@/components/settings/site'); -const Subscription = () => import(/* webpackChunkName: "settings" */'@/components/settings/subscription'); -const Transactions = () => import(/* webpackChunkName: "settings" */'@/components/settings/purchaseHistory'); - // Hall const HallPage = () => import(/* webpackChunkName: "hall" */'@/components/hall/index'); const PatronsPage = () => import(/* webpackChunkName: "hall" */'@/components/hall/patrons'); @@ -99,7 +64,6 @@ const QuestsPage = () => import(/* webpackChunkName: "shops-quest" */'@/componen const SeasonalPage = () => import(/* webpackChunkName: "shops-seasonal" */'@/components/shops/seasonal/index'); const TimeTravelersPage = () => import(/* webpackChunkName: "shops-timetravelers" */'@/components/shops/timeTravelers/index'); -const NotFoundPage = () => import(/* webpackChunkName: "not-found" */'@/components/404'); Vue.use(VueRouter); @@ -184,26 +148,7 @@ const router = new VueRouter({ }, ], }, - { - path: '/groups', - component: NotFoundPage, - children: [ - { name: 'tavern', path: 'tavern' }, - { - name: 'myGuilds', - path: 'myGuilds', - }, - { - name: 'guildsDiscovery', - path: 'discovery', - }, - { - name: 'guild', - path: 'guild/:groupId', - props: true, - }, - ], - }, + DEPRECATED_ROUTES, { path: PAGES.PRIVATE_MESSAGES, name: 'privateMessages', component: MessagesIndex }, { name: 'challenges', @@ -228,122 +173,8 @@ const router = new VueRouter({ }, ], }, - { - path: '/user', - component: ParentPage, - children: [ - { name: 'stats', path: 'stats', component: ProfilePage }, - { name: 'achievements', path: 'achievements', component: ProfilePage }, - { name: 'profile', path: 'profile', component: ProfilePage }, - { - name: 'settings', - path: 'settings', - component: Settings, - children: [ - { - name: 'site', - path: 'site', - component: Site, - }, - { - name: 'api', - path: 'api', - component: API, - }, - { - name: 'dataExport', - path: 'data-export', - component: DataExport, - }, - { - name: 'promoCode', - path: 'promo-code', - component: PromoCode, - }, - { - name: 'subscription', - path: 'subscription', - component: Subscription, - }, - { - name: 'transactions', - path: 'transactions', - component: Transactions, - meta: { - privilegeNeeded: [ - 'userSupport', - ], - }, - }, - { - name: 'notifications', - path: 'notifications', - component: Notifications, - }, - ], - }, - ], - }, - { - path: '/static', - component: StaticWrapper, - children: [ - { - name: 'app', path: 'app', component: AppPage, meta: { requiresLogin: false }, - }, - { - name: 'appleRedirect', path: 'apple-redirect', component: AppleRedirectPage, meta: { requiresLogin: false }, - }, - { - name: 'clearBrowserData', path: 'clear-browser-data', component: ClearBrowserDataPage, meta: { requiresLogin: false }, - }, - { - name: 'communityGuidelines', path: 'community-guidelines', component: CommunityGuidelinesPage, meta: { requiresLogin: false }, - }, - { - name: 'contact', path: 'contact', component: ContactPage, meta: { requiresLogin: false }, - }, - { - name: 'faq', path: 'faq', component: FAQPage, meta: { requiresLogin: false }, - }, - { - name: 'chatSunsetFaq', path: 'tavern-and-guilds', component: ChatSunsetFaq, meta: { requiresLogin: false }, - }, - { - name: 'features', path: 'features', component: FeaturesPage, meta: { requiresLogin: false }, - }, - { - name: 'groupPlans', path: 'group-plans', component: GroupPlansPage, meta: { requiresLogin: false }, - }, - { - name: 'home', path: 'home', component: HomePage, meta: { requiresLogin: false }, - }, - { - name: 'front', path: 'front', component: HomePage, meta: { requiresLogin: false }, - }, - { - name: 'news', path: 'new-stuff', component: NewsPage, meta: { requiresLogin: false }, - }, - { - name: 'overview', path: 'overview', component: OverviewPage, meta: { requiresLogin: false }, - }, - { - name: 'plans', path: 'plans', component: GroupPlansPage, meta: { requiresLogin: false }, - }, - { - name: 'pressKit', path: 'press-kit', component: PressKitPage, meta: { requiresLogin: false }, - }, - { - name: 'privacy', path: 'privacy', component: PrivacyPage, meta: { requiresLogin: false }, - }, - { - name: 'terms', path: 'terms', component: TermsPage, meta: { requiresLogin: false }, - }, - { - name: 'notFound', path: 'not-found', component: NotFoundPage, meta: { requiresLogin: false }, - }, - ], - }, + USER_ROUTES, + STATIC_ROUTES, { path: '/hall', component: HallPage, diff --git a/website/client/src/router/shared-route-imports.js b/website/client/src/router/shared-route-imports.js new file mode 100644 index 0000000000..e336f99cc6 --- /dev/null +++ b/website/client/src/router/shared-route-imports.js @@ -0,0 +1,3 @@ +export const NotFoundPage = () => import(/* webpackChunkName: "not-found" */'@/components/404'); + +export const ProfilePage = () => import(/* webpackChunkName: "user" */'@/components/userMenu/profilePage'); diff --git a/website/client/src/router/static-routes.js b/website/client/src/router/static-routes.js new file mode 100644 index 0000000000..015ba38d0a --- /dev/null +++ b/website/client/src/router/static-routes.js @@ -0,0 +1,86 @@ +// NOTE: when adding a page make sure to implement the `common:setTitle` action + +import { NotFoundPage } from './shared-route-imports'; + +const StaticWrapper = () => import(/* webpackChunkName: "entry" */'@/components/static/staticWrapper'); +const HomePage = () => import(/* webpackChunkName: "entry" */'@/components/static/home'); + +const AppPage = () => import(/* webpackChunkName: "static" */'@/components/static/app'); +const AppleRedirectPage = () => import(/* webpackChunkName: "static" */'@/components/static/appleRedirect'); +const ClearBrowserDataPage = () => import(/* webpackChunkName: "static" */'@/components/static/clearBrowserData'); +const CommunityGuidelinesPage = () => import(/* webpackChunkName: "static" */'@/components/static/communityGuidelines'); +const ContactPage = () => import(/* webpackChunkName: "static" */'@/components/static/contact'); +const FAQPage = () => import(/* webpackChunkName: "static" */'@/components/static/faq'); +const FeaturesPage = () => import(/* webpackChunkName: "static" */'@/components/static/features'); +const GroupPlansPage = () => import(/* webpackChunkName: "static" */'@/components/static/groupPlans'); +// Commenting out merch page see +// https://github.com/HabitRPG/habitica/issues/12039 +// const MerchPage = () => import(/* webpackChunkName: "static" */'@/components/static/merch'); +const NewsPage = () => import(/* webpackChunkName: "static" */'@/components/static/newStuff'); +const OverviewPage = () => import(/* webpackChunkName: "static" */'@/components/static/overview'); +const PressKitPage = () => import(/* webpackChunkName: "static" */'@/components/static/pressKit'); +const PrivacyPage = () => import(/* webpackChunkName: "static" */'@/components/static/privacy'); +const ChatSunsetFaq = () => import(/* webpackChunkName: "static" */'@/components/static/chatSunsetFaq'); +const TermsPage = () => import(/* webpackChunkName: "static" */'@/components/static/terms'); + + +export const STATIC_ROUTES = { + path: '/static', + component: StaticWrapper, + children: [ + { + name: 'app', path: 'app', component: AppPage, meta: { requiresLogin: false }, + }, + { + name: 'appleRedirect', path: 'apple-redirect', component: AppleRedirectPage, meta: { requiresLogin: false }, + }, + { + name: 'clearBrowserData', path: 'clear-browser-data', component: ClearBrowserDataPage, meta: { requiresLogin: false }, + }, + { + name: 'communityGuidelines', path: 'community-guidelines', component: CommunityGuidelinesPage, meta: { requiresLogin: false }, + }, + { + name: 'contact', path: 'contact', component: ContactPage, meta: { requiresLogin: false }, + }, + { + name: 'faq', path: 'faq', component: FAQPage, meta: { requiresLogin: false }, + }, + { + name: 'chatSunsetFaq', path: 'tavern-and-guilds', component: ChatSunsetFaq, meta: { requiresLogin: false }, + }, + { + name: 'features', path: 'features', component: FeaturesPage, meta: { requiresLogin: false }, + }, + { + name: 'groupPlans', path: 'group-plans', component: GroupPlansPage, meta: { requiresLogin: false }, + }, + { + name: 'home', path: 'home', component: HomePage, meta: { requiresLogin: false }, + }, + { + name: 'front', path: 'front', component: HomePage, meta: { requiresLogin: false }, + }, + { + name: 'news', path: 'new-stuff', component: NewsPage, meta: { requiresLogin: false }, + }, + { + name: 'overview', path: 'overview', component: OverviewPage, meta: { requiresLogin: false }, + }, + { + name: 'plans', path: 'plans', component: GroupPlansPage, meta: { requiresLogin: false }, + }, + { + name: 'pressKit', path: 'press-kit', component: PressKitPage, meta: { requiresLogin: false }, + }, + { + name: 'privacy', path: 'privacy', component: PrivacyPage, meta: { requiresLogin: false }, + }, + { + name: 'terms', path: 'terms', component: TermsPage, meta: { requiresLogin: false }, + }, + { + name: 'notFound', path: 'not-found', component: NotFoundPage, meta: { requiresLogin: false }, + }, + ], +}; diff --git a/website/client/src/router/user-routes.js b/website/client/src/router/user-routes.js new file mode 100644 index 0000000000..bece6045f8 --- /dev/null +++ b/website/client/src/router/user-routes.js @@ -0,0 +1,71 @@ +import ParentPage from '@/components/parentPage.vue'; +import { ProfilePage } from './shared-route-imports'; + + +// Settings +const Settings = () => import(/* webpackChunkName: "settings" */'@/components/settings/index'); +const API = () => import(/* webpackChunkName: "settings" */'@/components/settings/api'); +const DataExport = () => import(/* webpackChunkName: "settings" */'@/components/settings/dataExport'); +const Notifications = () => import(/* webpackChunkName: "settings" */'@/components/settings/notifications'); +const PromoCode = () => import(/* webpackChunkName: "settings" */'@/components/settings/promoCode'); +const Site = () => import(/* webpackChunkName: "settings" */'@/components/settings/site'); +const Subscription = () => import(/* webpackChunkName: "settings" */'@/components/settings/subscription'); +const Transactions = () => import(/* webpackChunkName: "settings" */'@/components/settings/purchaseHistory'); + + +export const USER_ROUTES = { + path: '/user', + component: ParentPage, + children: [ + { name: 'stats', path: 'stats', component: ProfilePage }, + { name: 'achievements', path: 'achievements', component: ProfilePage }, + { name: 'profile', path: 'profile', component: ProfilePage }, + { + name: 'settings', + path: 'settings', + component: Settings, + children: [ + { + name: 'site', + path: 'site', + component: Site, + }, + { + name: 'api', + path: 'api', + component: API, + }, + { + name: 'dataExport', + path: 'data-export', + component: DataExport, + }, + { + name: 'promoCode', + path: 'promo-code', + component: PromoCode, + }, + { + name: 'subscription', + path: 'subscription', + component: Subscription, + }, + { + name: 'transactions', + path: 'transactions', + component: Transactions, + meta: { + privilegeNeeded: [ + 'userSupport', + ], + }, + }, + { + name: 'notifications', + path: 'notifications', + component: Notifications, + }, + ], + }, + ], +}; From d56494450734a2360d7e3e243034212f9303b3f5 Mon Sep 17 00:00:00 2001 From: Natalie L <78037386+CuriousMagpie@users.noreply.github.com> Date: Mon, 14 Aug 2023 15:37:42 -0400 Subject: [PATCH 03/39] feat(content): add August Pet Quest Bundles and Magic Hatching Potions (#14786) * feat(content): add June subscriber items * feat(content): add August pet quest bundle and magic hatching potions * fix(time): updated start time to 0800EDT * fix(content): correct start date for potions --------- Co-authored-by: Sabe Jones --- website/common/script/content/bundles.js | 2 +- .../common/script/content/constants/events.js | 10 ++++++- .../common/script/content/hatching-potions.js | 16 ++++++------ .../script/content/shop-featuredItems.js | 26 +++++++++---------- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/website/common/script/content/bundles.js b/website/common/script/content/bundles.js index 4388aca9d4..2d0d90935a 100644 --- a/website/common/script/content/bundles.js +++ b/website/common/script/content/bundles.js @@ -102,7 +102,7 @@ const bundles = { 'butterfly', ], canBuy () { - return moment().isBetween('2020-03-09', '2020-04-02'); + return moment().isBetween(EVENTS.bundle202308.start, EVENTS.bundle202308.end); }, type: 'quests', value: 7, diff --git a/website/common/script/content/constants/events.js b/website/common/script/content/constants/events.js index b38991944d..41dafd0ad2 100644 --- a/website/common/script/content/constants/events.js +++ b/website/common/script/content/constants/events.js @@ -11,10 +11,18 @@ const gemsPromo = { export const EVENTS = { noEvent: { start: '2023-08-01T23:59-04:00', - end: '2023-08-31T08:00-04:00', + end: '2023-08-10T08:00-04:00', season: 'normal', npcImageSuffix: '', }, + bundle202308: { + start: '2023-08-15T08:00-04:00', + end: '2023-08-31T23:59-04:00', + }, + potions202308: { + start: '2023-08-15T08:00-04:00', + end: '2023-08-31T23:59-04:00', + }, summer2023: { start: '2023-06-20T08:00-04:00', end: '2023-07-31T23:59-04:00', diff --git a/website/common/script/content/hatching-potions.js b/website/common/script/content/hatching-potions.js index ae08346c4f..9d1cee99c1 100644 --- a/website/common/script/content/hatching-potions.js +++ b/website/common/script/content/hatching-potions.js @@ -140,13 +140,13 @@ const premium = { value: 2, text: t('hatchingPotionThunderstorm'), limited: true, - event: EVENTS.bundle202211, + event: EVENTS.potions202308, _addlNotes: t('eventAvailabilityReturning', { - availableDate: t('dateEndNovember'), - previousDate: t('novemberYYYY', { year: 2021 }), + availableDate: t('dateEndAugust'), + previousDate: t('novemberYYYY', { year: 2022 }), }), canBuy () { - return moment().isBetween(EVENTS.bundle202211.start, EVENTS.bundle202211.end); + return moment().isBetween(EVENTS.potions202308.start, EVENTS.potions202308.end); }, }, Spooky: { @@ -542,13 +542,13 @@ const premium = { value: 2, text: t('hatchingPotionPorcelain'), limited: true, - event: EVENTS.birthday10, + event: EVENTS.potions202308, _addlNotes: t('eventAvailabilityReturning', { - availableDate: t('dateStartFebruary'), - previousDate: t('augustYYYY', { year: 2022 }), + availableDate: t('dateStartAugust'), + previousDate: t('februaryYYYY', { year: 2022 }), }), canBuy () { - return moment().isBetween(EVENTS.birthday10.start, EVENTS.birthday10.end); + return moment().isBetween(EVENTS.potions202308.start, EVENTS.potions202308.end); }, }, PinkMarble: { diff --git a/website/common/script/content/shop-featuredItems.js b/website/common/script/content/shop-featuredItems.js index 965ce7e987..3219ce9592 100644 --- a/website/common/script/content/shop-featuredItems.js +++ b/website/common/script/content/shop-featuredItems.js @@ -5,7 +5,7 @@ import { EVENTS } from './constants'; // path: 'premiumHatchingPotions.Rainbow', const featuredItems = { market () { - if (moment().isBetween(EVENTS.summer2023.start, EVENTS.summer2023.end)) { + if (moment().isBetween(EVENTS.potions202308.start, EVENTS.potions202308.end)) { return [ { type: 'armoire', @@ -13,15 +13,15 @@ const featuredItems = { }, { type: 'premiumHatchingPotion', - path: 'premiumHatchingPotions.Sunset', + path: 'premiumHatchingPotions.Thunderstorm', }, { type: 'premiumHatchingPotion', - path: 'premiumHatchingPotions.Glass', + path: 'premiumHatchingPotions.Porcelain', }, { - type: 'premiumHatchingPotion', - path: 'premiumHatchingPotions.SandSculpture', + type: 'hatchingPotions', + path: 'hatchingPotions.Zombie', }, ]; } @@ -32,32 +32,32 @@ const featuredItems = { }, { type: 'food', - path: 'food.Honey', + path: 'food.Meat', }, { type: 'hatchingPotions', - path: 'hatchingPotions.Golden', + path: 'hatchingPotions.Zombie', }, { type: 'eggs', - path: 'eggs.Dragon', + path: 'eggs.Fox', }, ]; }, quests () { - if (moment().isBetween(EVENTS.bundle202306.start, EVENTS.bundle202306.end)) { + if (moment().isBetween(EVENTS.bundle202308.start, EVENTS.bundle202308.end)) { return [ { type: 'bundles', - path: 'bundles.splashyPals', + path: 'bundles.hugabug', }, { type: 'quests', - path: 'quests.harpy', + path: 'quests.octopus', }, { type: 'quests', - path: 'quests.owl', + path: 'quests.rock', }, ]; } @@ -89,7 +89,7 @@ const featuredItems = { }, { type: 'quests', - path: 'quests.nudibranch', + path: 'quests.axolotl', }, ]; }, From a6792a4f08335c77cfa8e23dbd221a1032516c33 Mon Sep 17 00:00:00 2001 From: SabreCat Date: Mon, 14 Aug 2023 14:36:49 -0500 Subject: [PATCH 04/39] 5.1.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 591fecb9d4..5aed2314cc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "habitica", - "version": "5.1.0", + "version": "5.1.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 641249e44f..074985daad 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "habitica", "description": "A habit tracker app which treats your goals like a Role Playing Game.", - "version": "5.1.0", + "version": "5.1.1", "main": "./website/server/index.js", "dependencies": { "@babel/core": "^7.22.5", From bf0e640fa645dcfd544814115b644e525e320076 Mon Sep 17 00:00:00 2001 From: SabreCat Date: Tue, 15 Aug 2023 14:33:32 -0500 Subject: [PATCH 05/39] fix(parties): actual 30 not 29 --- test/api/v3/integration/groups/POST-groups_invite.test.js | 4 ++-- website/common/script/constants.js | 2 +- website/server/models/group.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/api/v3/integration/groups/POST-groups_invite.test.js b/test/api/v3/integration/groups/POST-groups_invite.test.js index 0001e09e3a..aab4c50a27 100644 --- a/test/api/v3/integration/groups/POST-groups_invite.test.js +++ b/test/api/v3/integration/groups/POST-groups_invite.test.js @@ -7,7 +7,7 @@ import { } from '../../../../helpers/api-integration/v3'; const INVITES_LIMIT = 100; -const PARTY_LIMIT_MEMBERS = 29; +const PARTY_LIMIT_MEMBERS = 30; const MAX_EMAIL_INVITES_BY_USER = 200; describe('Post /groups/:groupId/invite', () => { @@ -571,7 +571,7 @@ describe('Post /groups/:groupId/invite', () => { .to.eventually.be.rejected.and.eql({ code: 400, error: 'BadRequest', - message: t('partyExceedsMembersLimit', { maxMembersParty: PARTY_LIMIT_MEMBERS + 1 }), + message: t('partyExceedsMembersLimit', { maxMembersParty: PARTY_LIMIT_MEMBERS }), }); }).timeout(10000); }); diff --git a/website/common/script/constants.js b/website/common/script/constants.js index b3510378e0..bc569da079 100644 --- a/website/common/script/constants.js +++ b/website/common/script/constants.js @@ -27,7 +27,7 @@ export const SUPPORTED_SOCIAL_NETWORKS = [ export const GUILDS_PER_PAGE = 30; // number of guilds to return per page when using pagination -export const PARTY_LIMIT_MEMBERS = 29; +export const PARTY_LIMIT_MEMBERS = 30; export const MINIMUM_PASSWORD_LENGTH = 8; export const MAXIMUM_PASSWORD_LENGTH = 64; diff --git a/website/server/models/group.js b/website/server/models/group.js index c41aa0320b..14ff572c84 100644 --- a/website/server/models/group.js +++ b/website/server/models/group.js @@ -471,7 +471,7 @@ schema.statics.validateInvitations = async function getInvitationErr (invites, r memberCount += totalInvites; if (memberCount > shared.constants.PARTY_LIMIT_MEMBERS) { - throw new BadRequest(res.t('partyExceedsMembersLimit', { maxMembersParty: shared.constants.PARTY_LIMIT_MEMBERS + 1 })); + throw new BadRequest(res.t('partyExceedsMembersLimit', { maxMembersParty: shared.constants.PARTY_LIMIT_MEMBERS })); } } }; From 8f64afe9df5803c3215a282051fa25570c5dfb3a Mon Sep 17 00:00:00 2001 From: SabreCat Date: Tue, 15 Aug 2023 14:54:22 -0500 Subject: [PATCH 06/39] fix(challenges): leave chal from invalid group --- website/server/controllers/api-v3/challenges.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/website/server/controllers/api-v3/challenges.js b/website/server/controllers/api-v3/challenges.js index 109422080c..150293c1ed 100644 --- a/website/server/controllers/api-v3/challenges.js +++ b/website/server/controllers/api-v3/challenges.js @@ -577,11 +577,13 @@ api.getChallenge = { const group = await Group.getGroup({ user, groupId: challenge.group, fields: `${basicGroupFields} purchased`, optionalMembership: true, }); - if (!group || !challenge.canView(user, group)) throw new NotFound(res.t('challengeNotFound')); - group.purchased = undefined; - + if (!group && !challenge.canView(user, group)) throw new NotFound(res.t('challengeNotFound')); const chalRes = challenge.toJSON(); - chalRes.group = group.toJSON({ minimize: true }); + if (group) { + group.purchased = undefined; + chalRes.group = group.toJSON({ minimize: true }); + } + // Instead of populate we make a find call manually because of https://github.com/Automattic/mongoose/issues/3833 const chalLeader = await User.findById(chalRes.leader).select(nameFields).exec(); chalRes.leader = chalLeader ? chalLeader.toJSON({ minimize: true }) : null; From 1ea954ab10afb7c8061e8009b7f5d12d406de4b1 Mon Sep 17 00:00:00 2001 From: SabreCat Date: Tue, 15 Aug 2023 15:21:28 -0500 Subject: [PATCH 07/39] fix(challenge): don't pierce privacy on GET/:id --- website/server/controllers/api-v3/challenges.js | 2 +- website/server/models/challenge.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/website/server/controllers/api-v3/challenges.js b/website/server/controllers/api-v3/challenges.js index 150293c1ed..7db05352c2 100644 --- a/website/server/controllers/api-v3/challenges.js +++ b/website/server/controllers/api-v3/challenges.js @@ -575,7 +575,7 @@ api.getChallenge = { // Fetching basic group data const group = await Group.getGroup({ - user, groupId: challenge.group, fields: `${basicGroupFields} purchased`, optionalMembership: true, + user, groupId: challenge.group, fields: `${basicGroupFields} purchased`, }); if (!group && !challenge.canView(user, group)) throw new NotFound(res.t('challengeNotFound')); const chalRes = challenge.toJSON(); diff --git a/website/server/models/challenge.js b/website/server/models/challenge.js index 73092238cf..e5a7814558 100644 --- a/website/server/models/challenge.js +++ b/website/server/models/challenge.js @@ -93,6 +93,7 @@ schema.methods.canModify = function canModifyChallenge (user) { schema.methods.canJoin = function canJoinChallenge (user, group) { // for when leader has left private group that contains the challenge if (this.isLeader(user)) return true; + if (!group) return false; if (group.type === 'guild' && group.privacy === 'public') { return group._id === TAVERN_ID; } From 50cc7ee09a538123b4b6aa0d61bc9d57957429ee Mon Sep 17 00:00:00 2001 From: SabreCat Date: Tue, 15 Aug 2023 15:48:30 -0500 Subject: [PATCH 08/39] fix(profile): skip redundant navigation --- website/client/src/components/memberDetails.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/client/src/components/memberDetails.vue b/website/client/src/components/memberDetails.vue index 844e599935..e59ad25587 100644 --- a/website/client/src/components/memberDetails.vue +++ b/website/client/src/components/memberDetails.vue @@ -270,6 +270,9 @@ export default { methods: { percent, showMemberModal (member) { + if (this.$route.name === 'userProfile' && this.$route.params?.userId === member._id) { + return; + } this.$router.push({ name: 'userProfile', params: { userId: member._id } }); }, }, From faa7ff632820001b5820fe72a2d877f82e7778ae Mon Sep 17 00:00:00 2001 From: SabreCat Date: Tue, 15 Aug 2023 15:51:10 -0500 Subject: [PATCH 09/39] 5.1.2 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5aed2314cc..648087fb58 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "habitica", - "version": "5.1.1", + "version": "5.1.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 074985daad..72d445ad8c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "habitica", "description": "A habit tracker app which treats your goals like a Role Playing Game.", - "version": "5.1.1", + "version": "5.1.2", "main": "./website/server/index.js", "dependencies": { "@babel/core": "^7.22.5", From c9395ba1ca23146549165b1aa6d03490cf10df57 Mon Sep 17 00:00:00 2001 From: SabreCat Date: Wed, 16 Aug 2023 15:01:41 -0500 Subject: [PATCH 10/39] fix(strings): patch up Orb, quests, potions --- website/common/locales/en/questsContent.json | 2 +- website/common/locales/en/rebirth.json | 2 +- website/common/script/content/hatching-potions.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/website/common/locales/en/questsContent.json b/website/common/locales/en/questsContent.json index fdde384328..fadd710442 100644 --- a/website/common/locales/en/questsContent.json +++ b/website/common/locales/en/questsContent.json @@ -689,7 +689,7 @@ "dysheartenerArtCredit": "Artwork by @AnnDeLune", "hugabugText": "Hug a Bug Quest Bundle", - "hugabugNotes": "Contains 'The CRITICAL BUG,' 'The Snail of Drudgery Sludge,' and 'Bye, Bye, Butterfry.' Available until March 31.", + "hugabugNotes": "Contains 'The CRITICAL BUG,' 'The Snail of Drudgery Sludge,' and 'Bye, Bye, Butterfry.' Available until August 31.", "questSquirrelText": "The Sneaky Squirrel", "questSquirrelNotes": "You wake up and find you’ve overslept! Why didn’t your alarm go off? … How did an acorn get stuck in the ringer?

When you try to make breakfast, the toaster is stuffed with acorns. When you go to retrieve your mount, @Shtut is there, trying unsuccessfully to unlock their stable. They look into the keyhole. “Is that an acorn in there?”

@randomdaisy cries out, “Oh no! I knew my pet squirrels had gotten out, but I didn’t know they’d made such trouble! Can you help me round them up before they make any more of a mess?”

Following the trail of mischievously placed oak nuts, you track and catch the wayward sciurines, with @Cantras helping secure each one safely at home. But just when you think your task is almost complete, an acorn bounces off your helm! You look up to see a mighty beast of a squirrel, crouched in defense of a prodigious pile of seeds.

“Oh dear,” says @randomdaisy, softly. “She’s always been something of a resource guarder. We’ll have to proceed very carefully!” You circle up with your party, ready for trouble!", diff --git a/website/common/locales/en/rebirth.json b/website/common/locales/en/rebirth.json index 4031482136..906d8b4627 100644 --- a/website/common/locales/en/rebirth.json +++ b/website/common/locales/en/rebirth.json @@ -8,7 +8,7 @@ "rebirthOrb": "Used an Orb of Rebirth to start over after attaining Level <%= level %>.", "rebirthOrb100": "Used an Orb of Rebirth to start over after attaining Level 100 or higher.", "rebirthOrbNoLevel": "Used an Orb of Rebirth to start over.", - "rebirthPop": "Instantly restart your character as a Level 1 Warrior while retaining achievements, collectibles, and equipment. Your tasks and their history will remain but they will be reset to yellow. Your streaks will be removed except from tasks belonging to active Challenges and Group Plans. Your Gold, Experience, Mana, and the effects of all Skills will be removed. All of this will take effect immediately. For more information, see the wiki's Orb of Rebirth page.", + "rebirthPop": "Instantly restart your character as a Level 1 Warrior while retaining achievements, collectibles, and equipment. Your tasks and their history will remain but they will be reset to yellow. Your streaks will be removed except from tasks belonging to active Challenges and Group Plans. Your Gold, Experience, Mana, and the effects of all Skills will be removed. All of this will take effect immediately.", "rebirthName": "Orb of Rebirth", "rebirthComplete": "You have been reborn!", "nextFreeRebirth": "<%= days %> days until FREE Orb of Rebirth" diff --git a/website/common/script/content/hatching-potions.js b/website/common/script/content/hatching-potions.js index 9d1cee99c1..bd826e5d71 100644 --- a/website/common/script/content/hatching-potions.js +++ b/website/common/script/content/hatching-potions.js @@ -544,7 +544,7 @@ const premium = { limited: true, event: EVENTS.potions202308, _addlNotes: t('eventAvailabilityReturning', { - availableDate: t('dateStartAugust'), + availableDate: t('dateEndAugust'), previousDate: t('februaryYYYY', { year: 2022 }), }), canBuy () { From 04dcb275016e9fc2faca01088a1b8bda5bd0b7ec Mon Sep 17 00:00:00 2001 From: SabreCat Date: Wed, 16 Aug 2023 15:01:54 -0500 Subject: [PATCH 11/39] 5.1.3 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 648087fb58..c36fc104b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "habitica", - "version": "5.1.2", + "version": "5.1.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 72d445ad8c..2f6bddf2c2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "habitica", "description": "A habit tracker app which treats your goals like a Role Playing Game.", - "version": "5.1.2", + "version": "5.1.3", "main": "./website/server/index.js", "dependencies": { "@babel/core": "^7.22.5", From 58d58ff9625d867ec25c23e110e9be9cba5ac6bf Mon Sep 17 00:00:00 2001 From: SabreCat Date: Wed, 16 Aug 2023 15:56:10 -0500 Subject: [PATCH 12/39] fix(guilds): correct various errors --- website/client/src/components/avatar.vue | 37 ++++++++++++------- .../components/challenges/groupChallenges.vue | 2 +- .../src/components/chat/chatMessages.vue | 4 +- .../header/notifications/guildInvitation.vue | 2 +- website/server/controllers/api-v3/tasks.js | 5 +-- 5 files changed, 29 insertions(+), 21 deletions(-) diff --git a/website/client/src/components/avatar.vue b/website/client/src/components/avatar.vue index 3317772105..cf28966c02 100644 --- a/website/client/src/components/avatar.vue +++ b/website/client/src/components/avatar.vue @@ -1,5 +1,6 @@