diff --git a/habitica-images b/habitica-images index d66a5ea922..e8f76ad308 160000 --- a/habitica-images +++ b/habitica-images @@ -1 +1 @@ -Subproject commit d66a5ea922d91815d4419b718ff38a80e11667f7 +Subproject commit e8f76ad308e256fb65306cfe880cabdc98c818cd diff --git a/migrations/archive/2022/20221213_pet_group_achievements.js b/migrations/archive/2022/20221213_pet_group_achievements.js new file mode 100644 index 0000000000..5bf2079b5e --- /dev/null +++ b/migrations/archive/2022/20221213_pet_group_achievements.js @@ -0,0 +1,108 @@ +/* eslint-disable no-console */ +const MIGRATION_NAME = '20221213_pet_group_achievements'; +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.items && user.items.pets) { + const pets = user.items.pets; + if (pets['BearCub-Base'] + && pets['BearCub-CottonCandyBlue'] + && pets['BearCub-CottonCandyPink'] + && pets['BearCub-Desert'] + && pets['BearCub-Golden'] + && pets['BearCub-Red'] + && pets['BearCub-Shade'] + && pets['BearCub-Skeleton'] + && pets['BearCub-White'] + && pets['BearCub-Zombie'] + && pets['Fox-Base'] + && pets['Fox-CottonCandyBlue'] + && pets['Fox-CottonCandyPink'] + && pets['Fox-Desert'] + && pets['Fox-Golden'] + && pets['Fox-Red'] + && pets['Fox-Shade'] + && pets['Fox-Skeleton'] + && pets['Fox-White'] + && pets['Fox-Zombie'] + && pets['Penguin-Base'] + && pets['Penguin-CottonCandyBlue'] + && pets['Penguin-CottonCandyPink'] + && pets['Penguin-Desert'] + && pets['Penguin-Golden'] + && pets['Penguin-Red'] + && pets['Penguin-Shade'] + && pets['Penguin-Skeleton'] + && pets['Penguin-White'] + && pets['Penguin-Zombie'] + && pets['Whale-Base'] + && pets['Whale-CottonCandyBlue'] + && pets['Whale-CottonCandyPink'] + && pets['Whale-Desert'] + && pets['Whale-Golden'] + && pets['Whale-Red'] + && pets['Whale-Shade'] + && pets['Whale-Skeleton'] + && pets['Whale-White'] + && pets['Whale-Zombie'] + && pets['Wolf-Base'] + && pets['Wolf-CottonCandyBlue'] + && pets['Wolf-CottonCandyPink'] + && pets['Wolf-Desert'] + && pets['Wolf-Golden'] + && pets['Wolf-Red'] + && pets['Wolf-Shade'] + && pets['Wolf-Skeleton'] + && pets['Wolf-White'] + && pets['Wolf-Zombie'] { + set['achievements.polarPro'] = true; + } + } + + if (count % progressCount === 0) console.warn(`${count} ${user._id}`); + + return await User.update({ _id: user._id }, { $set: set }).exec(); +} + +export default async function processUsers () { + let query = { + // migration: { $ne: MIGRATION_NAME }, + 'auth.timestamps.loggedin': { $gt: new Date('2022-11-01') }, + }; + + const fields = { + _id: 1, + items: 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 + } +}; diff --git a/package-lock.json b/package-lock.json index ff6e486f6f..b541922bd8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "habitica", - "version": "4.251.0", + "version": "4.253.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 639747324f..953ce21b8f 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": "4.251.0", + "version": "4.253.0", "main": "./website/server/index.js", "dependencies": { "@babel/core": "^7.20.5", diff --git a/test/api/v3/integration/user/auth/PUT-user_update_password.test.js b/test/api/v3/integration/user/auth/PUT-user_update_password.test.js index 94fbd4f3e2..4ccfef0c5a 100644 --- a/test/api/v3/integration/user/auth/PUT-user_update_password.test.js +++ b/test/api/v3/integration/user/auth/PUT-user_update_password.test.js @@ -96,6 +96,20 @@ describe('PUT /user/auth/update-password', async () => { }); }); + it('returns an error when newPassword is too long', async () => { + const body = { + password, + newPassword: '12345678910111213141516171819202122232425262728293031323334353637383940', + confirmPassword: '12345678910111213141516171819202122232425262728293031323334353637383940', + }; + + await expect(user.put(ENDPOINT, body)).to.eventually.be.rejected.and.eql({ + code: 400, + error: 'BadRequest', + message: t('invalidReqParams'), + }); + }); + it('returns an error when confirmPassword is missing', async () => { const body = { password, diff --git a/website/client/src/assets/css/sprites/spritesmith-main.css b/website/client/src/assets/css/sprites/spritesmith-main.css index 4302329360..1f4657bda7 100644 --- a/website/client/src/assets/css/sprites/spritesmith-main.css +++ b/website/client/src/assets/css/sprites/spritesmith-main.css @@ -293,6 +293,11 @@ width: 48px; height: 52px; } +.achievement-polarPro2x { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/achievement-polarPro2x.png'); + width: 68px; + height: 68px; +} .achievement-primedForPainting2x { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/achievement-primedForPainting2x.png'); width: 48px; @@ -31275,6 +31280,26 @@ width: 117px; height: 120px; } +.broad_armor_special_winter2023Healer { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_special_winter2023Healer.png'); + width: 117px; + height: 120px; +} +.broad_armor_special_winter2023Mage { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_special_winter2023Mage.png'); + width: 114px; + height: 90px; +} +.broad_armor_special_winter2023Rogue { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_special_winter2023Rogue.png'); + width: 116px; + height: 119px; +} +.broad_armor_special_winter2023Warrior { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_special_winter2023Warrior.png'); + width: 114px; + height: 117px; +} .broad_armor_special_yeti { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_special_yeti.png'); width: 90px; @@ -31500,6 +31525,26 @@ width: 117px; height: 120px; } +.head_special_winter2023Healer { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_special_winter2023Healer.png'); + width: 117px; + height: 120px; +} +.head_special_winter2023Mage { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_special_winter2023Mage.png'); + width: 114px; + height: 90px; +} +.head_special_winter2023Rogue { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_special_winter2023Rogue.png'); + width: 116px; + height: 119px; +} +.head_special_winter2023Warrior { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_special_winter2023Warrior.png'); + width: 114px; + height: 117px; +} .head_special_yeti { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_special_yeti.png'); width: 90px; @@ -31635,6 +31680,21 @@ width: 117px; height: 120px; } +.shield_special_winter2023Healer { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shield_special_winter2023Healer.png'); + width: 117px; + height: 120px; +} +.shield_special_winter2023Rogue { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shield_special_winter2023Rogue.png'); + width: 116px; + height: 119px; +} +.shield_special_winter2023Warrior { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shield_special_winter2023Warrior.png'); + width: 114px; + height: 117px; +} .shield_special_yeti { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shield_special_yeti.png'); width: 90px; @@ -31815,6 +31875,26 @@ width: 68px; height: 68px; } +.shop_armor_special_winter2023Healer { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_armor_special_winter2023Healer.png'); + width: 68px; + height: 68px; +} +.shop_armor_special_winter2023Mage { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_armor_special_winter2023Mage.png'); + width: 68px; + height: 68px; +} +.shop_armor_special_winter2023Rogue { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_armor_special_winter2023Rogue.png'); + width: 68px; + height: 68px; +} +.shop_armor_special_winter2023Warrior { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_armor_special_winter2023Warrior.png'); + width: 68px; + height: 68px; +} .shop_armor_special_yeti { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_armor_special_yeti.png'); width: 68px; @@ -32040,6 +32120,26 @@ width: 68px; height: 68px; } +.shop_head_special_winter2023Healer { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_head_special_winter2023Healer.png'); + width: 68px; + height: 68px; +} +.shop_head_special_winter2023Mage { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_head_special_winter2023Mage.png'); + width: 68px; + height: 68px; +} +.shop_head_special_winter2023Rogue { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_head_special_winter2023Rogue.png'); + width: 68px; + height: 68px; +} +.shop_head_special_winter2023Warrior { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_head_special_winter2023Warrior.png'); + width: 68px; + height: 68px; +} .shop_head_special_yeti { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_head_special_yeti.png'); width: 68px; @@ -32175,6 +32275,21 @@ width: 68px; height: 68px; } +.shop_shield_special_winter2023Healer { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_shield_special_winter2023Healer.png'); + width: 68px; + height: 68px; +} +.shop_shield_special_winter2023Rogue { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_shield_special_winter2023Rogue.png'); + width: 68px; + height: 68px; +} +.shop_shield_special_winter2023Warrior { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_shield_special_winter2023Warrior.png'); + width: 68px; + height: 68px; +} .shop_shield_special_yeti { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_shield_special_yeti.png'); width: 68px; @@ -32355,6 +32470,26 @@ width: 68px; height: 68px; } +.shop_weapon_special_winter2023Healer { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_weapon_special_winter2023Healer.png'); + width: 68px; + height: 68px; +} +.shop_weapon_special_winter2023Mage { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_weapon_special_winter2023Mage.png'); + width: 68px; + height: 68px; +} +.shop_weapon_special_winter2023Rogue { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_weapon_special_winter2023Rogue.png'); + width: 68px; + height: 68px; +} +.shop_weapon_special_winter2023Warrior { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_weapon_special_winter2023Warrior.png'); + width: 68px; + height: 68px; +} .shop_weapon_special_yeti { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_weapon_special_yeti.png'); width: 68px; @@ -32535,6 +32670,26 @@ width: 117px; height: 120px; } +.slim_armor_special_winter2023Healer { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_special_winter2023Healer.png'); + width: 117px; + height: 120px; +} +.slim_armor_special_winter2023Mage { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_special_winter2023Mage.png'); + width: 114px; + height: 90px; +} +.slim_armor_special_winter2023Rogue { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_special_winter2023Rogue.png'); + width: 116px; + height: 119px; +} +.slim_armor_special_winter2023Warrior { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_special_winter2023Warrior.png'); + width: 114px; + height: 117px; +} .slim_armor_special_yeti { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_special_yeti.png'); width: 90px; @@ -32715,6 +32870,26 @@ width: 117px; height: 120px; } +.weapon_special_winter2023Healer { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/weapon_special_winter2023Healer.png'); + width: 117px; + height: 120px; +} +.weapon_special_winter2023Mage { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/weapon_special_winter2023Mage.png'); + width: 114px; + height: 90px; +} +.weapon_special_winter2023Rogue { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/weapon_special_winter2023Rogue.png'); + width: 116px; + height: 119px; +} +.weapon_special_winter2023Warrior { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/weapon_special_winter2023Warrior.png'); + width: 114px; + height: 117px; +} .weapon_special_yeti { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/weapon_special_yeti.png'); width: 90px; diff --git a/website/common/locales/en/achievements.json b/website/common/locales/en/achievements.json index b4b577280b..ad43c35688 100644 --- a/website/common/locales/en/achievements.json +++ b/website/common/locales/en/achievements.json @@ -141,5 +141,8 @@ "achievementWoodlandWizardModalText": "You collected all the forest pets!", "achievementBoneToPick": "Bone to Pick", "achievementBoneToPickText": "Has hatched all the Classic and Quest Skeleton Pets!", - "achievementBoneToPickModalText": "You collected all the Classic and Quest Skeleton Pets!" + "achievementBoneToPickModalText": "You collected all the Classic and Quest Skeleton Pets!", + "achievementPolarPro": "Polar Pro", + "achievementPolarProText": "Has hatched all Polar pets: Bear, Fox, Penguin, Whale, and Wolf!", + "achievementPolarProModalText": "You collected all the Polar Pets!" } diff --git a/website/common/locales/en/gear.json b/website/common/locales/en/gear.json index 766e6754ef..d78ac5111c 100644 --- a/website/common/locales/en/gear.json +++ b/website/common/locales/en/gear.json @@ -456,6 +456,15 @@ "weaponSpecialFall2022HealerText": "Right Peeker Eye", "weaponSpecialFall2022HealerNotes": "To claim victory, hold it forth and utter the words of command: 'Eye One!' Increases Intelligence by <%= int %>. Limited Edition 2022 Fall Gear.", + "weaponSpecialWinter2023RogueText": "Green Satin Sash", + "weaponSpecialWinter2023RogueNotes": "Legends tell of Rogues who snare their opponents' weapons, disarm them, then gift the item back just to be cute. Incrases Strength by <%= str %>. Limited Edition 2022-2023 Winter Gear.", + "weaponSpecialWinter2023WarriorText": "Tusk Spear", + "weaponSpecialWinter2023WarriorNotes": "The two prongs of this spear are shaped like walrus tusks but are twice as powerful. Jab at doubts and at silly poems until they back off! Increases Strength by <%= str %>. Limited Edition 2022-2023 Winter Gear.", + "weaponSpecialWinter2023MageText": "Foxfire", + "weaponSpecialWinter2023MageNotes": "Neither fox nor fire, but plenty festive! Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2022-2023 Winter Gear.", + "weaponSpecialWinter2023HealerText": "Throwing Wreath", + "weaponSpecialWinter2023HealerNotes": "Watch this festive, prickly wreath spin through the air toward your enemy or obstacles and return to you like a boomerang for another throw. Increases Intelligence by <%= int %>. Limited Edition 2022-2023 Winter Gear.", + "weaponMystery201411Text": "Pitchfork of Feasting", "weaponMystery201411Notes": "Stab your enemies or dig in to your favorite foods - this versatile pitchfork does it all! Confers no benefit. November 2014 Subscriber Item.", "weaponMystery201502Text": "Shimmery Winged Staff of Love and Also Truth", @@ -1109,6 +1118,15 @@ "armorSpecialFall2022HealerText": "Profusion of Peeker Pods", "armorSpecialFall2022HealerNotes": "How many peeps could a Peeker peep, if a Peeker could peep peeps? Increases Constitution by <%= con %>. Limited Edition 2022 Fall Gear.", + "armorSpecialWinter2023RogueText": "Ribbon Wrap", + "armorSpecialWinter2023RogueNotes": "Obtain items. Bundle them up in pretty paper. And give them to your local Rogue! The season demands it. Increases Perception by <%= per %>. Limited Edition 2022-2023 Winter Gear.", + "armorSpecialWinter2023WarriorText": "Walrus Suit", + "armorSpecialWinter2023WarriorNotes": "This tough walrus suit is perfect for a walk along a beach in the middle of the night. Increases Constitution by <%= con %>. Limited Edition 2022-2023 Winter Gear.", + "armorSpecialWinter2023MageText": "Fairy Light Gown", + "armorSpecialWinter2023MageNotes": "Just because you have lights on, that doesn't make you a tree! ...maybe some other year. Increases Intelligence by <%= int %>. Limited Edition 2022-2023 Winter Gear.", + "armorSpecialWinter2023HealerText": "Cardinal Suit", + "armorSpecialWinter2023HealerNotes": "This bright cardinal suit is perfect for flying high above your problems. Increases Constitution by <%= con %>. Limited Edition 2022-2023 Winter Gear.", + "armorMystery201402Text": "Messenger Robes", "armorMystery201402Notes": "Shimmering and strong, these robes have many pockets to carry letters. Confers no benefit. February 2014 Subscriber Item.", "armorMystery201403Text": "Forest Walker Armor", @@ -1835,6 +1853,15 @@ "headSpecialFall2022MageNotes": "Entrance and lure others close with this magical maiden mask. Increases Perception by <%= per %>. Limited Edition 2022 Fall Gear.", "headSpecialFall2022HealerText": "Peeker Mask", "headSpecialFall2022HealerNotes": "Beauty is in there. Somewhere! Increases Intelligence by <%= int %>. Limited Edition 2022 Fall Gear.", + + "headSpecialWinter2023RogueText": "Gift Bow", + "headSpecialWinter2023RogueNotes": "People's temptations to “unwrap” your hair will give you opportunities to practice your ducks and dodges. Increases Perception by <%= per %>. Limited Edition 2022-2023 Winter Gear.", + "headSpecialWinter2023WarriorText": "Walrus Helm", + "headSpecialWinter2023WarriorNotes": "This walrus helm is perfect for chatting with a friend or partaking in a clever meal. Increases Strength by <%= str %>. Limited Edition 2022-2023 Winter Gear.", + "headSpecialWinter2023MageText": "Fairy-Lit Tiara", + "headSpecialWinter2023MageNotes": "Were you hatched with a Starry Night potion? Because I've got stars in my eyes for you. Increases Perception by <%= per %>. Limited Edition 2022-2023 Winter Gear.", + "headSpecialWinter2023HealerText": "Cardinal Helm", + "headSpecialWinter2023HealerNotes": "This cardinal helm is perfect for whistling and singing to herald the winter season. Increases Intelligence by <%= int %>. Limited Edition 2022-2023 Winter Gear.", "headSpecialGaymerxText": "Rainbow Warrior Helm", "headSpecialGaymerxNotes": "In celebration of the GaymerX Conference, this special helmet is decorated with a radiant, colorful rainbow pattern! GaymerX is a game convention celebrating LGTBQ and gaming and is open to everyone.", @@ -2396,6 +2423,11 @@ "shieldSpecialFall2022HealerText": "Left Peeker Eye", "shieldSpecialFall2022HealerNotes": "Eye Two, look upon this costume and tremble. Increases Constitution by <%= con %>. Limited Edition 2022 Fall Gear.", + "shieldSpecialWinter2023WarriorText": "Oyster Shield", + "shieldSpecialWinter2023WarriorNotes": "The time has come, the Walrus said, to talk of many things: of oyster shells—and winter bells—of songs that someone sings—and where this shield’s pearl has gone—or what the new year brings! Increases Constitution by <%= con %>. Limited Edition 2022-2023 Winter Gear.", + "shieldSpecialWinter2023HealerText": "Cool Jams", + "shieldSpecialWinter2023HealerNotes": "Your song of frost and snow will soothe the spirits of all who hear. Increases Constitution by <%= con %>. Limited Edition 2022-2023 Winter Gear.", + "shieldMystery201601Text": "Resolution Slayer", "shieldMystery201601Notes": "This blade can be used to parry away all distractions. Confers no benefit. January 2016 Subscriber Item.", "shieldMystery201701Text": "Time-Freezer Shield", diff --git a/website/common/locales/en/limited.json b/website/common/locales/en/limited.json index 658227ca49..5e7e96b345 100644 --- a/website/common/locales/en/limited.json +++ b/website/common/locales/en/limited.json @@ -191,6 +191,10 @@ "fall2022OrcWarriorSet": "Orc (Warrior)", "fall2022HarpyMageSet": "Harpy (Mage)", "fall2022WatcherHealerSet": "Peeker (Healer)", + "winter2023WalrusWarriorSet": "Walrus (Warrior)", + "winter2023FairyLightsMageSet": "Fairy Lights (Mage)", + "winter2023CardinalHealerSet": "Cardinal (Healer)", + "spring2023RibbonRogueSet": "Ribbon (Rogue)", "eventAvailability": "Available for purchase until <%= date(locale) %>.", "eventAvailabilityReturning": "Available for purchase until <%= availableDate(locale) %>. This potion was last available in <%= previousDate(locale) %>.", "dateEndJanuary": "January 31", @@ -229,7 +233,7 @@ "howItWorks": "How it Works", "g1g1HowItWorks": "Type in the username of the account you’d like to gift to. From there, pick the sub length you’d like to gift and check out. Your account will automatically be rewarded with the same level of subscription you just gifted.", "limitations": "Limitations", - "g1g1Limitations": "This is a limited time event that starts on December 16th at 8:00 AM ET (13:00 UTC) and will end January 6th at 8:00 PM ET (1:00 UTC). This promotion only applies when you gift to another Habitican. If you or your gift recipient already have a subscription, the gifted subscription will add months of credit that will only be used after the current subscription is canceled or expires.", + "g1g1Limitations": "This is a limited time event that starts on December 15th at 8:00 AM ET (13:00 UTC) and will end January 8th at 11:59 PM ET (January 9th 04:59 UTC). This promotion only applies when you gift to another Habitican. If you or your gift recipient already have a subscription, the gifted subscription will add months of credit that will only be used after the current subscription is canceled or expires.", "noLongerAvailable": "This item is no longer available.", "gemSaleHow": "Between <%= eventStartMonth %> <%= eventStartOrdinal %> and <%= eventEndOrdinal %>, simply purchase any Gem bundle like usual and your account will be credited with the promotional amount of Gems. More Gems to spend, share, or save for any future releases!", "gemSaleLimitations": "This promotion only applies during the limited time event. This event starts on <%= eventStartMonth %> <%= eventStartOrdinal %> at 8:00 AM EDT (12:00 UTC) and will end <%= eventStartMonth %> <%= eventEndOrdinal %> at 8:00 PM EDT (00:00 UTC). The promo offer is only available when buying Gems for yourself." diff --git a/website/common/script/content/achievements.js b/website/common/script/content/achievements.js index 12849bf637..f9451c33de 100644 --- a/website/common/script/content/achievements.js +++ b/website/common/script/content/achievements.js @@ -183,6 +183,11 @@ const animalSetAchievs = { titleKey: 'achievementDomesticated', textKey: 'achievementDomesticatedText', }, + polarPro: { + icon: 'achievement-polarPro', + titleKey: 'achievementPolarPro', + textKey: 'achievementPolarProText', + }, reptacularRumble: { icon: 'achievement-reptacularRumble', titleKey: 'achievementReptacularRumble', diff --git a/website/common/script/content/appearance/sets.js b/website/common/script/content/appearance/sets.js index 65152186c0..942b70f2ad 100644 --- a/website/common/script/content/appearance/sets.js +++ b/website/common/script/content/appearance/sets.js @@ -18,7 +18,7 @@ export default prefill({ setPrice: 5, availableFrom: '2022-10-04T08:00-04:00', availableUntil: EVENTS.fall2022.end, text: t('hauntedColors'), }, winteryHairColors: { - setPrice: 5, availableFrom: '2021-12-23T08:00-05:00', availableUntil: '2022-01-31T20:00-05:00', text: t('winteryColors'), + setPrice: 5, availableFrom: '2021-12-23T08:00-05:00', availableUntil: EVENTS.winter2023.end, text: t('winteryColors'), }, rainbowSkins: { setPrice: 5, text: t('rainbowSkins') }, animalSkins: { setPrice: 5, text: t('animalSkins') }, @@ -33,6 +33,6 @@ export default prefill({ setPrice: 5, availableFrom: '2022-07-05T08:00-05:00', availableUntil: EVENTS.summer2022.end, text: t('splashySkins'), }, winterySkins: { - setPrice: 5, availableFrom: '2021-12-23T08:00-05:00', availableUntil: '2022-01-31T20:00-05:00', text: t('winterySkins'), + setPrice: 5, availableFrom: '2023-01-17T08:00-05:00', availableUntil: EVENTS.winter2023.end, text: t('winterySkins'), }, }); diff --git a/website/common/script/content/bundles.js b/website/common/script/content/bundles.js index cb4e982fee..8214d474a6 100644 --- a/website/common/script/content/bundles.js +++ b/website/common/script/content/bundles.js @@ -85,8 +85,9 @@ const bundles = { 'evilsanta2', 'penguin', ], + event: EVENTS.winter2023, canBuy () { - return moment().isBetween('2022-01-11T08:00-05:00', '2022-01-31T20:00-05:00'); + return moment().isBetween(EVENTS.winter2023.start, EVENTS.winter2023.end); }, type: 'quests', value: 7, diff --git a/website/common/script/content/constants/animalSetAchievements.js b/website/common/script/content/constants/animalSetAchievements.js index 0c747a0826..51c07fabf3 100644 --- a/website/common/script/content/constants/animalSetAchievements.js +++ b/website/common/script/content/constants/animalSetAchievements.js @@ -41,6 +41,18 @@ const ANIMAL_SET_ACHIEVEMENTS = { achievementKey: 'domesticated', notificationType: 'ACHIEVEMENT_ANIMAL_SET', }, + polarPro: { + type: 'pet', + species: [ + 'BearCub', + 'Fox', + 'Penguin', + 'Whale', + 'Wolf', + ], + achievementKey: 'polarPro', + notificationType: 'ACHIEVEMENT_ANIMAL_SET', + }, reptacularRumble: { type: 'pet', species: [ diff --git a/website/common/script/content/constants/events.js b/website/common/script/content/constants/events.js index f561d44bd5..c3e8522062 100644 --- a/website/common/script/content/constants/events.js +++ b/website/common/script/content/constants/events.js @@ -10,11 +10,23 @@ const gemsPromo = { export const EVENTS = { noEvent: { - start: '2022-11-27T20:00-05:00', - end: '2022-12-20T08:00-05:00', + start: '2023-01-31T20:00-05:00', + end: '2023-02-14T08:00-05:00', season: 'normal', npcImageSuffix: '', }, + winter2023: { + start: '2022-12-20T08:00-05:00', + end: '2023-01-31T23:59-05:00', + npcImageSuffix: '_winter', + season: 'winter', + gear: true, + }, + g1g12022: { + start: '2022-12-15T08:00-05:00', + end: '2023-01-08T23:59-05:00', + promo: 'g1g1', + }, harvestFeast2022: { start: '2022-11-22T08:00-05:00', end: '2022-11-27T20:00-05:00', diff --git a/website/common/script/content/constants/seasonalSets.js b/website/common/script/content/constants/seasonalSets.js index 009ee62321..9af7043ce5 100644 --- a/website/common/script/content/constants/seasonalSets.js +++ b/website/common/script/content/constants/seasonalSets.js @@ -47,6 +47,11 @@ const SEASONAL_SETS = { 'winter2022StockingWarriorSet', 'winter2022PomegranateMageSet', 'winter2022IceCrystalHealerSet', + + 'winter2023RibbonRogueSet', + 'winter2023WalrusWarriorSet', + 'winter2023FairyLightsMageSet', + 'winter2023CardinalHealerSet', ], spring: [ // spring 2014 diff --git a/website/common/script/content/gear/sets/special/index.js b/website/common/script/content/gear/sets/special/index.js index 55f9c2d7a6..485e54ec83 100644 --- a/website/common/script/content/gear/sets/special/index.js +++ b/website/common/script/content/gear/sets/special/index.js @@ -718,27 +718,35 @@ const armor = { }, winter2022Rogue: { set: 'winter2022FireworksRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Warrior: { set: 'winter2022StockingWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Mage: { set: 'winter2022PomegranateMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Healer: { set: 'winter2022IceCrystalHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, spring2022Rogue: { set: 'spring2022MagpieRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Warrior: { set: 'spring2022RainstormWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Mage: { set: 'spring2022ForsythiaMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Healer: { set: 'spring2022PeridotHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, birthday2022: { text: t('armorSpecialBirthday2022Text'), @@ -748,27 +756,47 @@ const armor = { }, summer2022Rogue: { set: 'summer2022CrabRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Warrior: { set: 'summer2022WaterspoutWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Mage: { set: 'summer2022MantaRayMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Healer: { set: 'summer2022AngelfishHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, fall2022Rogue: { set: 'fall2022KappaRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Warrior: { set: 'fall2022OrcWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Mage: { set: 'fall2022HarpyMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Healer: { set: 'fall2022WatcherHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', + }, + winter2023Rogue: { + set: 'winter2023RibbonRogueSet', + }, + winter2023Warrior: { + set: 'winter2023WalrusWarriorSet', + }, + winter2023Mage: { + set: 'winter2023FairyLightsMageSet', + }, + winter2023Healer: { + set: 'winter2023CardinalHealerSet', }, }; @@ -1824,15 +1852,19 @@ const head = { }, winter2022Rogue: { set: 'winter2022FireworksRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Warrior: { set: 'winter2022StockingWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Mage: { set: 'winter2022PomegranateMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Healer: { set: 'winter2022IceCrystalHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, nye2021: { text: t('headSpecialNye2021Text'), @@ -1842,39 +1874,63 @@ const head = { }, spring2022Rogue: { set: 'spring2022MagpieRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Warrior: { set: 'spring2022RainstormWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Mage: { set: 'spring2022ForsythiaMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Healer: { set: 'spring2022PeridotHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, summer2022Rogue: { set: 'summer2022CrabRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Warrior: { set: 'summer2022WaterspoutWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Mage: { set: 'summer2022MantaRayMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Healer: { set: 'summer2022AngelfishHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, fall2022Rogue: { set: 'fall2022KappaRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Warrior: { set: 'fall2022OrcWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Mage: { set: 'fall2022HarpyMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Healer: { set: 'fall2022WatcherHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', + }, + winter2023Rogue: { + set: 'winter2023RibbonRogueSet', + }, + winter2023Warrior: { + set: 'winter2023WalrusWarriorSet', + }, + winter2023Mage: { + set: 'winter2023FairyLightsMageSet', + }, + winter2023Healer: { + set: 'winter2023CardinalHealerSet', }, }; @@ -2285,7 +2341,6 @@ const shield = { }, spring2015Rogue: { set: 'sneakySqueakerSet', - event: EVENTS.spring2021, canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2015Warrior: { @@ -2636,39 +2691,60 @@ const shield = { }, winter2022Rogue: { set: 'winter2022FireworksRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Warrior: { set: 'winter2022StockingWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Healer: { set: 'winter2022IceCrystalHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, spring2022Rogue: { set: 'spring2022MagpieRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Warrior: { set: 'spring2022RainstormWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Healer: { set: 'spring2022PeridotHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Rogue: { set: 'summer2022CrabRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Warrior: { set: 'summer2022WaterspoutWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Healer: { set: 'summer2022AngelfishHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, fall2022Rogue: { set: 'fall2022KappaRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Warrior: { set: 'fall2022OrcWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Healer: { set: 'fall2022WatcherHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', + }, + winter2023Rogue: { + set: 'winter2023RibbonRogueSet', + }, + winter2023Warrior: { + set: 'winter2023WalrusWarriorSet', + }, + winter2023Healer: { + set: 'winter2023CardinalHealerSet', }, }; @@ -3348,51 +3424,79 @@ const weapon = { }, winter2022Rogue: { set: 'winter2022FireworksRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Warrior: { set: 'winter2022StockingWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Mage: { set: 'winter2022PomegranateMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Healer: { set: 'winter2022IceCrystalHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, spring2022Rogue: { set: 'spring2022MagpieRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Warrior: { set: 'spring2022RainstormWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Mage: { set: 'spring2022ForsythiaMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Healer: { set: 'spring2022PeridotHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, summer2022Rogue: { set: 'summer2022CrabRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Warrior: { set: 'summer2022WaterspoutWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Mage: { set: 'summer2022MantaRayMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Healer: { set: 'summer2022AngelfishHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, fall2022Rogue: { set: 'fall2022KappaRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Warrior: { set: 'fall2022OrcWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Mage: { set: 'fall2022HarpyMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Healer: { set: 'fall2022WatcherHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', + }, + winter2023Rogue: { + set: 'winter2023RibbonRogueSet', + }, + winter2023Warrior: { + set: 'winter2023WalrusWarriorSet', + }, + winter2023Mage: { + set: 'winter2023FairyLightsMageSet', + }, + winter2023Healer: { + set: 'winter2023CardinalHealerSet', }, }; diff --git a/website/common/script/content/hatching-potions.js b/website/common/script/content/hatching-potions.js index a2e40396c2..9ba437243d 100644 --- a/website/common/script/content/hatching-potions.js +++ b/website/common/script/content/hatching-potions.js @@ -176,11 +176,11 @@ const premium = { limited: true, _addlNotes: t('eventAvailabilityReturning', { availableDate: t('dateEndJanuary'), - previousDate: t('januaryYYYY', { year: 2020 }), + previousDate: t('januaryYYYY', { year: 2022 }), }), - event: EVENTS.winter2022, + event: EVENTS.winter2023, canBuy () { - return moment().isBetween(EVENTS.winter2022.start, EVENTS.winter2022.end); + return moment().isBetween(EVENTS.winter2023.start, EVENTS.winter2023.end); }, }, Peppermint: { @@ -200,12 +200,13 @@ const premium = { value: 2, text: t('hatchingPotionStarryNight'), limited: true, + event: EVENTS.winter2023, canBuy () { - return moment().isBetween('2019-12-19', '2020-02-02'); + return moment().isBetween(EVENTS.winter2023.start, EVENTS.winter2023.end); }, _addlNotes: t('eventAvailabilityReturning', { availableDate: t('dateEndJanuary'), - previousDate: t('decemberYYYY', { year: 2017 }), + previousDate: t('decemberYYYY', { year: 2019 }), }), }, Rainbow: { @@ -360,11 +361,11 @@ const premium = { limited: true, _addlNotes: t('eventAvailabilityReturning', { availableDate: t('dateEndJanuary'), - previousDate: t('decemberYYYY', { year: 2019 }), + previousDate: t('decemberYYYY', { year: 2020 }), }), - event: EVENTS.winter2021, + event: EVENTS.winter2023, canBuy () { - return moment().isBetween('2020-12-22T08:00-04:00', '2021-01-31T20:00-04:00'); + return moment().isBetween(EVENTS.winter2023.start, EVENTS.winter2023.end); }, }, Ruby: { diff --git a/website/common/script/content/shop-featuredItems.js b/website/common/script/content/shop-featuredItems.js index 031d7d3a9c..44ae32f7f7 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.bundle202211.start, EVENTS.bundle202211.end)) { + if (moment().isBetween(EVENTS.winter2023.start, EVENTS.winter2023.end)) { return [ { type: 'armoire', @@ -13,15 +13,15 @@ const featuredItems = { }, { type: 'premiumHatchingPotion', - path: 'premiumHatchingPotions.Frost', + path: 'premiumHatchingPotions.StarryNight', }, { type: 'premiumHatchingPotion', - path: 'premiumHatchingPotions.Ember', + path: 'premiumHatchingPotions.Holly', }, { type: 'premiumHatchingPotion', - path: 'premiumHatchingPotions.Thunderstorm', + path: 'premiumHatchingPotions.Aurora', }, ]; } @@ -32,51 +32,51 @@ const featuredItems = { }, { type: 'food', - path: 'food.Milk', + path: 'food.RottenMeat', }, { type: 'hatchingPotions', - path: 'hatchingPotions.White', + path: 'hatchingPotions.CottonCandyBlue', }, { type: 'eggs', - path: 'eggs.Fox', + path: 'eggs.FlyingPig', }, ]; }, quests () { - if (moment().isBetween(EVENTS.bundle202211.start, EVENTS.bundle202211.end)) { + if (moment().isBetween(EVENTS.winter2023.start, EVENTS.winter2023.end)) { return [ { type: 'bundles', - path: 'bundles.rockingReptiles', + path: 'bundles.winterQuests', }, { type: 'quests', - path: 'quests.peacock', + path: 'quests.whale', }, { type: 'quests', - path: 'quests.harpy', + path: 'quests.turtle', }, ]; } return [ { type: 'quests', - path: 'quests.axolotl', + path: 'quests.slime', }, { type: 'quests', - path: 'quests.stone', + path: 'quests.seaserpent', }, { type: 'quests', - path: 'quests.whale', + path: 'quests.unicorn', }, ]; }, - seasonal: 'spring2021Healer', + seasonal: 'winter2022Healer', timeTravelers: [ // TODO ], diff --git a/website/common/script/libs/achievements.js b/website/common/script/libs/achievements.js index 52af6e2ce7..79aecd4c2f 100644 --- a/website/common/script/libs/achievements.js +++ b/website/common/script/libs/achievements.js @@ -220,6 +220,7 @@ function _getBasicAchievements (user, language) { _addSimple(result, user, { path: 'reptacularRumble', language }); _addSimple(result, user, { path: 'woodlandWizard', language }); _addSimple(result, user, { path: 'boneToPick', language }); + _addSimple(result, user, { path: 'polarPro', language }); _addSimpleWithMasterCount(result, user, { path: 'beastMaster', language }); _addSimpleWithMasterCount(result, user, { path: 'mountMaster', language }); diff --git a/website/common/script/libs/shops-seasonal.config.js b/website/common/script/libs/shops-seasonal.config.js index 077a011288..fc6c64fde3 100644 --- a/website/common/script/libs/shops-seasonal.config.js +++ b/website/common/script/libs/shops-seasonal.config.js @@ -30,23 +30,24 @@ export default { pinnedSets: SHOP_OPEN ? { - healer: 'fall2022WatcherHealerSet', - rogue: 'fall2022KappaRogueSet', - warrior: 'fall2022OrcWarriorSet', - wizard: 'fall2022HarpyMageSet', + rogue: 'winter2023RibbonRogueSet', + warrior: 'winter2023WalrusWarriorSet', + wizard: 'winter2023FairyLightsMageSet', + healer: 'winter2023CardinalHealerSet', } : {}, - availableSpells: SHOP_OPEN && moment().isBetween('2022-10-04T08:00-05:00', CURRENT_EVENT.end) + availableSpells: SHOP_OPEN && moment().isBetween('2022-12-27T08:00-05:00', CURRENT_EVENT.end) ? [ - 'spookySparkles', + 'snowball', ] : [], - availableQuests: SHOP_OPEN && CURRENT_EVENT.season === 'spring' + availableQuests: SHOP_OPEN && CURRENT_EVENT.season === 'winter' ? [ - 'egg', + 'evilsanta', + 'evilsanta2', ] : [], - featuredSet: 'fall2021BrainEaterMageSet', + featuredSet: 'winter2022PomegranateMageSet', }; diff --git a/website/server/controllers/api-v3/auth.js b/website/server/controllers/api-v3/auth.js index 7092066446..31cf12408e 100644 --- a/website/server/controllers/api-v3/auth.js +++ b/website/server/controllers/api-v3/auth.js @@ -289,8 +289,11 @@ api.updatePassword = { newPassword: { notEmpty: { errorMessage: res.t('missingNewPassword') }, isLength: { - options: { min: common.constants.MINIMUM_PASSWORD_LENGTH }, - errorMessage: res.t('minPasswordLength'), + options: { + min: common.constants.MINIMUM_PASSWORD_LENGTH, + max: common.constants.MAXIMUM_PASSWORD_LENGTH, + }, + errorMessage: res.t('passwordIssueLength'), }, }, confirmPassword: { diff --git a/website/server/libs/worldState.js b/website/server/libs/worldState.js index 257ab1879f..68e7081bc9 100644 --- a/website/server/libs/worldState.js +++ b/website/server/libs/worldState.js @@ -27,6 +27,9 @@ export function getCurrentEvent () { }); if (!currEvtKey) return null; + if (!common.content.events[currEvtKey].npcImageSuffix) { + common.content.events[currEvtKey].npcImageSuffix = ''; + } return { event: currEvtKey, ...common.content.events[currEvtKey], diff --git a/website/server/models/user/schema.js b/website/server/models/user/schema.js index 4afe7a1ae8..0f47a975d9 100644 --- a/website/server/models/user/schema.js +++ b/website/server/models/user/schema.js @@ -152,6 +152,7 @@ export default new Schema({ reptacularRumble: Boolean, woodlandWizard: Boolean, boneToPick: Boolean, + polarPro: Boolean, // Onboarding Guide createdTask: Boolean, completedTask: Boolean,