Skip to content

Instantly share code, notes, and snippets.

@aszlig
Created October 24, 2020 23:48
Show Gist options
  • Save aszlig/8c4c278a9c0b7daa370201afea0b5315 to your computer and use it in GitHub Desktop.
Save aszlig/8c4c278a9c0b7daa370201afea0b5315 to your computer and use it in GitHub Desktop.
diff --git a/pkgs/shabitica/patches/allow-invite-by-url.patch b/pkgs/shabitica/patches/allow-invite-by-url.patch
index 3a4bf06..a0501f6 100644
--- a/pkgs/shabitica/patches/allow-invite-by-url.patch
+++ b/pkgs/shabitica/patches/allow-invite-by-url.patch
@@ -20,10 +20,10 @@ Date: Mon May 13 11:42:29 2019 +0200
Filename: allow-invite-by-url.patch
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 27f1a5c628..49b174b594 100644
+index 095e1ea58d..5fc90963db 100644
--- a/test/api/v3/integration/groups/POST-groups_invite.test.js
+++ b/test/api/v3/integration/groups/POST-groups_invite.test.js
-@@ -337,6 +337,32 @@ describe('Post /groups/:groupId/invite', () => {
+@@ -341,6 +341,32 @@ describe('Post /groups/:groupId/invite', () => {
});
});
@@ -56,29 +56,41 @@ index 27f1a5c628..49b174b594 100644
describe('user and email invites', () => {
it('returns an error when emails and uuids are not provided', async () => {
await expect(inviter.post(`/groups/${group._id}/invite`))
-diff --git a/website/client/components/groups/inviteModal.vue b/website/client/components/groups/inviteModal.vue
-index a1e8a312eb..e761094de0 100644
---- a/website/client/components/groups/inviteModal.vue
-+++ b/website/client/components/groups/inviteModal.vue
-@@ -1,6 +1,15 @@
- <template lang="pug">
- b-modal#invite-modal(:title='$t(`inviteTo${groupType}`)', :hide-footer='true')
- div
-+ strong Invite via URL
-+ .mt-2.mb-4.d-flex
-+ button.btn.btn-secondary(@click='generateInviteUrl') Generate URL
-+ .input-group-text(v-if='inviteUrl', @click='copyInviteUrl')
-+ #invite-url.text {{ inviteUrl }}
-+ .ml-3
-+ .svg-icon.copy-icon(v-html='icons.copy')
-+ .small(v-once) {{ $t('copy') }}
-+
- strong {{ $t('inviteEmailUsername') }}
- .small {{ $t('inviteEmailUsernameInfo') }}
- div(v-for='(invite, index) in invites')
-@@ -41,6 +50,29 @@
+diff --git a/website/client/src/components/groups/inviteModal.vue b/website/client/src/components/groups/inviteModal.vue
+index a072d139f9..0bc3dd2b50 100644
+--- a/website/client/src/components/groups/inviteModal.vue
++++ b/website/client/src/components/groups/inviteModal.vue
+@@ -5,6 +5,27 @@
+ :hide-footer="true"
+ >
+ <div>
++ <strong>Invite via URL</strong>
++ <div class="mt-2 mb-4 d-flex">
++ <button
++ class="btn btn-secondary"
++ @click="generateInviteUrl"
++ >Generate URL</button>
++ <div class="input-group-text" v-if="inviteUrl" @click="copyInviteUrl">
++ <div id="invite-url" class="text">{{ inviteUrl }}</div>
++ <div class="ml-3">
++ <div
++ class="svg-icon copy-icon"
++ v-html="icons.copy"
++ ></div>
++ <div
++ v-once
++ class="small"
++ >{{ $t('copy') }}</div>
++ </div>
++ </div>
++ </div>
++
+ <strong>{{ $t('inviteEmailUsername') }}</strong>
+ <div class="small">
+ {{ $t('inviteEmailUsernameInfo') }}
+@@ -77,6 +98,29 @@
<style lang="scss" scoped>
- @import '~client/assets/scss/colors.scss';
+ @import '~@/assets/scss/colors.scss';
+ .input-group-text {
+ background-color: $gray-600;
@@ -106,55 +118,55 @@ index a1e8a312eb..e761094de0 100644
a:not([href]) {
color: $blue-10;
font-size: 16px;
-@@ -99,6 +131,7 @@
- import isUUID from 'validator/lib/isUUID';
- import notifications from 'client/mixins/notifications';
- import positiveIcon from 'assets/svg/positive.svg';
-+ import copyIcon from 'assets/svg/copy.svg';
+@@ -135,6 +179,7 @@ import isUUID from 'validator/lib/isUUID';
+ import { mapState } from '@/libs/store';
+ import notifications from '@/mixins/notifications';
+ import positiveIcon from '@/assets/svg/positive.svg';
++import copyIcon from '@/assets/svg/copy.svg';
- const INVITE_DEFAULTS = {text: '', error: null, valid: null};
+ const INVITE_DEFAULTS = { text: '', error: null, valid: null };
-@@ -117,9 +150,11 @@
- },
- data () {
- return {
-+ inviteUrl: null,
- invites: [clone(INVITE_DEFAULTS), clone(INVITE_DEFAULTS)],
- icons: Object.freeze({
- positiveIcon,
-+ copy: copyIcon,
- }),
- };
- },
-@@ -192,6 +227,24 @@
- this.text(this.$t(invitationString));
- this.close();
- },
-+ async generateInviteUrl () {
-+ this.inviteUrl = await this.$store.dispatch('guilds:inviteUrl', {
-+ groupId: this.group._id,
-+ });
-+ },
-+ copyInviteUrl () {
-+ if (navigator.clipboard) {
-+ navigator.clipboard.writeText(this.inviteUrl);
-+ } else {
-+ let copyText = document.createElement('textarea');
-+ copyText.value = this.inviteUrl;
-+ document.body.appendChild(copyText);
-+ copyText.select();
-+ document.execCommand('copy');
-+ document.body.removeChild(copyText);
-+ }
-+ this.text('Invite URL copied to clipboard.');
-+ },
+@@ -143,9 +188,11 @@ export default {
+ props: ['group', 'groupType'],
+ data () {
+ return {
++ inviteUrl: null,
+ invites: [clone(INVITE_DEFAULTS), clone(INVITE_DEFAULTS)],
+ icons: Object.freeze({
+ positiveIcon,
++ copy: copyIcon,
+ }),
+ };
+ },
+@@ -238,6 +285,24 @@ export default {
+ this.text(this.$t(invitationString));
+ this.close();
},
- mixins: [notifications],
- props: ['group', 'groupType'],
-diff --git a/website/client/store/actions/guilds.js b/website/client/store/actions/guilds.js
-index b4eda8714b..d186fbbd3b 100644
---- a/website/client/store/actions/guilds.js
-+++ b/website/client/store/actions/guilds.js
++ async generateInviteUrl () {
++ this.inviteUrl = await this.$store.dispatch('guilds:inviteUrl', {
++ groupId: this.group._id,
++ });
++ },
++ copyInviteUrl () {
++ if (navigator.clipboard) {
++ navigator.clipboard.writeText(this.inviteUrl);
++ } else {
++ let copyText = document.createElement('textarea');
++ copyText.value = this.inviteUrl;
++ document.body.appendChild(copyText);
++ copyText.select();
++ document.execCommand('copy');
++ document.body.removeChild(copyText);
++ }
++ this.text('Invite URL copied to clipboard.');
++ },
+ },
+ };
+ </script>
+diff --git a/website/client/src/store/actions/guilds.js b/website/client/src/store/actions/guilds.js
+index 2372fc9124..0e30181615 100644
+--- a/website/client/src/store/actions/guilds.js
++++ b/website/client/src/store/actions/guilds.js
@@ -169,6 +169,11 @@ export async function invite (store, payload) {
return response;
}
@@ -165,15 +177,15 @@ index b4eda8714b..d186fbbd3b 100644
+}
+
export async function inviteToQuest (store, payload) {
- let response = await axios.post(`/api/v4/groups/${payload.groupId}/quests/invite/${payload.key}`);
+ const response = await axios.post(`/api/v4/groups/${payload.groupId}/quests/invite/${payload.key}`);
diff --git a/website/server/controllers/api-v3/groups.js b/website/server/controllers/api-v3/groups.js
-index aa6b2f4f8a..73d56fdf87 100644
+index 0a622ea7aa..7e1cda6587 100644
--- a/website/server/controllers/api-v3/groups.js
+++ b/website/server/controllers/api-v3/groups.js
-@@ -24,9 +24,11 @@ import {
- import common from '../../../common';
+@@ -25,9 +25,11 @@ import common from '../../../common';
import apiError from '../../libs/apiError';
+ import { model as UserNotification } from '../../models/userNotification';
import payments from '../../libs/payments/payments';
+import { encrypt } from '../../libs/encryption';
@@ -183,7 +195,7 @@ index aa6b2f4f8a..73d56fdf87 100644
/**
* @apiDefine GroupBodyInvalid
-@@ -979,6 +981,59 @@ api.inviteToGroup = {
+@@ -1083,6 +1085,59 @@ api.inviteToGroup = {
},
};
diff --git a/pkgs/shabitica/patches/allow-register-first.patch b/pkgs/shabitica/patches/allow-register-first.patch
index 065132a..e71fedb 100644
--- a/pkgs/shabitica/patches/allow-register-first.patch
+++ b/pkgs/shabitica/patches/allow-register-first.patch
@@ -15,10 +15,10 @@ Date: Tue Mar 27 05:37:23 2018 +0200
Filename: allow-register-first.patch
diff --git a/website/server/libs/auth/index.js b/website/server/libs/auth/index.js
-index 3adf355408..a11e9042db 100644
+index 047c43aec2..d39b1a1362 100644
--- a/website/server/libs/auth/index.js
+++ b/website/server/libs/auth/index.js
-@@ -138,15 +138,17 @@ async function registerLocal (req, res, { isV3 = false }) {
+@@ -147,15 +147,17 @@ async function registerLocal (req, res, { isV3 = false }) {
},
};
diff --git a/pkgs/shabitica/patches/always-allow-delete.patch b/pkgs/shabitica/patches/always-allow-delete.patch
index 0caba6a..9333207 100644
--- a/pkgs/shabitica/patches/always-allow-delete.patch
+++ b/pkgs/shabitica/patches/always-allow-delete.patch
@@ -10,25 +10,25 @@ Date: Mon Apr 2 07:05:41 2018 +0200
Filename: always-allow-delete.patch
diff --git a/website/server/controllers/api-v3/user.js b/website/server/controllers/api-v3/user.js
-index fe65ba53dc..a43d86f415 100644
+index 7f8f0fa941..34bc303d6d 100644
--- a/website/server/controllers/api-v3/user.js
+++ b/website/server/controllers/api-v3/user.js
-@@ -251,7 +251,6 @@ api.deleteUser = {
+@@ -264,7 +264,6 @@ api.deleteUser = {
url: '/user',
async handler (req, res) {
- let user = res.locals.user;
-- let plan = user.purchased.plan;
+ const { user } = res.locals;
+- const { plan } = user.purchased;
- let password = req.body.password;
+ const { password } = req.body;
if (!password) throw new BadRequest(res.t('missingPassword'));
-@@ -264,10 +263,6 @@ api.deleteUser = {
- let feedback = req.body.feedback;
+@@ -277,10 +276,6 @@ api.deleteUser = {
+ const { feedback } = req.body;
if (feedback && feedback.length > 10000) throw new BadRequest(`Account deletion feedback is limited to 10,000 characters. For lengthy feedback, email ${TECH_ASSISTANCE_EMAIL}.`);
- if (plan && plan.customerId && !plan.dateTerminated) {
- throw new NotAuthorized(res.t('cannotDeleteActiveAccount'));
- }
-
- let types = ['party', 'guilds'];
- let groupFields = basicGroupFields.concat(' leader memberCount purchased');
+ const types = ['party', 'guilds'];
+ const groupFields = basicGroupFields.concat(' leader memberCount purchased');
diff --git a/pkgs/shabitica/patches/always-permit-group-leader-change.patch b/pkgs/shabitica/patches/always-permit-group-leader-change.patch
index dadbc6b..367137c 100644
--- a/pkgs/shabitica/patches/always-permit-group-leader-change.patch
+++ b/pkgs/shabitica/patches/always-permit-group-leader-change.patch
@@ -14,10 +14,10 @@ Date: Tue Mar 27 05:37:27 2018 +0200
Filename: always-permit-group-leader-change.patch
diff --git a/website/server/controllers/api-v3/groups.js b/website/server/controllers/api-v3/groups.js
-index dc35d5db83..6cbaf0f342 100644
+index 27873c888a..5248d6e2bd 100644
--- a/website/server/controllers/api-v3/groups.js
+++ b/website/server/controllers/api-v3/groups.js
-@@ -394,8 +394,6 @@ api.updateGroup = {
+@@ -415,8 +415,6 @@ api.updateGroup = {
if (group.leader !== user._id && group.type === 'party') throw new NotAuthorized(res.t('messageGroupOnlyLeaderCanUpdate'));
else if (group.leader !== user._id && !user.contributor.admin) throw new NotAuthorized(res.t('messageGroupOnlyLeaderCanUpdate'));
@@ -25,22 +25,22 @@ index dc35d5db83..6cbaf0f342 100644
-
_.assign(group, _.merge(group.toObject(), Group.sanitizeUpdate(req.body)));
- let savedGroup = await group.save();
+ const savedGroup = await group.save();
diff --git a/website/server/models/group.js b/website/server/models/group.js
-index 8b9133d85e..2fd7b7a8e6 100644
+index 00fbe78aa9..857c1316ed 100644
--- a/website/server/models/group.js
+++ b/website/server/models/group.js
-@@ -22,7 +22,6 @@ import {
+@@ -23,7 +23,6 @@ import { // eslint-disable-line import/no-cycle
import {
InternalServerError,
BadRequest,
- NotAuthorized,
} from '../libs/errors';
import baseModel from '../libs/baseModel';
- import { sendTxn as sendTxnEmail } from '../libs/email';
-@@ -1221,14 +1220,6 @@ schema.methods.leave = async function leaveGroup (user, keep = 'keep-all', keepC
- let group = this;
- let update = {};
+ import { sendTxn as sendTxnEmail } from '../libs/email'; // eslint-disable-line import/no-cycle
+@@ -1269,14 +1268,6 @@ schema.methods.leave = async function leaveGroup (user, keep = 'keep-all', keepC
+ const group = this;
+ const update = {};
- if (group.memberCount <= 1 && group.privacy === 'private' && group.hasNotCancelled()) {
- throw new NotAuthorized(shared.i18n.t('cannotDeleteActiveGroup'));
@@ -52,4 +52,4 @@ index 8b9133d85e..2fd7b7a8e6 100644
-
// only remove user from challenges if it's set to leave-challenges
if (keepChallenges === 'leave-challenges') {
- let challenges = await Challenge.find({
+ const challenges = await Challenge.find({
diff --git a/pkgs/shabitica/patches/buy-gems-via-menu.patch b/pkgs/shabitica/patches/buy-gems-via-menu.patch
index 4967e7a..a6695dc 100644
--- a/pkgs/shabitica/patches/buy-gems-via-menu.patch
+++ b/pkgs/shabitica/patches/buy-gems-via-menu.patch
@@ -12,35 +12,34 @@ Date: Sat Jun 23 14:25:29 2018 +0200
Signed-off-by: aszlig <aszlig@nix.build>
Filename: buy-gems-via-menu.patch
-diff --git a/website/client/components/header/menu.vue b/website/client/components/header/menu.vue
-index 1aa0759a54..b167999eec 100644
---- a/website/client/components/header/menu.vue
-+++ b/website/client/components/header/menu.vue
-@@ -71,7 +71,7 @@ div
- .top-menu-icon.svg-icon(v-html="icons.hourglasses", v-b-tooltip.hover.bottom="$t('mysticHourglassesTooltip')")
- span {{ userHourglasses }}
- .item-with-icon
-- a.top-menu-icon.svg-icon.gem(:aria-label="$t('gems')", href="#buy-gems" v-html="icons.gem", @click.prevent='showBuyGemsModal("gems")', v-b-tooltip.hover.bottom="$t('gems')")
-+ a.top-menu-icon.svg-icon.gem(:aria-label="$t('gems')", href="#buy-gems" v-html="icons.gem", @click.prevent='showBuyGemsModal', v-b-tooltip.hover.bottom="$t('gems')")
- span {{userGems}}
- .item-with-icon.gold
- .top-menu-icon.svg-icon(:aria-label="$t('gold')", v-html="icons.gold", v-b-tooltip.hover.bottom="$t('gold')")
-@@ -403,7 +403,7 @@ import profileModal from '../userMenu/profileModal';
+diff --git a/website/client/src/components/header/menu.vue b/website/client/src/components/header/menu.vue
+index f5a8e8504f..f9e4b49a77 100644
+--- a/website/client/src/components/header/menu.vue
++++ b/website/client/src/components/header/menu.vue
+@@ -345,7 +345,7 @@
+ class="top-menu-icon svg-icon gem"
+ :aria-label="$t('gems')"
+ href="#buy-gems"
+- @click.prevent="showBuyGemsModal('gems')"
++ @click.prevent="showBuyGemsModal"
+ v-html="icons.gem"
+ ></a>
+ <span>{{ userGems }}</span>
+@@ -703,6 +703,7 @@ import profileModal from '../userMenu/profileModal';
import reportFlagModal from '../chat/reportFlagModal';
- import sync from 'client/mixins/sync';
+ import sync from '@/mixins/sync';
import userDropdown from './userDropdown';
--
-+import getItemInfo from 'common/script/libs/getItemInfo';
++import getItemInfo from '@/../../common/script/libs/getItemInfo';
+
export default {
- components: {
-@@ -466,9 +466,9 @@ export default {
+@@ -766,9 +767,9 @@ export default {
openPartyModal () {
this.$root.$emit('bv::show::modal', 'create-party-modal');
},
- showBuyGemsModal (startingPage) {
- this.$store.state.gemModalOptions.startingPage = startingPage;
-- this.$root.$emit('bv::show::modal', 'buy-gems', {alreadyTracked: true});
+- this.$root.$emit('bv::show::modal', 'buy-gems', { alreadyTracked: true });
+ showBuyGemsModal () {
+ let gemItem = getItemInfo(this.user, 'gem');
+ this.$root.$emit('buyModal::showItem', gemItem);
diff --git a/pkgs/shabitica/patches/dont-cancel-group-subscription-on-leave.patch b/pkgs/shabitica/patches/dont-cancel-group-subscription-on-leave.patch
index e4d033a..50a19a4 100644
--- a/pkgs/shabitica/patches/dont-cancel-group-subscription-on-leave.patch
+++ b/pkgs/shabitica/patches/dont-cancel-group-subscription-on-leave.patch
@@ -10,10 +10,10 @@ Date: Mon Apr 2 04:50:12 2018 +0200
Filename: dont-cancel-group-subscription-on-leave.patch
diff --git a/test/api/unit/models/group.test.js b/test/api/unit/models/group.test.js
-index 1470f0ad5d..992541d39a 100644
+index 7d32e6f9f8..0e6d77ec29 100644
--- a/test/api/unit/models/group.test.js
+++ b/test/api/unit/models/group.test.js
-@@ -1166,10 +1166,14 @@ describe('Group Model', () => {
+@@ -1174,10 +1174,14 @@ describe('Group Model', () => {
});
it('deletes a private group when the last member leaves and a subscription is active', async () => {
@@ -27,9 +27,9 @@ index 1470f0ad5d..992541d39a 100644
+ await party.leave(nonParticipatingMember);
+ await party.leave(undecidedMember);
- party = await Group.findOne({_id: party._id});
+ party = await Group.findOne({ _id: party._id });
expect(party).to.not.exist;
-@@ -1178,6 +1182,7 @@ describe('Group Model', () => {
+@@ -1186,6 +1190,7 @@ describe('Group Model', () => {
it('allows a leader to leave a group with an active subscription', async () => {
party.memberCount = 2;
party.purchased.plan.customerId = '110002222333';
@@ -38,19 +38,19 @@ index 1470f0ad5d..992541d39a 100644
await party.leave(questLeader);
diff --git a/test/api/v3/integration/groups/POST-groups_groupId_leave.js b/test/api/v3/integration/groups/POST-groups_groupId_leave.js
-index 65d76f4714..9eb8e166bd 100644
+index 70d60cc3d0..8ecb33e0d4 100644
--- a/test/api/v3/integration/groups/POST-groups_groupId_leave.js
+++ b/test/api/v3/integration/groups/POST-groups_groupId_leave.js
-@@ -10,8 +10,6 @@ import { v4 as generateUUID } from 'uuid';
- import {
- each,
- } from 'lodash';
+@@ -10,8 +10,6 @@ import {
+ generateUser,
+ translate as t,
+ } from '../../../../helpers/api-integration/v3';
-import { model as User } from '../../../../../website/server/models/user';
--import * as payments from '../../../../../website/server/libs/payments/payments';
+-import payments from '../../../../../website/server/libs/payments/payments';
describe('POST /groups/:groupId/leave', () => {
- let typesOfGroups = {
-@@ -275,71 +273,4 @@ describe('POST /groups/:groupId/leave', () => {
+ const typesOfGroups = {
+@@ -271,71 +269,4 @@ describe('POST /groups/:groupId/leave', () => {
expect(userWithNonExistentParty.party).to.eql({});
});
});
@@ -62,17 +62,17 @@ index 65d76f4714..9eb8e166bd 100644
- let member;
-
- beforeEach(async () => {
-- let { group, groupLeader, members } = await createAndPopulateGroup({
+- const { group, groupLeader, members } = await createAndPopulateGroup({
- groupDetails,
- members: 1,
- });
- leader = groupLeader;
-- member = members[0];
+- member = members[0]; // eslint-disable-line prefer-destructuring
- groupWithPlan = group;
-- let userWithFreePlan = await User.findById(leader._id).exec();
+- const userWithFreePlan = await User.findById(leader._id).exec();
-
- // Create subscription
-- let paymentData = {
+- const paymentData = {
- user: userWithFreePlan,
- groupId: groupWithPlan._id,
- sub: {
@@ -101,7 +101,7 @@ index 65d76f4714..9eb8e166bd 100644
-
- it('preserves the free subscription when leaving a any other group without a plan', async () => {
- // Joining a guild without a group plan
-- let { group: groupWithNoPlan } = await createAndPopulateGroup({
+- const { group: groupWithNoPlan } = await createAndPopulateGroup({
- groupDetails: {
- name: 'Group Without Plan',
- type: 'guild',
@@ -123,19 +123,19 @@ index 65d76f4714..9eb8e166bd 100644
- });
});
diff --git a/website/server/models/group.js b/website/server/models/group.js
-index 2fd7b7a8e6..3482311378 100644
+index 857c1316ed..86eda0d03e 100644
--- a/website/server/models/group.js
+++ b/website/server/models/group.js
-@@ -14,7 +14,6 @@ import {
+@@ -15,7 +15,6 @@ import {
+ } from './message';
import * as Tasks from './task';
- import validator from 'validator';
import { removeFromArray } from '../libs/collectionManipulators';
--import payments from '../libs/payments/payments';
- import {
+-import payments from '../libs/payments/payments'; // eslint-disable-line import/no-cycle
+ import { // eslint-disable-line import/no-cycle
groupChatReceivedWebhook,
questActivityWebhook,
-@@ -1257,10 +1256,6 @@ schema.methods.leave = async function leaveGroup (user, keep = 'keep-all', keepC
- update.$unset = {[`quest.members.${user._id}`]: 1};
+@@ -1302,10 +1301,6 @@ schema.methods.leave = async function leaveGroup (user, keep = 'keep-all', keepC
+ update.$unset = { [`quest.members.${user._id}`]: 1 };
}
- if (group.purchased.plan.customerId) {
@@ -144,4 +144,4 @@ index 2fd7b7a8e6..3482311378 100644
-
// If user is the last one in group and group is private, delete it
if (group.memberCount <= 1 && group.privacy === 'private') {
- // double check the member count is correct so we don't accidentally delete a group that still has users in it
+ // double check the member count is correct
diff --git a/pkgs/shabitica/patches/dont-restrict-email-domains.patch b/pkgs/shabitica/patches/dont-restrict-email-domains.patch
index 1724b02..0b806af 100644
--- a/pkgs/shabitica/patches/dont-restrict-email-domains.patch
+++ b/pkgs/shabitica/patches/dont-restrict-email-domains.patch
@@ -10,7 +10,7 @@ Date: Tue Mar 27 07:32:57 2018 +0200
Filename: dont-restrict-email-domains.patch
diff --git a/test/api/v3/integration/user/auth/POST-register_local.test.js b/test/api/v3/integration/user/auth/POST-register_local.test.js
-index 5b559aae5b..22f440ee6a 100644
+index 59e518fcb8..0749afc12f 100644
--- a/test/api/v3/integration/user/auth/POST-register_local.test.js
+++ b/test/api/v3/integration/user/auth/POST-register_local.test.js
@@ -389,38 +389,32 @@ describe('POST /user/auth/local/register', () => {
@@ -19,9 +19,9 @@ index 5b559aae5b..22f440ee6a 100644
- it('fails on a habitica.com email', async () => {
+ it('works even on a habitica.com email', async () => {
- let username = generateRandomUserName();
- let email = `${username}@habitica.com`;
- let password = 'password';
+ const username = generateRandomUserName();
+ const email = `${username}@habitica.com`;
+ const password = 'password';
- await expect(api.post('/user/auth/local/register', {
+ let user = await api.post('/user/auth/local/register', {
@@ -39,9 +39,9 @@ index 5b559aae5b..22f440ee6a 100644
- it('fails on a habitrpg.com email', async () => {
+ it('works even on a habitrpg.com email', async () => {
- let username = generateRandomUserName();
- let email = `${username}@habitrpg.com`;
- let password = 'password';
+ const username = generateRandomUserName();
+ const email = `${username}@habitrpg.com`;
+ const password = 'password';
- await expect(api.post('/user/auth/local/register', {
+ let user = await api.post('/user/auth/local/register', {
@@ -59,7 +59,7 @@ index 5b559aae5b..22f440ee6a 100644
it('requires a password', async () => {
diff --git a/test/api/v4/user/auth/POST-register_local.test.js b/test/api/v4/user/auth/POST-register_local.test.js
-index b75c9b4c55..8bdf4dd4c0 100644
+index 7dc4f265b6..293d4dfc03 100644
--- a/test/api/v4/user/auth/POST-register_local.test.js
+++ b/test/api/v4/user/auth/POST-register_local.test.js
@@ -372,38 +372,32 @@ describe('POST /user/auth/local/register', () => {
@@ -68,9 +68,9 @@ index b75c9b4c55..8bdf4dd4c0 100644
- it('fails on a habitica.com email', async () => {
+ it('works even on a habitica.com email', async () => {
- let username = generateRandomUserName();
- let email = `${username}@habitica.com`;
- let password = 'password';
+ const username = generateRandomUserName();
+ const email = `${username}@habitica.com`;
+ const password = 'password';
- await expect(api.post('/user/auth/local/register', {
+ let user = await api.post('/user/auth/local/register', {
@@ -88,9 +88,9 @@ index b75c9b4c55..8bdf4dd4c0 100644
- it('fails on a habitrpg.com email', async () => {
+ it('works even on a habitrpg.com email', async () => {
- let username = generateRandomUserName();
- let email = `${username}@habitrpg.com`;
- let password = 'password';
+ const username = generateRandomUserName();
+ const email = `${username}@habitrpg.com`;
+ const password = 'password';
- await expect(api.post('/user/auth/local/register', {
+ let user = await api.post('/user/auth/local/register', {
@@ -108,31 +108,29 @@ index b75c9b4c55..8bdf4dd4c0 100644
it('requires a password', async () => {
diff --git a/website/server/models/user/schema.js b/website/server/models/user/schema.js
-index 621f66e92c..75efb7f937 100644
+index 1e472b4361..6fdea247aa 100644
--- a/website/server/models/user/schema.js
+++ b/website/server/models/user/schema.js
-@@ -15,8 +15,6 @@ import {
+@@ -15,8 +15,6 @@ import { // eslint-disable-line import/no-cycle
- const Schema = mongoose.Schema;
+ const { Schema } = mongoose;
-const RESTRICTED_EMAIL_DOMAINS = Object.freeze(['habitica.com', 'habitrpg.com']);
-
// User schema definition
- let schema = new Schema({
+ export default new Schema({
apiToken: {
-@@ -32,15 +30,6 @@ let schema = new Schema({
+@@ -32,13 +30,6 @@ export default new Schema({
validate: [{
- validator: (v) => validator.isEmail(v),
+ validator: v => validator.isEmail(v),
message: shared.i18n.t('invalidEmail'),
- }, {
- validator (email) {
-- let lowercaseEmail = email.toLowerCase();
+- const lowercaseEmail = email.toLowerCase();
-
-- return RESTRICTED_EMAIL_DOMAINS.every((domain) => {
-- return !lowercaseEmail.endsWith(`@${domain}`);
-- });
+- return RESTRICTED_EMAIL_DOMAINS.every(domain => !lowercaseEmail.endsWith(`@${domain}`));
- },
-- message: shared.i18n.t('invalidEmailDomain', { domains: RESTRICTED_EMAIL_DOMAINS.join(', ')}),
+- message: shared.i18n.t('invalidEmailDomain', { domains: RESTRICTED_EMAIL_DOMAINS.join(', ') }),
}],
},
username: {
diff --git a/pkgs/shabitica/patches/fix-client-circular-import.patch b/pkgs/shabitica/patches/fix-client-circular-import.patch
index d5c6704..860e6d5 100644
--- a/pkgs/shabitica/patches/fix-client-circular-import.patch
+++ b/pkgs/shabitica/patches/fix-client-circular-import.patch
@@ -14,20 +14,20 @@ Date: Thu Mar 29 05:54:18 2018 +0200
Filename: fix-client-circular-import.patch
diff --git a/website/common/script/libs/statsComputed.js b/website/common/script/libs/statsComputed.js
-index 1239b6d9d5..b13054cbbb 100644
+index 150200f4da..d0b4e2363c 100644
--- a/website/common/script/libs/statsComputed.js
+++ b/website/common/script/libs/statsComputed.js
@@ -1,11 +1,11 @@
import each from 'lodash/each';
import get from 'lodash/get';
import values from 'lodash/values';
--import content from '../content/index';
+-import content from '../content/index'; // eslint-disable-line import/no-cycle
+import contentGear from '../content/gear';
import * as statHelpers from '../statHelpers';
function equipmentStatBonusComputed (stat, user) {
-- let gear = content.gear.flat;
-+ let gear = contentGear.flat;
+- const gear = content.gear.flat;
++ const gear = contentGear.flat;
let gearBonus = 0;
let classBonus = 0;
diff --git a/pkgs/shabitica/patches/fix-connection-info-for-migrations.patch b/pkgs/shabitica/patches/fix-connection-info-for-migrations.patch
index b7bb5ce..cd4b52d 100644
--- a/pkgs/shabitica/patches/fix-connection-info-for-migrations.patch
+++ b/pkgs/shabitica/patches/fix-connection-info-for-migrations.patch
@@ -32,49 +32,52 @@ index a58df2a4cf..35da63622b 100644
const dbUsers = monk(connectionString).get('users', { castIds: false });
diff --git a/migrations/restock_armoire.js b/migrations/restock_armoire.js
-index 5046998a3b..34188d0688 100644
+index 182213b85b..3ba50c2e46 100644
--- a/migrations/restock_armoire.js
+++ b/migrations/restock_armoire.js
-@@ -6,8 +6,9 @@ let authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done
+@@ -7,9 +7,10 @@ const authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is do
* Remove flag stating that the Enchanted Armoire is empty, for when new equipment is added
*/
-+let mongoose = require('mongoose');
- let monk = require('monk');
--let connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
-+let connectionString = `mongodb://${mongoose.connection.host}`;
- let dbUsers = monk(connectionString).get('users', { castIds: false });
++const mongoose = require('mongoose');
+ const monk = require('monk'); // eslint-disable-line import/no-extraneous-dependencies
+
+-const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
++const connectionString = 'mongodb://${mongoose.connection.host}`;
+ const dbUsers = monk(connectionString).get('users', { castIds: false });
function processUsers (lastId) {
diff --git a/migrations/tasks/habits-one-history-entry-per-day-challenges.js b/migrations/tasks/habits-one-history-entry-per-day-challenges.js
-index dcb05f48bf..12e55ecb79 100644
+index 799e896af1..4dd0e624a7 100644
--- a/migrations/tasks/habits-one-history-entry-per-day-challenges.js
+++ b/migrations/tasks/habits-one-history-entry-per-day-challenges.js
-@@ -6,10 +6,11 @@
- * Iterates over all habits and condense multiple history entries for the same day into a single entry
+@@ -7,11 +7,12 @@
+ * Iterates over all habits and condense multiple history entries for the same day into a single one
*/
+const mongoose = require('mongoose');
- const monk = require('monk');
+ const monk = require('monk'); // eslint-disable-line import/no-extraneous-dependencies
const _ = require('lodash');
const moment = require('moment');
+
-const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
+const connectionString = `mongodb://${mongoose.connection.host}`;
const dbTasks = monk(connectionString).get('tasks', { castIds: false });
function processChallengeHabits (lastId) {
diff --git a/migrations/tasks/habits-one-history-entry-per-day-users.js b/migrations/tasks/habits-one-history-entry-per-day-users.js
-index 509aa71eb7..f71cad61ed 100644
+index cb3d2c24b5..71e2df5f27 100644
--- a/migrations/tasks/habits-one-history-entry-per-day-users.js
+++ b/migrations/tasks/habits-one-history-entry-per-day-users.js
-@@ -6,10 +6,11 @@ const authorUuid = 'ed4c688c-6652-4a92-9d03-a5a79844174a'; // ... own data is do
- * Iterates over all habits and condense multiple history entries for the same day into a single entry
+@@ -7,11 +7,12 @@ const authorUuid = 'ed4c688c-6652-4a92-9d03-a5a79844174a'; // ... own data is do
+ * Iterates over all habits and condense multiple history entries for the same day into a single one
*/
+const mongoose = require('mongoose');
- const monk = require('monk');
+ const monk = require('monk'); // eslint-disable-line import/no-extraneous-dependencies
const _ = require('lodash');
const moment = require('moment');
+
-const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
+const connectionString = `mongodb://${mongoose.connection.host}`;
const dbTasks = monk(connectionString).get('tasks', { castIds: false });
diff --git a/pkgs/shabitica/patches/fix-import-of-chat-model.patch b/pkgs/shabitica/patches/fix-import-of-chat-model.patch
deleted file mode 100644
index 3deb84a..0000000
--- a/pkgs/shabitica/patches/fix-import-of-chat-model.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-Author: aszlig <aszlig@nix.build>
-Date: Wed Oct 10 00:01:51 2018 +0200
-
- Fix import of Chat model
-
- With the refactor of the chat model to be included within the message
- model the import will fail during migration. So in order to be able to
- migrate older releases, let's fix the import.
-
- Signed-off-by: aszlig <aszlig@nix.build>
- Filename: fix-import-of-chat-model.patch
-
-diff --git a/migrations/groups/migrate-chat.js b/migrations/groups/migrate-chat.js
-index 8b341952cd..3b6c717636 100644
---- a/migrations/groups/migrate-chat.js
-+++ b/migrations/groups/migrate-chat.js
-@@ -8,7 +8,7 @@
- */
-
- import { model as Group } from '../../website/server/models/group';
--import { model as Chat } from '../../website/server/models/chat';
-+import { chatModel as Chat } from '../../website/server/models/message';
-
- async function moveGroupChatToModel (skip = 0) {
- const groups = await Group.find({})
diff --git a/pkgs/shabitica/patches/fix-invalid-session-cookie.patch b/pkgs/shabitica/patches/fix-invalid-session-cookie.patch
index 26e21b4..5187d27 100644
--- a/pkgs/shabitica/patches/fix-invalid-session-cookie.patch
+++ b/pkgs/shabitica/patches/fix-invalid-session-cookie.patch
@@ -23,10 +23,10 @@ Date: Mon Aug 6 08:07:39 2018 +0200
Filename: fix-invalid-session-cookie.patch
diff --git a/website/server/middlewares/index.js b/website/server/middlewares/index.js
-index 745ac8f7cb..fb80823c26 100644
+index 26542a05e7..90f621f06d 100644
--- a/website/server/middlewares/index.js
+++ b/website/server/middlewares/index.js
-@@ -66,7 +66,7 @@ module.exports = function attachMiddlewares (app, server) {
+@@ -66,7 +66,7 @@ export default function attachMiddlewares (app, server) {
app.use(methodOverride());
app.use(cookieSession({
diff --git a/pkgs/shabitica/patches/fix-moment-recur-import.patch b/pkgs/shabitica/patches/fix-moment-recur-import.patch
index 19de3f0..bef9d6c 100644
--- a/pkgs/shabitica/patches/fix-moment-recur-import.patch
+++ b/pkgs/shabitica/patches/fix-moment-recur-import.patch
@@ -15,19 +15,19 @@ Date: Thu Mar 29 09:49:42 2018 +0200
Filename: fix-moment-recur-import.patch
diff --git a/test/common/shouldDo.test.js b/test/common/shouldDo.test.js
-index dedcaa4951..f0ea2f8a60 100644
+index f7505d20f3..803ebc158f 100644
--- a/test/common/shouldDo.test.js
+++ b/test/common/shouldDo.test.js
@@ -1,6 +1,5 @@
- import { shouldDo, DAY_MAPPING } from '../../website/common/script/cron';
-import moment from 'moment';
--import 'moment-recur';
+import moment from 'moment-recur';
+ import { shouldDo, DAY_MAPPING } from '../../website/common/script/cron';
+-import 'moment-recur';
describe('shouldDo', () => {
- let day, dailyTask;
+ let day; let
diff --git a/website/common/script/cron.js b/website/common/script/cron.js
-index b93df4b80e..ca6ca36676 100644
+index 53be939a4e..548b3fa0e0 100644
--- a/website/common/script/cron.js
+++ b/website/common/script/cron.js
@@ -6,8 +6,7 @@
diff --git a/pkgs/shabitica/patches/fix-server-common-import.patch b/pkgs/shabitica/patches/fix-server-common-import.patch
deleted file mode 100644
index 7002188..0000000
--- a/pkgs/shabitica/patches/fix-server-common-import.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-Author: aszlig <aszlig@nix.build>
-Date: Wed Mar 28 07:08:45 2018 +0200
-
- Fix import of common module from server
-
- It's not really necessary to go through ../website here, because server
- and common are in the same directory.
-
- In our setup, the directory layout is a little bit different, so we
- don't have a "website" directory.
-
- Signed-off-by: aszlig <aszlig@nix.build>
- Filename: fix-server-common-import.patch
-
-diff --git a/website/server/controllers/api-v3/members.js b/website/server/controllers/api-v3/members.js
-index 9c59c17a43..f2cbae187d 100644
---- a/website/server/controllers/api-v3/members.js
-+++ b/website/server/controllers/api-v3/members.js
-@@ -18,7 +18,7 @@ import {
- getUserInfo,
- sendTxn as sendTxnEmail,
- } from '../../libs/email';
--import { achievements } from '../../../../website/common/';
-+import { achievements } from '../../../common/';
- import {sentMessage} from '../../libs/inbox';
-
- let api = {};
diff --git a/pkgs/shabitica/patches/fixup-test-runners.patch b/pkgs/shabitica/patches/fixup-test-runners.patch
index 45db17d..86b1831 100644
--- a/pkgs/shabitica/patches/fixup-test-runners.patch
+++ b/pkgs/shabitica/patches/fixup-test-runners.patch
@@ -18,115 +18,115 @@ Date: Mon Apr 2 09:23:06 2018 +0200
Filename: fixup-test-runners.patch
diff --git a/gulp/gulp-tests.js b/gulp/gulp-tests.js
-index 7294a90574..80b331ec17 100644
+index 47eec297ec..c7e97b9641 100644
--- a/gulp/gulp-tests.js
+++ b/gulp/gulp-tests.js
-@@ -17,7 +17,7 @@ const TEST_DB_URI = nconf.get('TEST_DB_URI');
+@@ -17,7 +17,7 @@ const TEST_DB_URI = nconf.get('TEST_DB_URI');
const SANITY_TEST_COMMAND = 'npm run test:sanity';
const COMMON_TEST_COMMAND = 'npm run test:common';
const CONTENT_TEST_COMMAND = 'npm run test:content';
--const CONTENT_OPTIONS = {maxBuffer: 1024 * 500};
-+const CONTENT_OPTIONS = {maxBuffer: 1073741824};
+-const CONTENT_OPTIONS = { maxBuffer: 1024 * 500 };
++const CONTENT_OPTIONS = { maxBuffer: 1073741824 };
/* Helper methods for reporting test summary */
- let testResults = [];
-@@ -56,7 +56,7 @@ gulp.task('test:prepare:mongo', (cb) => {
+ const testResults = [];
+@@ -55,7 +55,7 @@ gulp.task('test:prepare:mongo', cb => {
- gulp.task('test:prepare:server', gulp.series('test:prepare:mongo', (done) => {
+ gulp.task('test:prepare:server', gulp.series('test:prepare:mongo', done => {
if (!server) {
- server = exec(testBin('node ./website/server/index.js', `NODE_DB_URI=${TEST_DB_URI} PORT=${TEST_SERVER_PORT}`), (error, stdout, stderr) => {
+ server = exec(testBin('node ./website/server/index.js', `NODE_DB_URI=${TEST_DB_URI} PORT=${TEST_SERVER_PORT}`), CONTENT_OPTIONS, (error, stdout, stderr) => {
if (error) {
throw new Error(`Problem with the server: ${error}`);
}
-@@ -79,6 +79,7 @@ gulp.task('test:prepare', gulp.series(
- gulp.task('test:sanity', (cb) => {
- let runner = exec(
+@@ -78,6 +78,7 @@ gulp.task('test:prepare', gulp.series(
+ gulp.task('test:sanity', cb => {
+ const runner = exec(
testBin(SANITY_TEST_COMMAND),
+ CONTENT_OPTIONS,
- (err) => {
+ err => {
if (err) {
process.exit(1);
-@@ -92,6 +93,7 @@ gulp.task('test:sanity', (cb) => {
- gulp.task('test:common', gulp.series('test:prepare:build', (cb) => {
- let runner = exec(
+@@ -91,6 +92,7 @@ gulp.task('test:sanity', cb => {
+ gulp.task('test:common', gulp.series('test:prepare:build', cb => {
+ const runner = exec(
testBin(COMMON_TEST_COMMAND),
+ CONTENT_OPTIONS,
- (err) => {
+ err => {
if (err) {
process.exit(1);
-@@ -103,7 +105,7 @@ gulp.task('test:common', gulp.series('test:prepare:build', (cb) => {
+@@ -102,7 +104,7 @@ gulp.task('test:common', gulp.series('test:prepare:build', cb => {
}));
- gulp.task('test:common:clean', (cb) => {
+ gulp.task('test:common:clean', cb => {
- pipe(exec(testBin(COMMON_TEST_COMMAND), () => cb()));
+ pipe(exec(testBin(COMMON_TEST_COMMAND), CONTENT_OPTIONS, () => cb()));
});
- gulp.task('test:common:watch', gulp.series('test:common:clean', () => {
-@@ -113,6 +115,7 @@ gulp.task('test:common:watch', gulp.series('test:common:clean', () => {
- gulp.task('test:common:safe', gulp.series('test:prepare:build', (cb) => {
- let runner = exec(
+ gulp.task('test:common:watch', gulp.series('test:common:clean', () => gulp.watch(['common/script/**/*', 'test/common/**/*'], gulp.series('test:common:clean', done => done()))));
+@@ -110,6 +112,7 @@ gulp.task('test:common:watch', gulp.series('test:common:clean', () => gulp.watch
+ gulp.task('test:common:safe', gulp.series('test:prepare:build', cb => {
+ const runner = exec(
testBin(COMMON_TEST_COMMAND),
+ CONTENT_OPTIONS,
(err, stdout) => { // eslint-disable-line handle-callback-err
testResults.push({
suite: 'Common Specs\t',
-@@ -167,7 +170,8 @@ gulp.task('test:content:safe', gulp.series('test:prepare:build', (cb) => {
+@@ -162,7 +165,8 @@ gulp.task('test:content:safe', gulp.series('test:prepare:build', cb => {
- gulp.task('test:api:unit', (done) => {
- let runner = exec(
+ gulp.task('test:api:unit', done => {
+ const runner = exec(
- testBin('istanbul cover --dir coverage/api-unit node_modules/mocha/bin/_mocha -- test/api/unit --recursive --require ./test/helpers/start-server'),
+ testBin('istanbul cover --dir coverage/api-unit mocha -- test/api/unit --recursive --require ./test/helpers/start-server'),
+ CONTENT_OPTIONS,
- (err) => {
+ err => {
if (err) {
process.exit(1);
-@@ -185,8 +189,8 @@ gulp.task('test:api:unit:watch', () => {
+@@ -178,8 +182,8 @@ gulp.task('test:api:unit:watch', () => gulp.watch(['website/server/libs/*', 'tes
- gulp.task('test:api-v3:integration', (done) => {
- let runner = exec(
+ gulp.task('test:api-v3:integration', done => {
+ const runner = exec(
- testBin('istanbul cover --dir coverage/api-v3-integration --report lcovonly node_modules/mocha/bin/_mocha -- test/api/v3/integration --recursive --require ./test/helpers/start-server'),
-- {maxBuffer: 500 * 1024},
+- { maxBuffer: 500 * 1024 },
+ testBin('istanbul cover --dir coverage/api-v3-integration --report lcovonly mocha -- test/api/v3/integration --recursive --require ./test/helpers/start-server'),
+ CONTENT_OPTIONS,
- (err) => {
+ err => {
if (err) {
process.exit(1);
-@@ -208,7 +212,7 @@ gulp.task('test:api-v3:integration:watch', () => {
- gulp.task('test:api-v3:integration:separate-server', (done) => {
- let runner = exec(
+@@ -199,7 +203,7 @@ gulp.task('test:api-v3:integration:watch', () => gulp.watch([
+ gulp.task('test:api-v3:integration:separate-server', done => {
+ const runner = exec(
testBin('mocha test/api/v3/integration --recursive --require ./test/helpers/start-server', 'LOAD_SERVER=0'),
-- {maxBuffer: 500 * 1024},
+- { maxBuffer: 500 * 1024 },
+ CONTENT_OPTIONS,
- (err) => done(err)
+ err => done(err),
);
-@@ -217,8 +221,8 @@ gulp.task('test:api-v3:integration:separate-server', (done) => {
+@@ -208,8 +212,8 @@ gulp.task('test:api-v3:integration:separate-server', done => {
- gulp.task('test:api-v4:integration', (done) => {
- let runner = exec(
+ gulp.task('test:api-v4:integration', done => {
+ const runner = exec(
- testBin('istanbul cover --dir coverage/api-v4-integration --report lcovonly node_modules/mocha/bin/_mocha -- test/api/v4 --recursive --require ./test/helpers/start-server'),
-- {maxBuffer: 500 * 1024},
+- { maxBuffer: 500 * 1024 },
+ testBin('istanbul cover --dir coverage/api-v4-integration --report lcovonly mocha -- test/api/v4 --recursive --require ./test/helpers/start-server'),
+ CONTENT_OPTIONS,
- (err) => {
+ err => {
if (err) {
process.exit(1);
-@@ -233,7 +237,7 @@ gulp.task('test:api-v4:integration', (done) => {
- gulp.task('test:api-v4:integration:separate-server', (done) => {
- let runner = exec(
+@@ -224,7 +228,7 @@ gulp.task('test:api-v4:integration', done => {
+ gulp.task('test:api-v4:integration:separate-server', done => {
+ const runner = exec(
testBin('mocha test/api/v4 --recursive --require ./test/helpers/start-server', 'LOAD_SERVER=0'),
-- {maxBuffer: 500 * 1024},
+- { maxBuffer: 500 * 1024 },
+ CONTENT_OPTIONS,
- (err) => done(err)
+ err => done(err),
);
diff --git a/package.json b/package.json
-index 01c208c60b..88d6cd993c 100644
+index 5b86e60282..0dbe7d68dd 100644
--- a/package.json
+++ b/package.json
-@@ -112,9 +112,9 @@
+@@ -72,9 +72,9 @@
"test:api-v3:integration:separate-server": "NODE_ENV=test gulp test:api-v3:integration:separate-server",
"test:api-v4:integration": "gulp test:api-v4:integration",
"test:api-v4:integration:separate-server": "NODE_ENV=test gulp test:api-v4:integration:separate-server",
@@ -139,16 +139,3 @@ index 01c208c60b..88d6cd993c 100644
"test:nodemon": "gulp test:nodemon",
"coverage": "COVERAGE=true mocha --require register-handlers.js --reporter html-cov > coverage.html; open coverage.html",
"sprites": "gulp sprites:compile",
-diff --git a/test/client/e2e/runner.js b/test/client/e2e/runner.js
-index 4c3829f785..4d40c020d4 100644
---- a/test/client/e2e/runner.js
-+++ b/test/client/e2e/runner.js
-@@ -18,7 +18,7 @@ if (opts.indexOf('--env') === -1) {
- }
-
- const spawn = require('cross-spawn');
--const runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' });
-+const runner = spawn('nightwatch', opts, { stdio: 'inherit' });
-
- runner.on('exit', function (code) {
- server.close();
diff --git a/pkgs/shabitica/patches/free-group-plans.patch b/pkgs/shabitica/patches/free-group-plans.patch
index 3ad0657..3243f51 100644
--- a/pkgs/shabitica/patches/free-group-plans.patch
+++ b/pkgs/shabitica/patches/free-group-plans.patch
@@ -14,7 +14,7 @@ Date: Tue Mar 27 05:37:23 2018 +0200
Filename: free-group-plans.patch
diff --git a/test/api/unit/models/group.test.js b/test/api/unit/models/group.test.js
-index 0a2b45b571..1470f0ad5d 100644
+index 85557ba418..7d32e6f9f8 100644
--- a/test/api/unit/models/group.test.js
+++ b/test/api/unit/models/group.test.js
@@ -1,4 +1,3 @@
@@ -25,12 +25,12 @@ index 0a2b45b571..1470f0ad5d 100644
@@ -17,7 +16,6 @@ import {
} from '../../../../website/server/libs/webhook';
import * as email from '../../../../website/server/libs/email';
- import { TAVERN_ID } from '../../../../website/common/script/';
+ import { TAVERN_ID } from '../../../../website/common/script/constants';
-import shared from '../../../../website/common';
describe('Group Model', () => {
- let party, questLeader, participatingMember, sleepingParticipatingMember, nonParticipatingMember, undecidedMember;
-@@ -1167,32 +1165,21 @@ describe('Group Model', () => {
+ let party; let questLeader; let participatingMember;
+@@ -1175,32 +1173,21 @@ describe('Group Model', () => {
expect(party).to.not.exist;
});
@@ -47,7 +47,7 @@ index 0a2b45b571..1470f0ad5d 100644
- });
+ await party.leave(participatingMember);
- party = await Group.findOne({_id: party._id});
+ party = await Group.findOne({ _id: party._id });
- expect(party).to.exist;
- expect(party.memberCount).to.eql(1);
+ expect(party).to.not.exist;
@@ -66,9 +66,9 @@ index 0a2b45b571..1470f0ad5d 100644
- });
+ await party.leave(questLeader);
- party = await Group.findOne({_id: party._id});
+ party = await Group.findOne({ _id: party._id });
expect(party).to.exist;
-@@ -2341,7 +2328,7 @@ describe('Group Model', () => {
+@@ -2362,7 +2349,7 @@ describe('Group Model', () => {
context('isSubscribed', () => {
it('returns false if group does not have customer id', () => {
@@ -77,7 +77,7 @@ index 0a2b45b571..1470f0ad5d 100644
});
it('returns true if group does not have plan.dateTerminated', () => {
-@@ -2349,20 +2336,6 @@ describe('Group Model', () => {
+@@ -2370,20 +2357,6 @@ describe('Group Model', () => {
expect(party.isSubscribed()).to.be.true;
});
@@ -98,7 +98,7 @@ index 0a2b45b571..1470f0ad5d 100644
});
context('hasNotCancelled', () => {
-@@ -2375,46 +2348,14 @@ describe('Group Model', () => {
+@@ -2396,46 +2369,14 @@ describe('Group Model', () => {
expect(party.hasNotCancelled()).to.be.true;
});
@@ -146,10 +146,10 @@ index 0a2b45b571..1470f0ad5d 100644
});
});
diff --git a/test/api/unit/models/user.test.js b/test/api/unit/models/user.test.js
-index 1e82b58f97..d1c5b0804a 100644
+index f8eedfc1c8..f7b2b5e85f 100644
--- a/test/api/unit/models/user.test.js
+++ b/test/api/unit/models/user.test.js
-@@ -356,20 +356,6 @@ describe('User Model', () => {
+@@ -357,20 +357,6 @@ describe('User Model', () => {
expect(user.hasCancelled()).to.be.false;
});
@@ -171,17 +171,16 @@ index 1e82b58f97..d1c5b0804a 100644
context('pre-save hook', () => {
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 1695d3966d..27f1a5c628 100644
+index a3c50c38df..095e1ea58d 100644
--- a/test/api/v3/integration/groups/POST-groups_invite.test.js
+++ b/test/api/v3/integration/groups/POST-groups_invite.test.js
-@@ -1,14 +1,11 @@
+@@ -2,13 +2,11 @@ import { v4 as generateUUID } from 'uuid';
+ import nconf from 'nconf';
import {
generateUser,
- generateGroup,
translate as t,
} from '../../../../helpers/api-integration/v3';
- import { v4 as generateUUID } from 'uuid';
--import nconf from 'nconf';
const INVITES_LIMIT = 100;
const PARTY_LIMIT_MEMBERS = 30;
@@ -189,16 +188,16 @@ index 1695d3966d..27f1a5c628 100644
describe('Post /groups/:groupId/invite', () => {
let inviter;
-@@ -316,27 +313,6 @@ describe('Post /groups/:groupId/invite', () => {
+@@ -319,27 +317,6 @@ describe('Post /groups/:groupId/invite', () => {
});
});
- it('returns an error when a user has sent the max number of email invites', async () => {
-- let inviterWithMax = await generateUser({
+- const inviterWithMax = await generateUser({
- invitesSent: MAX_EMAIL_INVITES_BY_USER,
- balance: 4,
- });
-- let tmpGroup = await inviterWithMax.post('/groups', {
+- const tmpGroup = await inviterWithMax.post('/groups', {
- name: groupName,
- type: 'guild',
- });
@@ -210,31 +209,31 @@ index 1695d3966d..27f1a5c628 100644
- .to.eventually.be.rejected.and.eql({
- code: 401,
- error: 'NotAuthorized',
-- message: t('inviteLimitReached', {techAssistanceEmail: nconf.get('ADMIN_EMAIL')}),
+- message: t('inviteLimitReached', { techAssistanceEmail: nconf.get('ADMIN_EMAIL') }),
- });
- });
-
it('invites a user to a group by email', async () => {
- let res = await inviter.post(`/groups/${group._id}/invite`, {
+ const res = await inviter.post(`/groups/${group._id}/invite`, {
emails: [testInvite],
-@@ -405,25 +381,6 @@ describe('Post /groups/:groupId/invite', () => {
+@@ -408,25 +385,6 @@ describe('Post /groups/:groupId/invite', () => {
expect(invitedUser.invitations.guilds[0].id).to.equal(group._id);
expect(invite).to.exist;
});
-
- it('invites marks invite with cancelled plan', async () => {
-- let cancelledPlanGroup = await generateGroup(inviter, {
+- const cancelledPlanGroup = await generateGroup(inviter, {
- type: 'guild',
- name: generateUUID(),
- });
- await cancelledPlanGroup.createCancelledSubscription();
-
-- let newUser = await generateUser();
-- let invite = await inviter.post(`/groups/${cancelledPlanGroup._id}/invite`, {
+- const newUser = await generateUser();
+- const invite = await inviter.post(`/groups/${cancelledPlanGroup._id}/invite`, {
- uuids: [newUser._id],
-- emails: [{name: 'test', email: 'test@habitica.com'}],
+- emails: [{ name: 'test', email: 'test@habitica.com' }],
- });
-- let invitedUser = await newUser.get('/user');
+- const invitedUser = await newUser.get('/user');
-
- expect(invitedUser.invitations.guilds[0].id).to.equal(cancelledPlanGroup._id);
- expect(invitedUser.invitations.guilds[0].cancelledPlan).to.be.true;
@@ -243,50 +242,54 @@ index 1695d3966d..27f1a5c628 100644
});
describe('guild invites', () => {
-diff --git a/website/client/components/group-plans/index.vue b/website/client/components/group-plans/index.vue
-index 82a20d244d..9a5e64926f 100644
---- a/website/client/components/group-plans/index.vue
-+++ b/website/client/components/group-plans/index.vue
-@@ -6,11 +6,6 @@
- exact, :class="{'active': $route.name === 'groupPlanDetailTaskInformation'}") {{ $t('groupTaskBoard') }}
- router-link.nav-link(:to="{name: 'groupPlanDetailInformation', params: {groupId}}",
- exact, :class="{'active': $route.name === 'groupPlanDetailInformation'}") {{ $t('groupInformation') }}
-- router-link.nav-link(
-- v-if='isLeader',
-- :to="{name: 'groupPlanBilling', params: {groupId}}",
-- exact,
-- :class="{'active': $route.name === 'groupPlanBilling'}") {{ $t('groupBilling') }}
-
- .col-12
- router-view
-diff --git a/website/client/components/group-plans/taskInformation.vue b/website/client/components/group-plans/taskInformation.vue
-index a30df3683b..f00a229a67 100644
---- a/website/client/components/group-plans/taskInformation.vue
-+++ b/website/client/components/group-plans/taskInformation.vue
+diff --git a/website/client/src/components/group-plans/index.vue b/website/client/src/components/group-plans/index.vue
+index 25b597c2e7..0e97a60ecb 100644
+--- a/website/client/src/components/group-plans/index.vue
++++ b/website/client/src/components/group-plans/index.vue
+@@ -18,15 +18,6 @@
+ >
+ {{ $t('groupInformation') }}
+ </router-link>
+- <router-link
+- v-if="isLeader"
+- class="nav-link"
+- :to="{name: 'groupPlanBilling', params: {groupId}}"
+- exact="exact"
+- :class="{'active': $route.name === 'groupPlanBilling'}"
+- >
+- {{ $t('groupBilling') }}
+- </router-link>
+ </secondary-menu>
+ <div class="col-12">
+ <router-view />
+diff --git a/website/client/src/components/group-plans/taskInformation.vue b/website/client/src/components/group-plans/taskInformation.vue
+index d98baeedd6..28bf507699 100644
+--- a/website/client/src/components/group-plans/taskInformation.vue
++++ b/website/client/src/components/group-plans/taskInformation.vue
@@ -1,6 +1,5 @@
- <template lang="pug">
- .standard-page
-- group-plan-overview-modal
- task-modal(
- :task="workingTask",
- :purpose="taskFormPurpose",
-@@ -70,7 +69,6 @@
- import taskDefaults from 'common/script/libs/taskDefaults';
+ <template>
+ <div class="standard-page">
+- <group-plan-overview-modal />
+ <task-modal
+ ref="taskModal"
+ :task="workingTask"
+@@ -111,7 +110,6 @@ import groupBy from 'lodash/groupBy';
+ import taskDefaults from '@/../../common/script/libs/taskDefaults';
import TaskColumn from '../tasks/column';
import TaskModal from '../tasks/taskModal';
-import GroupPlanOverviewModal from './groupPlanOverviewModal';
- import positiveIcon from 'assets/svg/positive.svg';
- import filterIcon from 'assets/svg/filter.svg';
-@@ -91,7 +89,6 @@ export default {
+ import positiveIcon from '@/assets/svg/positive.svg';
+ import filterIcon from '@/assets/svg/filter.svg';
+@@ -127,7 +125,6 @@ export default {
components: {
TaskColumn,
TaskModal,
- GroupPlanOverviewModal,
},
+ props: ['groupId'],
data () {
- return {
-@@ -137,10 +134,6 @@ export default {
+@@ -214,10 +211,6 @@ export default {
mounted () {
if (!this.searchId) this.searchId = this.groupId;
this.load();
@@ -295,61 +298,105 @@ index a30df3683b..f00a229a67 100644
- this.$root.$emit('bv::show::modal', 'group-plan-overview');
- }
},
- computed: {
- ...mapState({user: 'user.data'}),
-diff --git a/website/client/components/groups/groupPlan.vue b/website/client/components/groups/groupPlan.vue
-index 2561b2946b..5f43a03430 100644
---- a/website/client/components/groups/groupPlan.vue
-+++ b/website/client/components/groups/groupPlan.vue
-@@ -30,21 +30,8 @@ div
- h2 In-Game Benefits
- p Group members get an exclusive Jackalope Mount, as well as full subscription benefits, including special monthly equipment sets and the ability to buy gems with gold.
-
-- #upgrading-group.container.payment-options(v-if='upgradingGroup._id')
-+ .container.upgrade-group(v-if='upgradingGroup._id')
- h1.text-center.purple-header Are you ready to upgrade?
-- .row
-- .col-12.text-center
-- .purple-box
-- .amount-section
-- .dollar $
-- .number 9
-- .name Group Owner Subscription
-- .plus
-- .svg-icon(v-html="icons.positiveIcon")
-- .amount-section
-- .dollar $
-- .number 3
-- .name Each Individual Group Member
-
- .container.col-6.offset-3.create-option(v-if='!upgradingGroup._id')
- .row
-@@ -52,23 +39,8 @@ div
- .row
- .col-12.text-center
- button.btn.btn-primary.create-group(@click='launchModal("create")') Create Your New Group
-- .row.pricing
-- .col-5
-- .dollar $
-- .number 9
-- .name
-- div Group Owner
-- div Subscription
-- .col-1
-- .plus +
-- .col-6
-- .dollar $
-- .number 3
-- .name
-- div Each Additional
-- div Member
-
-- b-modal#group-plan-modal(title="Select Payment", size='md', hide-footer=true)
-+ b-modal#group-plan-modal(:title="$t('createAGroup')", size='md', hide-footer=true)
- .col-12(v-if='activePage === PAGES.CREATE_GROUP')
- .form-group
- label.control-label(for='new-group-name') Name
-@@ -91,36 +63,6 @@ div
+ methods: {
+ async load () {
+diff --git a/website/client/src/components/groups/groupPlan.vue b/website/client/src/components/groups/groupPlan.vue
+index a4b1f41a86..a6be5afc02 100644
+--- a/website/client/src/components/groups/groupPlan.vue
++++ b/website/client/src/components/groups/groupPlan.vue
+@@ -53,46 +53,11 @@
+ </div>
+ <div
+ v-if="upgradingGroup._id"
+- id="upgrading-group"
+- class="container payment-options"
++ class="container upgrade-group"
+ >
+ <h1 class="text-center purple-header">
+ Are you ready to upgrade?
+ </h1>
+- <div class="row">
+- <div class="col-12 text-center">
+- <div class="purple-box">
+- <div class="amount-section">
+- <div class="dollar">
+- $
+- </div>
+- <div class="number">
+- 9
+- </div>
+- <div class="name">
+- Group Owner Subscription
+- </div>
+- </div>
+- <div class="plus">
+- <div
+- class="svg-icon"
+- v-html="icons.positiveIcon"
+- ></div>
+- </div>
+- <div class="amount-section">
+- <div class="dollar">
+- $
+- </div>
+- <div class="number">
+- 3
+- </div>
+- <div class="name">
+- Each Individual Group Member
+- </div>
+- </div>
+- </div>
+- </div>
+- </div>
+ </div>
+ <div
+ v-if="!upgradingGroup._id"
+@@ -113,42 +78,11 @@
+ </button>
+ </div>
+ </div>
+- <div class="row pricing">
+- <div class="col-5">
+- <div class="dollar">
+- $
+- </div>
+- <div class="number">
+- 9
+- </div>
+- <div class="name">
+- <div>Group Owner</div>
+- <div>Subscription</div>
+- </div>
+- </div>
+- <div class="col-1">
+- <div class="plus">
+- +
+- </div>
+- </div>
+- <div class="col-6">
+- <div class="dollar">
+- $
+- </div>
+- <div class="number">
+- 3
+- </div>
+- <div class="name">
+- <div>Each Additional</div>
+- <div>Member</div>
+- </div>
+- </div>
+- </div>
+ </div>
+ </div>
+ <b-modal
+ id="group-plan-modal"
+- title="Select Payment"
++ :title="$t('createAGroup')"
+ size="md"
+ hide-footer="hide-footer"
+ >
+@@ -234,36 +168,6 @@
</template>
<style lang="scss" scoped>
@@ -386,7 +433,7 @@ index 2561b2946b..5f43a03430 100644
.header {
background: #432874;
background: linear-gradient(180deg, #4F2A93 0%, #432874 100%);
-@@ -195,88 +137,21 @@ div
+@@ -338,88 +242,21 @@
height: 96px;
}
@@ -474,13 +521,13 @@ index 2561b2946b..5f43a03430 100644
</style>
<script>
- import { mapState } from 'client/libs/store';
- import positiveIcon from 'assets/svg/positive.svg';
+ import { mapState } from '@/libs/store';
+ import positiveIcon from '@/assets/svg/positive.svg';
+import axios from 'axios';
export default {
data () {
-@@ -287,9 +162,7 @@ export default {
+@@ -430,9 +267,7 @@ export default {
PAGES: {
CREATE_GROUP: 'create-group',
UPGRADE_GROUP: 'upgrade-group',
@@ -490,7 +537,7 @@ index 2561b2946b..5f43a03430 100644
newGroup: {
type: 'guild',
privacy: 'private',
-@@ -324,21 +197,25 @@ export default {
+@@ -467,21 +302,25 @@ export default {
this.activePage = page;
window.scrollTo(0, 0);
},
@@ -519,7 +566,7 @@ index 2561b2946b..5f43a03430 100644
+
+ if (response.status >= 400) {
+ alert(`Error: ${response.message}`);
-+ return;
++ return null;
+ }
+
+ let newGroup = response.data.data;
@@ -527,21 +574,21 @@ index 2561b2946b..5f43a03430 100644
+ this.$store.state.groupPlans.push(newGroup);
+ this.$router.push(`/group-plans/${newGroup._id}/task-information`);
}
- },
- },
-diff --git a/website/client/router/index.js b/website/client/router/index.js
-index 05663006bc..0a760836f0 100644
---- a/website/client/router/index.js
-+++ b/website/client/router/index.js
-@@ -70,7 +70,6 @@ const GroupPlansAppPage = () => import(/* webpackChunkName: "guilds" */ 'client/
+
+ return null;
+diff --git a/website/client/src/router/index.js b/website/client/src/router/index.js
+index 196e97b282..06e44b2707 100644
+--- a/website/client/src/router/index.js
++++ b/website/client/src/router/index.js
+@@ -71,7 +71,6 @@ const GroupPlansAppPage = () => import(/* webpackChunkName: "guilds" */ '@/compo
// Group Plans
- const GroupPlanIndex = () => import(/* webpackChunkName: "group-plans" */ 'client/components/group-plans/index');
- const GroupPlanTaskInformation = () => import(/* webpackChunkName: "group-plans" */ 'client/components/group-plans/taskInformation');
--const GroupPlanBilling = () => import(/* webpackChunkName: "group-plans" */ 'client/components/group-plans/billing');
+ const GroupPlanIndex = () => import(/* webpackChunkName: "group-plans" */ '@/components/group-plans/index');
+ const GroupPlanTaskInformation = () => import(/* webpackChunkName: "group-plans" */ '@/components/group-plans/taskInformation');
+-const GroupPlanBilling = () => import(/* webpackChunkName: "group-plans" */ '@/components/group-plans/billing');
// Challenges
- const ChallengeIndex = () => import(/* webpackChunkName: "challenges" */ 'client/components/challenges/index');
-@@ -153,12 +152,6 @@ const router = new VueRouter({
+ const ChallengeIndex = () => import(/* webpackChunkName: "challenges" */ '@/components/challenges/index');
+@@ -160,12 +159,6 @@ const router = new VueRouter({
component: GroupPage,
props: true,
},
@@ -555,30 +602,30 @@ index 05663006bc..0a760836f0 100644
},
{
diff --git a/website/server/controllers/api-v3/groups.js b/website/server/controllers/api-v3/groups.js
-index 96ffc6ed7e..dc35d5db83 100644
+index 7048fba428..27873c888a 100644
--- a/website/server/controllers/api-v3/groups.js
+++ b/website/server/controllers/api-v3/groups.js
-@@ -23,6 +23,7 @@ import {
- } from '../../libs/invites';
+@@ -24,6 +24,7 @@ import {
import common from '../../../common';
import apiError from '../../libs/apiError';
+ import { model as UserNotification } from '../../models/userNotification';
+import payments from '../../libs/payments/payments';
const MAX_EMAIL_INVITES_BY_USER = 200;
const TECH_ASSISTANCE_EMAIL = nconf.get('ADMIN_EMAIL');
-@@ -162,8 +163,6 @@ api.createGroupPlan = {
- let user = res.locals.user;
- let group = new Group(Group.sanitize(req.body.groupToCreate));
+@@ -166,8 +167,6 @@ api.createGroupPlan = {
+ const { user } = res.locals;
+ const group = new Group(Group.sanitize(req.body.groupToCreate));
- req.checkBody('paymentType', res.t('paymentTypeRequired')).notEmpty();
-
- let validationErrors = req.validationErrors();
+ const validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
-@@ -173,6 +172,18 @@ api.createGroupPlan = {
+@@ -177,6 +176,18 @@ api.createGroupPlan = {
user.guilds.push(group._id);
- let results = await Promise.all([user.save(), group.save()]);
+ const results = await Promise.all([user.save(), group.save()]);
+
+ await payments.createSubscription({
+ user,
@@ -591,36 +638,37 @@ index 96ffc6ed7e..dc35d5db83 100644
+ groupId: group._id,
+ });
+
- let savedGroup = results[1];
+ const savedGroup = results[1];
// Instead of populate we make a find call manually because of https://github.com/Automattic/mongoose/issues/3833
diff --git a/website/server/models/group.js b/website/server/models/group.js
-index 489aba6938..8b9133d85e 100644
+index 7a6abe0e17..00fbe78aa9 100644
--- a/website/server/models/group.js
+++ b/website/server/models/group.js
@@ -1,4 +1,3 @@
-import moment from 'moment';
import mongoose from 'mongoose';
- import {
- model as User,
-@@ -1547,19 +1546,16 @@ schema.methods.checkChatSpam = function groupCheckChatSpam (user) {
+ import _ from 'lodash';
+ import validator from 'validator';
+@@ -1604,20 +1603,16 @@ schema.methods.checkChatSpam = function groupCheckChatSpam (user) {
};
schema.methods.isSubscribed = function isSubscribed () {
-- let now = new Date();
- let plan = this.purchased.plan;
-- return plan && plan.customerId && (!plan.dateTerminated || moment(plan.dateTerminated).isAfter(now));
+- const now = new Date();
+ const { plan } = this.purchased;
+- return plan && plan.customerId
+- && (!plan.dateTerminated || moment(plan.dateTerminated).isAfter(now));
+ return Boolean(plan && plan.customerId);
};
schema.methods.hasNotCancelled = function hasNotCancelled () {
-- let plan = this.purchased.plan;
+- const { plan } = this.purchased;
- return Boolean(this.isSubscribed() && !plan.dateTerminated);
+ return this.isSubscribed();
};
-schema.methods.hasCancelled = function hasNotCancelled () {
-- let plan = this.purchased.plan;
+- const { plan } = this.purchased;
- return Boolean(this.isSubscribed() && plan.dateTerminated);
+schema.methods.hasCancelled = function hasCancelled () {
+ return !this.isSubscribed();
diff --git a/pkgs/shabitica/patches/hardcoded-server-version.patch b/pkgs/shabitica/patches/hardcoded-server-version.patch
index 9cda72e..8786d2c 100644
--- a/pkgs/shabitica/patches/hardcoded-server-version.patch
+++ b/pkgs/shabitica/patches/hardcoded-server-version.patch
@@ -10,7 +10,7 @@ Date: Wed Mar 28 07:23:59 2018 +0200
Filename: hardcoded-server-version.patch
diff --git a/website/server/middlewares/response.js b/website/server/middlewares/response.js
-index 420ba9e529..1769d57ded 100644
+index 945cf19dea..3bae01eed3 100644
--- a/website/server/middlewares/response.js
+++ b/website/server/middlewares/response.js
@@ -1,4 +1,3 @@
@@ -18,7 +18,7 @@ index 420ba9e529..1769d57ded 100644
import {
model as UserNotification,
} from '../models/userNotification';
-@@ -20,7 +19,7 @@ module.exports = function responseHandler (req, res, next) {
+@@ -20,7 +19,7 @@ export default function responseHandler (req, res, next) {
response.userV = user._v;
}
diff --git a/pkgs/shabitica/patches/html-test-reports.patch b/pkgs/shabitica/patches/html-test-reports.patch
index ec94ee4..e67d8c7 100644
--- a/pkgs/shabitica/patches/html-test-reports.patch
+++ b/pkgs/shabitica/patches/html-test-reports.patch
@@ -13,44 +13,44 @@ Date: Tue Apr 3 05:09:43 2018 +0200
Filename: html-test-reports.patch
diff --git a/gulp/gulp-tests.js b/gulp/gulp-tests.js
-index 80b331ec17..4dbf4f26fc 100644
+index c7e97b9641..4494a97543 100644
--- a/gulp/gulp-tests.js
+++ b/gulp/gulp-tests.js
-@@ -170,7 +170,7 @@ gulp.task('test:content:safe', gulp.series('test:prepare:build', (cb) => {
+@@ -165,7 +165,7 @@ gulp.task('test:content:safe', gulp.series('test:prepare:build', cb => {
- gulp.task('test:api:unit', (done) => {
- let runner = exec(
+ gulp.task('test:api:unit', done => {
+ const runner = exec(
- testBin('istanbul cover --dir coverage/api-unit mocha -- test/api/unit --recursive --require ./test/helpers/start-server'),
+ testBin('istanbul cover --dir coverage/api-unit mocha -- test/api/unit --reporter mocha-multi-reporters --reporter-options configFile=mocha-reporters.json --recursive --require ./test/helpers/start-server'),
CONTENT_OPTIONS,
- (err) => {
+ err => {
if (err) {
-@@ -189,7 +189,7 @@ gulp.task('test:api:unit:watch', () => {
+@@ -182,7 +182,7 @@ gulp.task('test:api:unit:watch', () => gulp.watch(['website/server/libs/*', 'tes
- gulp.task('test:api-v3:integration', (done) => {
- let runner = exec(
+ gulp.task('test:api-v3:integration', done => {
+ const runner = exec(
- testBin('istanbul cover --dir coverage/api-v3-integration --report lcovonly mocha -- test/api/v3/integration --recursive --require ./test/helpers/start-server'),
+ testBin('istanbul cover --dir coverage/api-v3-integration --report lcovonly mocha -- test/api/v3/integration --reporter mocha-multi-reporters --reporter-options configFile=mocha-reporters.json --recursive --require ./test/helpers/start-server'),
CONTENT_OPTIONS,
- (err) => {
+ err => {
if (err) {
-@@ -211,7 +211,7 @@ gulp.task('test:api-v3:integration:watch', () => {
+@@ -202,7 +202,7 @@ gulp.task('test:api-v3:integration:watch', () => gulp.watch([
- gulp.task('test:api-v3:integration:separate-server', (done) => {
- let runner = exec(
+ gulp.task('test:api-v3:integration:separate-server', done => {
+ const runner = exec(
- testBin('mocha test/api/v3/integration --recursive --require ./test/helpers/start-server', 'LOAD_SERVER=0'),
+ testBin('mocha test/api/v3/integration --reporter mocha-multi-reporters --reporter-options configFile=mocha-reporters.json --recursive --require ./test/helpers/start-server', 'LOAD_SERVER=0'),
CONTENT_OPTIONS,
- (err) => done(err)
+ err => done(err),
);
-@@ -221,7 +221,7 @@ gulp.task('test:api-v3:integration:separate-server', (done) => {
+@@ -212,7 +212,7 @@ gulp.task('test:api-v3:integration:separate-server', done => {
- gulp.task('test:api-v4:integration', (done) => {
- let runner = exec(
+ gulp.task('test:api-v4:integration', done => {
+ const runner = exec(
- testBin('istanbul cover --dir coverage/api-v4-integration --report lcovonly mocha -- test/api/v4 --recursive --require ./test/helpers/start-server'),
+ testBin('istanbul cover --dir coverage/api-v4-integration --report lcovonly mocha -- test/api/v4 --reporter mocha-multi-reporters --reporter-options configFile=mocha-reporters.json --recursive --require ./test/helpers/start-server'),
CONTENT_OPTIONS,
- (err) => {
+ err => {
if (err) {
diff --git a/mocha-reporters.json b/mocha-reporters.json
new file mode 100644
@@ -63,10 +63,10 @@ index 0000000000..347c750ab3
+ "mochaSimpleHtmlReporterReporterOptions": {"output": "test-report.html"}
+}
diff --git a/package.json b/package.json
-index 88d6cd993c..1d5f379a88 100644
+index 0dbe7d68dd..0251a63798 100644
--- a/package.json
+++ b/package.json
-@@ -112,9 +112,9 @@
+@@ -72,9 +72,9 @@
"test:api-v3:integration:separate-server": "NODE_ENV=test gulp test:api-v3:integration:separate-server",
"test:api-v4:integration": "gulp test:api-v4:integration",
"test:api-v4:integration:separate-server": "NODE_ENV=test gulp test:api-v4:integration:separate-server",
@@ -79,12 +79,12 @@ index 88d6cd993c..1d5f379a88 100644
"test:nodemon": "gulp test:nodemon",
"coverage": "COVERAGE=true mocha --require register-handlers.js --reporter html-cov > coverage.html; open coverage.html",
"sprites": "gulp sprites:compile",
-@@ -161,6 +161,8 @@
- "karma-spec-reporter": "0.0.32",
- "karma-webpack": "^3.0.0",
+@@ -93,6 +93,8 @@
+ "expect.js": "^0.3.1",
+ "istanbul": "^1.1.0-alpha.1",
"mocha": "^5.1.1",
+ "mocha-multi-reporters": "^1.1.7",
+ "mocha-simple-html-reporter": "^1.1.0",
- "monk": "^6.0.6",
- "nightwatch": "^1.0.16",
- "puppeteer": "^1.14.0",
+ "monk": "^7.1.1",
+ "require-again": "^2.0.0",
+ "sinon": "^7.2.4",
diff --git a/pkgs/shabitica/patches/invite-only-config-option.patch b/pkgs/shabitica/patches/invite-only-config-option.patch
index bcf2880..70940f9 100644
--- a/pkgs/shabitica/patches/invite-only-config-option.patch
+++ b/pkgs/shabitica/patches/invite-only-config-option.patch
@@ -10,7 +10,7 @@ Date: Mon Apr 2 06:30:04 2018 +0200
Filename: invite-only-config-option.patch
diff --git a/config.json.example b/config.json.example
-index 324e871af2..00287d0621 100644
+index 8bef015240..09f25c71d8 100644
--- a/config.json.example
+++ b/config.json.example
@@ -7,6 +7,7 @@
@@ -22,11 +22,11 @@ index 324e871af2..00287d0621 100644
"MAINTENANCE_MODE": "false",
"NODE_DB_URI": "mongodb://localhost/habitrpg",
diff --git a/website/server/libs/auth/index.js b/website/server/libs/auth/index.js
-index a11e9042db..bf459d5e63 100644
+index d39b1a1362..7eff5c8e87 100644
--- a/website/server/libs/auth/index.js
+++ b/website/server/libs/auth/index.js
-@@ -13,7 +13,9 @@ import { model as Group } from '../../models/group';
- import moment from 'moment';
+@@ -13,7 +13,9 @@ import { decrypt } from '../encryption';
+ import { model as Group } from '../../models/group';
import { loginRes } from './utils';
import { verifyUsername } from '../user/validation';
+import nconf from 'nconf';
@@ -35,7 +35,7 @@ index a11e9042db..bf459d5e63 100644
const USERNAME_LENGTH_MIN = 1;
const USERNAME_LENGTH_MAX = 20;
-@@ -146,9 +148,9 @@ async function registerLocal (req, res, { isV3 = false }) {
+@@ -155,9 +157,9 @@ async function registerLocal (req, res, { isV3 = false }) {
// we check for partyInvite for backward compatibility
if (req.query.groupInvite || req.query.partyInvite) {
let success = await _handleGroupInvitation(newUser, req.query.groupInvite || req.query.partyInvite);
diff --git a/pkgs/shabitica/patches/invite-only.patch b/pkgs/shabitica/patches/invite-only.patch
index b54f1f0..732b349 100644
--- a/pkgs/shabitica/patches/invite-only.patch
+++ b/pkgs/shabitica/patches/invite-only.patch
@@ -11,55 +11,62 @@ Date: Tue Mar 27 05:37:13 2018 +0200
Signed-off-by: aszlig <aszlig@nix.build>
Filename: invite-only.patch
-diff --git a/website/client/components/static/home.vue b/website/client/components/static/home.vue
-index 0180180773..265ff3d708 100644
---- a/website/client/components/static/home.vue
-+++ b/website/client/components/static/home.vue
-@@ -5,7 +5,7 @@
- a(href='http://www.enable-javascript.com/', target='_blank') {{ $t('jsDisabledLink') }}
-
- #intro-signup.purple-1
-- .container
-+ .container(v-if='invited')
- .row
- .col-12.col-md-6.col-lg-6
- img(src='~assets/images/home/home-main@3x.png', width='357px')
-@@ -24,6 +24,12 @@
- button.sign-up(@click="register()") {{$t('signup')}}
- .col-12
- .spacer.svg-icon(v-html='icons.spacer')
-+ .container(v-if='!invited')
-+ img(src='~assets/images/home/home-main@3x.png', width='357px')
-+ h1 {{$t('motivateYourself')}}
-+ p.section-main {{$t('timeToGetThingsDone', {userCountInMillions})}}
-+ .col-12
-+ .spacer.svg-icon(v-html='icons.spacer')
-
- #gamify-life.purple-2
- .container-fluid
-@@ -543,6 +549,17 @@
- if (this.passwordConfirm.length <= 3) return false;
- return this.passwordConfirm !== this.password;
- },
-+ invited () {
-+ let groupInvite = '';
-+ if (this.$route.query && this.$route.query.p) {
-+ groupInvite = this.$route.query.p;
-+ }
-+
-+ if (this.$route.query && this.$route.query.groupInvite) {
-+ groupInvite = this.$route.query.groupInvite;
-+ }
-+ return Boolean(groupInvite);
-+ },
+diff --git a/website/client/src/components/static/home.vue b/website/client/src/components/static/home.vue
+index 0d8dbe5650..422a10d117 100644
+--- a/website/client/src/components/static/home.vue
++++ b/website/client/src/components/static/home.vue
+@@ -12,7 +12,7 @@
+ id="intro-signup"
+ class="purple-1"
+ >
+- <div class="container">
++ <div class="container" v-if="invited">
+ <div class="row">
+ <div class="col-12 col-md-6 col-lg-6">
+ <img
+@@ -98,6 +98,19 @@
+ </div>
+ </div>
+ </div>
++ <div class="container" v-if="!invited">
++ <img src="~@/assets/images/home/home-main@3x.png" width="357px">
++ <h1>{{ $t('motivateYourself') }}</h1>
++ <p class="section-main">
++ {{ $t('timeToGetThingsDone', {userCountInMillions}) }}
++ </p>
++ <div class="col-12">
++ <div
++ class="spacer svg-icon"
++ v-html="icons.spacer"
++ ></div>
++ </div>
++ </div>
+ </div>
+ <div
+ id="gamify-life"
+@@ -726,6 +739,17 @@ export default {
+ if (this.passwordConfirm.length <= 3) return false;
+ return this.passwordConfirm !== this.password;
},
- watch: {
- username () {
++ invited () {
++ let groupInvite = '';
++ if (this.$route.query && this.$route.query.p) {
++ groupInvite = this.$route.query.p;
++ }
++
++ if (this.$route.query && this.$route.query.groupInvite) {
++ groupInvite = this.$route.query.groupInvite;
++ }
++ return Boolean(groupInvite);
++ },
+ },
+ watch: {
+ username () {
diff --git a/website/server/libs/auth/index.js b/website/server/libs/auth/index.js
-index 97867e40b5..3adf355408 100644
+index 3dfed682e3..047c43aec2 100644
--- a/website/server/libs/auth/index.js
+++ b/website/server/libs/auth/index.js
-@@ -50,7 +50,9 @@ async function _handleGroupInvitation (user, invite) {
+@@ -55,7 +55,9 @@ async function _handleGroupInvitation (user, invite) {
}
} catch (err) {
logger.error(err);
@@ -69,7 +76,7 @@ index 97867e40b5..3adf355408 100644
}
function hasLocalAuth (user) {
-@@ -141,7 +143,11 @@ async function registerLocal (req, res, { isV3 = false }) {
+@@ -150,7 +152,11 @@ async function registerLocal (req, res, { isV3 = false }) {
// we check for partyInvite for backward compatibility
if (req.query.groupInvite || req.query.partyInvite) {
@@ -81,4 +88,4 @@ index 97867e40b5..3adf355408 100644
+ throw new NotAuthorized(res.t('inviteOnly'));
}
- let savedUser = await newUser.save();
+ const savedUser = await newUser.save();
diff --git a/pkgs/shabitica/patches/kill-footer.patch b/pkgs/shabitica/patches/kill-footer.patch
index c75e61e..63f47cb 100644
--- a/pkgs/shabitica/patches/kill-footer.patch
+++ b/pkgs/shabitica/patches/kill-footer.patch
@@ -12,105 +12,290 @@ Date: Tue Mar 27 05:37:21 2018 +0200
Signed-off-by: aszlig <aszlig@nix.build>
Filename: kill-footer.patch
-diff --git a/website/client/components/appFooter.vue b/website/client/components/appFooter.vue
-index 8478089836..175a7432d6 100644
---- a/website/client/components/appFooter.vue
-+++ b/website/client/components/appFooter.vue
-@@ -2,93 +2,6 @@
- .row.footer-row
- buy-gems-modal(v-if='user')
- //modify-inventory(v-if="isUserLoaded")
-- footer.col-12.expanded
-- .row
-- .col-12.col-md-2
-- h3 {{ $t('footerCompany') }}
-- ul
-- li
-- router-link(to='/static/features') {{ $t('companyAbout') }}
-- li
-- a(href='https://habitica.wordpress.com/', target='_blank') {{ $t('companyBlog') }}
-- li
-- a(href='http://blog.habitrpg.com/', target='_blank') {{ $t('tumblr') }}
-- li
-- router-link(to='/static/faq') {{ $t('FAQ') }}
-- li
-- a(href='http://habitica.fandom.com/wiki/Whats_New', target='_blank') {{ $t('oldNews') }}
-- li
-- router-link(to='/static/merch') {{ $t('merch') }}
-- li
-- router-link(to='/static/press-kit') {{ $t('presskit') }}
-- li
-- router-link(to='/static/contact') {{ $t('contactUs') }}
-- .col-12.col-md-2
-- h3 {{ $t('footerCommunity') }}
-- ul
-- li
-- a(target="_blanck", href="/static/community-guidelines") {{ $t('communityGuidelines') }}
-- li
-- router-link(to='/hall/contributors') {{ $t('hall') }}
-- li
-- router-link(to='/groups/guild/a29da26b-37de-4a71-b0c6-48e72a900dac') {{ $t('reportBug') }}
-- li
-- a(href='https://trello.com/c/odmhIqyW/440-read-first-table-of-contents', target='_blank') {{ $t('requestFeature') }}
-- li(v-html='$t("communityExtensions")')
-- li(v-html='$t("communityForum")')
-- .col-12.col-md-6
-- .row
-- .col-6
-- h3 {{ $t('footerDevs') }}
-- ul
-- li
-- a(href='/apidoc', target='_blank') {{ $t('APIv3') }}
-- li
-- a(:href="getDataDisplayToolUrl", target='_blank') {{ $t('dataDisplayTool') }}
-- li
-- a(href='http://habitica.fandom.com/wiki/Guidance_for_Blacksmiths', target='_blank') {{ $t('guidanceForBlacksmiths') }}
-- .row
-- .col-12.col-md-8 {{ $t('donateText3') }}
-- .col-12.col-md-4
-- button.btn.btn-contribute.btn-flat(@click="donate()", v-if="user")
-- .svg-icon.heart(v-html="icons.heart")
-- .text {{ $t('companyDonate') }}
-- .btn.btn-contribute.btn-flat(v-else)
-- a(href='http://habitica.fandom.com/wiki/Contributing_to_Habitica', target='_blank')
-- .svg-icon.heart(v-html="icons.heart")
-- .text {{ $t('companyContribute') }}
-- .row
-- .col-12
-- hr
-- .row
-- .col-12.col-md-5
-- | © 2019 Habitica. All rights reserved.
-- .debug.float-left(v-if="!IS_PRODUCTION && isUserLoaded")
-- button.btn.btn-primary(@click="debugMenuShown = !debugMenuShown") Toggle Debug Menu
-- .debug-group(v-if="debugMenuShown")
-- a.btn.btn-secondary(@click="setHealthLow()") Health = 1
-- a.btn.btn-secondary(@click="addMissedDay(1)") +1 Missed Day
-- a.btn.btn-secondary(@click="addMissedDay(2)") +2 Missed Days
-- a.btn.btn-secondary(@click="addMissedDay(8)") +8 Missed Days
-- a.btn.btn-secondary(@click="addMissedDay(32)") +32 Missed Days
-- a.btn.btn-secondary(@click="addTenGems()") +10 Gems
-- a.btn.btn-secondary(@click="addHourglass()") +1 Mystic Hourglass
-- a.btn.btn-secondary(@click="addGold()") +500GP
-- a.btn.btn-secondary(@click="plusTenHealth()") + 10HP
-- a.btn.btn-secondary(@click="addMana()") +MP
-- a.btn.btn-secondary(@click="addLevelsAndGold()") +Exp +GP +MP
-- a.btn.btn-secondary(@click="addExp()") +Exp
-- a.btn.btn-secondary(@click="addOneLevel()") +1 Level
-- a.btn.btn-secondary(@click="addQuestProgress()", tooltip="+1000 to boss quests. 300 items to collection quests") Quest Progress Up
-- a.btn.btn-secondary(@click="makeAdmin()") Make Admin
-- a.btn.btn-secondary(@click="openModifyInventoryModal()") Modify Inventory
-- .col-12.col-md-2.text-center
-- .logo.svg-icon(v-html='icons.gryphon')
-- .col-12.col-md-5.text-right
-- span.ml-4
-- a(target="_blanck", href="/static/privacy") {{ $t('privacy') }}
-- span.ml-4
-- a(target="_blanck", href="/static/terms") {{ $t('terms') }}
+diff --git a/website/client/src/components/appFooter.vue b/website/client/src/components/appFooter.vue
+index 3a4d0b63cf..78f6d0ac0e 100644
+--- a/website/client/src/components/appFooter.vue
++++ b/website/client/src/components/appFooter.vue
+@@ -2,262 +2,6 @@
+ <div class="row footer-row">
+ <buy-gems-modal v-if="user" />
+ <!--modify-inventory(v-if="isUserLoaded")-->
+- <footer class="col-12 expanded">
+- <div class="row">
+- <div class="col-12 col-md-2">
+- <h3>{{ $t('footerCompany') }}</h3>
+- <ul>
+- <li>
+- <router-link to="/static/features">
+- {{ $t('companyAbout') }}
+- </router-link>
+- </li>
+- <li>
+- <a
+- href="https://habitica.wordpress.com/"
+- target="_blank"
+- >{{ $t('companyBlog') }}</a>
+- </li>
+- <li>
+- <a
+- href="http://blog.habitrpg.com/"
+- target="_blank"
+- >{{ $t('tumblr') }}</a>
+- </li>
+- <li>
+- <router-link to="/static/faq">
+- {{ $t('FAQ') }}
+- </router-link>
+- </li>
+- <li>
+- <a
+- href="http://habitica.fandom.com/wiki/Whats_New"
+- target="_blank"
+- >{{ $t('oldNews') }}</a>
+- </li>
+- <li>
+- <router-link to="/static/merch">
+- {{ $t('merch') }}
+- </router-link>
+- </li>
+- <li>
+- <router-link to="/static/press-kit">
+- {{ $t('presskit') }}
+- </router-link>
+- </li>
+- <li>
+- <router-link to="/static/contact">
+- {{ $t('contactUs') }}
+- </router-link>
+- </li>
+- </ul>
+- </div>
+- <div class="col-12 col-md-2">
+- <h3>{{ $t('footerCommunity') }}</h3>
+- <ul>
+- <li>
+- <a
+- target="_blanck"
+- href="/static/community-guidelines"
+- >{{ $t('communityGuidelines') }}</a>
+- </li>
+- <li>
+- <router-link to="/hall/contributors">
+- {{ $t('hall') }}
+- </router-link>
+- </li>
+- <li>
+- <router-link
+- to="/groups/guild/a29da26b-37de-4a71-b0c6-48e72a900dac"
+- >
+- {{ $t('reportBug') }}
+- </router-link>
+- </li>
+- <li>
+- <a
+- href="https://trello.com/c/odmhIqyW/440-read-first-table-of-contents"
+- target="_blank"
+- >{{ $t('requestFeature') }}</a>
+- </li>
+- <li v-html="$t('communityExtensions')"></li>
+- <li v-html="$t('communityForum')"></li>
+- </ul>
+- </div>
+- <div class="col-12 col-md-6">
+- <div class="row">
+- <div class="col-6">
+- <h3>{{ $t('footerDevs') }}</h3>
+- <ul>
+- <li>
+- <a
+- href="/apidoc"
+- target="_blank"
+- >{{ $t('APIv3') }}</a>
+- </li>
+- <li>
+- <a
+- :href="getDataDisplayToolUrl"
+- target="_blank"
+- >{{ $t('dataDisplayTool') }}</a>
+- </li>
+- <li>
+- <a
+- href="http://habitica.fandom.com/wiki/Guidance_for_Blacksmiths"
+- target="_blank"
+- >{{ $t('guidanceForBlacksmiths') }}</a>
+- </li>
+- </ul>
+- </div>
+- </div>
+- <div class="row">
+- <div class="col-12 col-md-8">
+- {{ $t('donateText3') }}
+- </div>
+- <div class="col-12 col-md-4">
+- <button
+- v-if="user"
+- class="btn btn-contribute btn-flat"
+- @click="donate()"
+- >
+- <div
+- class="svg-icon heart"
+- v-html="icons.heart"
+- ></div>
+- <div class="text">
+- {{ $t('companyDonate') }}
+- </div>
+- </button>
+- <div
+- v-else
+- class="btn btn-contribute btn-flat"
+- >
+- <a
+- href="http://habitica.fandom.com/wiki/Contributing_to_Habitica"
+- target="_blank"
+- >
+- <div
+- class="svg-icon heart"
+- v-html="icons.heart"
+- ></div>
+- <div class="text">{{ $t('companyContribute') }}</div>
+- </a>
+- </div>
+- </div>
+- </div>
+- </div>
+- </div>
+- <div class="row">
+- <div class="col-12">
+- <hr>
+- </div>
+- </div>
+- <div class="row">
+- <div class="col-12 col-md-5">
+- © 2019 Habitica. All rights reserved.
+- <div
+- v-if="!IS_PRODUCTION && isUserLoaded"
+- class="debug float-left"
+- >
+- <button
+- class="btn btn-primary"
+- @click="debugMenuShown = !debugMenuShown"
+- >
+- Toggle Debug Menu
+- </button>
+- <div
+- v-if="debugMenuShown"
+- class="debug-group"
+- >
+- <a
+- class="btn btn-secondary"
+- @click="setHealthLow()"
+- >Health = 1</a>
+- <a
+- class="btn btn-secondary"
+- @click="addMissedDay(1)"
+- >+1 Missed Day</a>
+- <a
+- class="btn btn-secondary"
+- @click="addMissedDay(2)"
+- >+2 Missed Days</a>
+- <a
+- class="btn btn-secondary"
+- @click="addMissedDay(8)"
+- >+8 Missed Days</a>
+- <a
+- class="btn btn-secondary"
+- @click="addMissedDay(32)"
+- >+32 Missed Days</a>
+- <a
+- class="btn btn-secondary"
+- @click="addTenGems()"
+- >+10 Gems</a>
+- <a
+- class="btn btn-secondary"
+- @click="addHourglass()"
+- >+1 Mystic Hourglass</a>
+- <a
+- class="btn btn-secondary"
+- @click="addGold()"
+- >+500GP</a>
+- <a
+- class="btn btn-secondary"
+- @click="plusTenHealth()"
+- >+ 10HP</a>
+- <a
+- class="btn btn-secondary"
+- @click="addMana()"
+- >+MP</a>
+- <a
+- class="btn btn-secondary"
+- @click="addLevelsAndGold()"
+- >+Exp +GP +MP</a>
+- <a
+- class="btn btn-secondary"
+- @click="addExp()"
+- >+Exp</a>
+- <a
+- class="btn btn-secondary"
+- @click="addOneLevel()"
+- >+1 Level</a>
+- <a
+- class="btn btn-secondary"
+- tooltip="+1000 to boss quests. 300 items to collection quests"
+- @click="addQuestProgress()"
+- >Quest Progress Up</a>
+- <a
+- class="btn btn-secondary"
+- @click="makeAdmin()"
+- >Make Admin</a>
+- <a
+- class="btn btn-secondary"
+- @click="openModifyInventoryModal()"
+- >Modify Inventory</a>
+- </div>
+- </div>
+- </div>
+- <div class="col-12 col-md-2 text-center">
+- <div
+- class="logo svg-icon"
+- v-html="icons.gryphon"
+- ></div>
+- </div>
+- <div class="col-12 col-md-5 text-right">
+- <span class="ml-4">
+- <a
+- target="_blanck"
+- href="/static/privacy"
+- >{{ $t('privacy') }}</a>
+- </span>
+- <span class="ml-4">
+- <a
+- target="_blanck"
+- href="/static/terms"
+- >{{ $t('terms') }}</a>
+- </span>
+- </div>
+- </div>
+- </footer>
+ </div>
</template>
- <style lang="scss" scoped>
-@@ -176,25 +89,6 @@
+@@ -268,15 +12,6 @@
+ z-index: 17;
+ }
+
+- footer {
+- color: #c3c0c7;
+- padding-bottom: 3em;
+-
+- a {
+- color: #2995cd;
+- }
+- }
+-
+ h3 {
+ color: #878190;
+ }
+@@ -346,25 +81,6 @@
.heart svg {
margin-top: .1em;
}
diff --git a/pkgs/shabitica/patches/mailer-daemon.patch b/pkgs/shabitica/patches/mailer-daemon.patch
index 73eeede..926d519 100644
--- a/pkgs/shabitica/patches/mailer-daemon.patch
+++ b/pkgs/shabitica/patches/mailer-daemon.patch
@@ -18,7 +18,7 @@ Date: Tue Mar 27 05:37:16 2018 +0200
Filename: mailer-daemon.patch
diff --git a/config.json.example b/config.json.example
-index e13607e0ee..cb82930b49 100644
+index ff01e0294e..e1c6fe35da 100644
--- a/config.json.example
+++ b/config.json.example
@@ -7,13 +7,11 @@
@@ -35,8 +35,8 @@ index e13607e0ee..cb82930b49 100644
+ "MAILER_SOCKET": "/run/habitica/mailer.sock",
"MAINTENANCE_MODE": "false",
"NODE_DB_URI": "mongodb://localhost/habitrpg",
- "NODE_ENV": "development",
-@@ -22,9 +20,6 @@
+ "MONGODB_POOL_SIZE": "10",
+@@ -23,9 +21,6 @@
"SESSION_SECRET": "YOUR SECRET HERE",
"SESSION_SECRET_IV": "12345678912345678912345678912345",
"SESSION_SECRET_KEY": "1234567891234567891234567891234567891234567891234567891234567891",
@@ -47,10 +47,10 @@ index e13607e0ee..cb82930b49 100644
"WEB_CONCURRENCY": 1,
"SKIP_SSL_CHECK_KEY": "key",
diff --git a/test/api/unit/libs/email.test.js b/test/api/unit/libs/email.test.js
-index 93cffd8693..6d17a0c0dd 100644
+index 9179ba9642..53333ab143 100644
--- a/test/api/unit/libs/email.test.js
+++ b/test/api/unit/libs/email.test.js
-@@ -104,7 +104,7 @@ describe('emails', () => {
+@@ -105,7 +105,7 @@ describe('emails', () => {
};
sendTxnEmail(mailingInfo, emailType);
@@ -59,8 +59,8 @@ index 93cffd8693..6d17a0c0dd 100644
json: true,
body: {
data: {
-@@ -139,7 +139,7 @@ describe('emails', () => {
- let mailingInfo = getUser();
+@@ -138,7 +138,7 @@ describe('emails', () => {
+ const mailingInfo = getUser();
sendTxnEmail(mailingInfo, emailType);
- expect(got.post).to.be.calledWith('undefined/job', sinon.match({
@@ -68,8 +68,8 @@ index 93cffd8693..6d17a0c0dd 100644
json: true,
body: {
data: {
-@@ -162,7 +162,7 @@ describe('emails', () => {
- let variables = [1, 2, 3];
+@@ -161,7 +161,7 @@ describe('emails', () => {
+ const variables = [1, 2, 3];
sendTxnEmail(mailingInfo, emailType, variables);
- expect(got.post).to.be.calledWith('undefined/job', sinon.match({
@@ -78,10 +78,10 @@ index 93cffd8693..6d17a0c0dd 100644
body: {
data: {
diff --git a/website/server/libs/email.js b/website/server/libs/email.js
-index b37c3e8a0a..a2f4adf0c9 100644
+index 2385546ca6..aa865383b8 100644
--- a/website/server/libs/email.js
+++ b/website/server/libs/email.js
-@@ -5,13 +5,7 @@ import got from 'got';
+@@ -5,13 +5,7 @@ import { encrypt } from './encryption';
import logger from './logger';
const IS_PROD = nconf.get('IS_PROD');
@@ -96,7 +96,7 @@ index b37c3e8a0a..a2f4adf0c9 100644
const BASE_URL = nconf.get('BASE_URL');
export function getUserInfo (user, fields = []) {
-@@ -120,8 +114,7 @@ export function sendTxn (mailingInfoArray, emailType, variables, personalVariabl
+@@ -118,8 +112,7 @@ export function sendTxn (mailingInfoArray, emailType, variables, personalVariabl
}
if (IS_PROD && mailingInfoArray.length > 0) {
diff --git a/pkgs/shabitica/patches/migration-runner-promise-fallback.patch b/pkgs/shabitica/patches/migration-runner-promise-fallback.patch
index 38b0145..2b226a0 100644
--- a/pkgs/shabitica/patches/migration-runner-promise-fallback.patch
+++ b/pkgs/shabitica/patches/migration-runner-promise-fallback.patch
@@ -17,21 +17,21 @@ Date: Sat Oct 13 02:40:20 2018 +0200
Filename: migration-runner-promise-fallback.patch
diff --git a/migrations/migration-runner.js b/migrations/migration-runner.js
-index 38901eda7a..245097a105 100644
+index 799bf9d5aa..676cd0c903 100644
--- a/migrations/migration-runner.js
+++ b/migrations/migration-runner.js
-@@ -18,11 +18,13 @@ setUpServer();
+@@ -19,11 +19,13 @@ setUpServer();
// Replace this with your migration
const processUsers = require('@migrationScript@');
-processUsers()
-- .then(function success () {
+- .then(() => {
+let result = processUsers();
+if (Promise.resolve(result) === result) {
+ result.then(function success () {
process.exit(0);
})
-- .catch(function failure (err) {
+- .catch(err => {
- console.log(err);
- process.exit(1);
- });
diff --git a/pkgs/shabitica/patches/migration-substvar.patch b/pkgs/shabitica/patches/migration-substvar.patch
index 0eec0a2..4fe7e30 100644
--- a/pkgs/shabitica/patches/migration-substvar.patch
+++ b/pkgs/shabitica/patches/migration-substvar.patch
@@ -9,15 +9,16 @@ Date: Wed May 2 03:15:04 2018 +0200
Filename: migration-substvar.patch
diff --git a/migrations/migration-runner.js b/migrations/migration-runner.js
-index 39cec8b1aa..38901eda7a 100644
+index 60926b4264..799bf9d5aa 100644
--- a/migrations/migration-runner.js
+++ b/migrations/migration-runner.js
-@@ -17,7 +17,7 @@ function setUpServer () {
+@@ -18,8 +18,7 @@ function setUpServer () {
setUpServer();
// Replace this with your migration
--const processUsers = require('');
+-const processUsers = () => {}; // require('').default;
+-
+const processUsers = require('@migrationScript@');
processUsers()
- .then(function success () {
+ .then(() => {
process.exit(0);
diff --git a/pkgs/shabitica/patches/mocha-no-timeout.patch b/pkgs/shabitica/patches/mocha-no-timeout.patch
index 5089f31..dd55c6f 100644
--- a/pkgs/shabitica/patches/mocha-no-timeout.patch
+++ b/pkgs/shabitica/patches/mocha-no-timeout.patch
@@ -10,7 +10,7 @@ Date: Wed Apr 11 17:46:08 2018 +0200
Filename: mocha-no-timeout.patch
diff --git a/test/mocha.opts b/test/mocha.opts
-index 28345d5049..093c26c6aa 100644
+index 3f4155608a..83d49b8c9d 100644
--- a/test/mocha.opts
+++ b/test/mocha.opts
@@ -1,6 +1,6 @@
@@ -19,5 +19,5 @@ index 28345d5049..093c26c6aa 100644
---timeout 8000
+--no-timeouts
--check-leaks
- --globals io
- --require babel-register
+ --require @babel/register
+ --require ./test/helpers/globals.helper
diff --git a/pkgs/shabitica/patches/no-censorship.patch b/pkgs/shabitica/patches/no-censorship.patch
index 2428a0f..aa199cb 100644
--- a/pkgs/shabitica/patches/no-censorship.patch
+++ b/pkgs/shabitica/patches/no-censorship.patch
@@ -12,30 +12,31 @@ Date: Sat Apr 7 03:03:48 2018 +0200
Filename: no-censorship.patch
diff --git a/test/api/v3/integration/chat/POST-chat.test.js b/test/api/v3/integration/chat/POST-chat.test.js
-index 50cb211863..d22ba309d5 100644
+index 6fbb138251..b6840451c3 100644
--- a/test/api/v3/integration/chat/POST-chat.test.js
+++ b/test/api/v3/integration/chat/POST-chat.test.js
-@@ -12,19 +12,11 @@ import {
+@@ -12,20 +12,12 @@ import {
+ TAVERN_ID,
} from '../../../../../website/server/models/group';
import { CHAT_FLAG_FROM_SHADOW_MUTE } from '../../../../../website/common/script/constants';
- import { v4 as generateUUID } from 'uuid';
-import { getMatchesByWordArray } from '../../../../../website/server/libs/stringUtils';
-import bannedWords from '../../../../../website/server/libs/bannedWords';
-import guildsAllowingBannedWords from '../../../../../website/server/libs/guildsAllowingBannedWords';
import * as email from '../../../../../website/server/libs/email';
describe('POST /chat', () => {
- let user, groupWithChat, member, additionalMember;
- let testMessage = 'Test Message';
-- let testBannedWordMessage = 'TESTPLACEHOLDERSWEARWORDHERE';
-- let testBannedWordMessage1 = 'TESTPLACEHOLDERSWEARWORDHERE1';
-- let testSlurMessage = 'message with TESTPLACEHOLDERSLURWORDHERE';
-- let testSlurMessage1 = 'TESTPLACEHOLDERSLURWORDHERE1';
-- let bannedWordErrorMessage = t('bannedWordUsed', {swearWordsUsed: testBannedWordMessage});
+ let user; let groupWithChat; let member; let
+ additionalMember;
+ const testMessage = 'Test Message';
+- const testBannedWordMessage = 'TESTPLACEHOLDERSWEARWORDHERE';
+- const testBannedWordMessage1 = 'TESTPLACEHOLDERSWEARWORDHERE1';
+- const testSlurMessage = 'message with TESTPLACEHOLDERSLURWORDHERE';
+- const testSlurMessage1 = 'TESTPLACEHOLDERSLURWORDHERE1';
+- const bannedWordErrorMessage = t('bannedWordUsed', { swearWordsUsed: testBannedWordMessage });
before(async () => {
- let { group, groupLeader, members } = await createAndPopulateGroup({
-@@ -131,7 +123,6 @@ describe('POST /chat', () => {
+ const { group, groupLeader, members } = await createAndPopulateGroup({
+@@ -132,7 +124,6 @@ describe('POST /chat', () => {
describe('shadow-mute user', () => {
beforeEach(() => {
sandbox.spy(email, 'sendTxn');
@@ -43,7 +44,7 @@ index 50cb211863..d22ba309d5 100644
});
afterEach(() => {
-@@ -149,25 +140,6 @@ describe('POST /chat', () => {
+@@ -150,25 +141,6 @@ describe('POST /chat', () => {
await sleep(0.5);
expect(email.sendTxn).to.be.calledOnce;
expect(email.sendTxn.args[0][1]).to.eql('shadow-muted-post-report-to-mods');
@@ -69,13 +70,13 @@ index 50cb211863..d22ba309d5 100644
});
it('creates a chat with zero flagCount when sending a message to a private guild', async () => {
-@@ -215,213 +187,6 @@ describe('POST /chat', () => {
+@@ -216,218 +188,6 @@ describe('POST /chat', () => {
});
});
- context('banned word', () => {
- it('returns an error when chat message contains a banned word in tavern', async () => {
-- await expect(user.post('/groups/habitrpg/chat', { message: testBannedWordMessage}))
+- await expect(user.post('/groups/habitrpg/chat', { message: testBannedWordMessage }))
- .to.eventually.be.rejected.and.eql({
- code: 400,
- error: 'BadRequest',
@@ -84,7 +85,7 @@ index 50cb211863..d22ba309d5 100644
- });
-
- it('returns an error when chat message contains a banned word in a public guild', async () => {
-- let { group, members } = await createAndPopulateGroup({
+- const { group, members } = await createAndPopulateGroup({
- groupDetails: {
- name: 'public guild',
- type: 'guild',
@@ -93,7 +94,7 @@ index 50cb211863..d22ba309d5 100644
- members: 1,
- });
-
-- await expect(members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage}))
+- await expect(members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage }))
- .to.eventually.be.rejected.and.eql({
- code: 400,
- error: 'BadRequest',
@@ -102,8 +103,8 @@ index 50cb211863..d22ba309d5 100644
- });
-
- it('errors when word is part of a phrase', async () => {
-- let wordInPhrase = `phrase ${testBannedWordMessage} end`;
-- await expect(user.post('/groups/habitrpg/chat', { message: wordInPhrase}))
+- const wordInPhrase = `phrase ${testBannedWordMessage} end`;
+- await expect(user.post('/groups/habitrpg/chat', { message: wordInPhrase }))
- .to.eventually.be.rejected.and.eql({
- code: 400,
- error: 'BadRequest',
@@ -112,8 +113,8 @@ index 50cb211863..d22ba309d5 100644
- });
-
- it('errors when word is surrounded by non alphabet characters', async () => {
-- let wordInPhrase = `_!${testBannedWordMessage}@_`;
-- await expect(user.post('/groups/habitrpg/chat', { message: wordInPhrase}))
+- const wordInPhrase = `_!${testBannedWordMessage}@_`;
+- await expect(user.post('/groups/habitrpg/chat', { message: wordInPhrase }))
- .to.eventually.be.rejected.and.eql({
- code: 400,
- error: 'BadRequest',
@@ -122,47 +123,51 @@ index 50cb211863..d22ba309d5 100644
- });
-
- it('errors when word is typed in mixed case', async () => {
-- let substrLength = Math.floor(testBannedWordMessage.length / 2);
-- let chatMessage = testBannedWordMessage.substring(0, substrLength).toLowerCase() + testBannedWordMessage.substring(substrLength).toUpperCase();
+- const substrLength = Math.floor(testBannedWordMessage.length / 2);
+- const chatMessage = testBannedWordMessage.substring(0, substrLength).toLowerCase()
+- + testBannedWordMessage.substring(substrLength).toUpperCase();
- await expect(user.post('/groups/habitrpg/chat', { message: chatMessage }))
- .to.eventually.be.rejected.and.eql({
- code: 400,
- error: 'BadRequest',
-- message: t('bannedWordUsed', {swearWordsUsed: chatMessage}),
+- message: t('bannedWordUsed', { swearWordsUsed: chatMessage }),
- });
- });
-
- it('checks error message has all the banned words used, regardless of case', async () => {
-- let testBannedWords = [testBannedWordMessage.toUpperCase(), testBannedWordMessage1.toLowerCase()];
-- let chatMessage = `Mixing ${testBannedWords[0]} and ${testBannedWords[1]} is bad for you.`;
-- await expect(user.post('/groups/habitrpg/chat', { message: chatMessage}))
+- const testBannedWords = [
+- testBannedWordMessage.toUpperCase(),
+- testBannedWordMessage1.toLowerCase(),
+- ];
+- const chatMessage = `Mixing ${testBannedWords[0]} and ${testBannedWords[1]} is bad for you.`;
+- await expect(user.post('/groups/habitrpg/chat', { message: chatMessage }))
- .to.eventually.be.rejected
- .and.have.property('message')
- .that.includes(testBannedWords.join(', '));
- });
-
- it('check all banned words are matched', async () => {
-- let message = bannedWords.join(',').replace(/\\/g, '');
-- let matches = getMatchesByWordArray(message, bannedWords);
+- const message = bannedWords.join(',').replace(/\\/g, '');
+- const matches = getMatchesByWordArray(message, bannedWords);
- expect(matches.length).to.equal(bannedWords.length);
- });
-
- it('does not error when bad word is suffix of a word', async () => {
-- let wordAsSuffix = `prefix${testBannedWordMessage}`;
-- let message = await user.post('/groups/habitrpg/chat', { message: wordAsSuffix});
+- const wordAsSuffix = `prefix${testBannedWordMessage}`;
+- const message = await user.post('/groups/habitrpg/chat', { message: wordAsSuffix });
-
- expect(message.message.id).to.exist;
- });
-
- it('does not error when bad word is prefix of a word', async () => {
-- let wordAsPrefix = `${testBannedWordMessage}suffix`;
-- let message = await user.post('/groups/habitrpg/chat', { message: wordAsPrefix});
+- const wordAsPrefix = `${testBannedWordMessage}suffix`;
+- const message = await user.post('/groups/habitrpg/chat', { message: wordAsPrefix });
-
- expect(message.message.id).to.exist;
- });
-
- it('does not error when sending a chat message containing a banned word to a party', async () => {
-- let { group, members } = await createAndPopulateGroup({
+- const { group, members } = await createAndPopulateGroup({
- groupDetails: {
- name: 'Party',
- type: 'party',
@@ -171,13 +176,13 @@ index 50cb211863..d22ba309d5 100644
- members: 1,
- });
-
-- let message = await members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage});
+- const message = await members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage });
-
- expect(message.message.id).to.exist;
- });
-
- it('does not error when sending a chat message containing a banned word to a public guild in which banned words are allowed', async () => {
-- let { group, members } = await createAndPopulateGroup({
+- const { group, members } = await createAndPopulateGroup({
- groupDetails: {
- name: 'public guild',
- type: 'guild',
@@ -188,13 +193,13 @@ index 50cb211863..d22ba309d5 100644
-
- guildsAllowingBannedWords[group._id] = true;
-
-- let message = await members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage});
+- const message = await members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage });
-
- expect(message.message.id).to.exist;
- });
-
- it('does not error when sending a chat message containing a banned word to a private guild', async () => {
-- let { group, members } = await createAndPopulateGroup({
+- const { group, members } = await createAndPopulateGroup({
- groupDetails: {
- name: 'private guild',
- type: 'guild',
@@ -203,7 +208,7 @@ index 50cb211863..d22ba309d5 100644
- members: 1,
- });
-
-- let message = await members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage});
+- const message = await members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage });
-
- expect(message.message.id).to.exist;
- });
@@ -216,11 +221,11 @@ index 50cb211863..d22ba309d5 100644
-
- afterEach(() => {
- sandbox.restore();
-- user.update({'flags.chatRevoked': false});
+- user.update({ 'flags.chatRevoked': false });
- });
-
- it('errors and revokes privileges when chat message contains a banned slur', async () => {
-- await expect(user.post(`/groups/${groupWithChat._id}/chat`, { message: testSlurMessage})).to.eventually.be.rejected.and.eql({
+- await expect(user.post(`/groups/${groupWithChat._id}/chat`, { message: testSlurMessage })).to.eventually.be.rejected.and.eql({
- code: 400,
- error: 'BadRequest',
- message: t('bannedSlurUsed'),
@@ -232,7 +237,7 @@ index 50cb211863..d22ba309d5 100644
- expect(email.sendTxn.args[0][1]).to.eql('slur-report-to-mods');
-
- // Chat privileges are revoked
-- await expect(user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage})).to.eventually.be.rejected.and.eql({
+- await expect(user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage })).to.eventually.be.rejected.and.eql({
- code: 401,
- error: 'NotAuthorized',
- message: t('chatPrivilegesRevoked'),
@@ -240,7 +245,7 @@ index 50cb211863..d22ba309d5 100644
- });
-
- it('does not allow slurs in private groups', async () => {
-- let { group, members } = await createAndPopulateGroup({
+- const { group, members } = await createAndPopulateGroup({
- groupDetails: {
- name: 'Party',
- type: 'party',
@@ -249,7 +254,7 @@ index 50cb211863..d22ba309d5 100644
- members: 1,
- });
-
-- await expect(members[0].post(`/groups/${group._id}/chat`, { message: testSlurMessage})).to.eventually.be.rejected.and.eql({
+- await expect(members[0].post(`/groups/${group._id}/chat`, { message: testSlurMessage })).to.eventually.be.rejected.and.eql({
- code: 400,
- error: 'BadRequest',
- message: t('bannedSlurUsed'),
@@ -261,7 +266,7 @@ index 50cb211863..d22ba309d5 100644
- expect(email.sendTxn.args[2][1]).to.eql('slur-report-to-mods');
-
- // Chat privileges are revoked
-- await expect(members[0].post(`/groups/${groupWithChat._id}/chat`, { message: testMessage})).to.eventually.be.rejected.and.eql({
+- await expect(members[0].post(`/groups/${groupWithChat._id}/chat`, { message: testMessage })).to.eventually.be.rejected.and.eql({
- code: 401,
- error: 'NotAuthorized',
- message: t('chatPrivilegesRevoked'),
@@ -269,8 +274,9 @@ index 50cb211863..d22ba309d5 100644
- });
-
- it('errors when slur is typed in mixed case', async () => {
-- let substrLength = Math.floor(testSlurMessage1.length / 2);
-- let chatMessage = testSlurMessage1.substring(0, substrLength).toLowerCase() + testSlurMessage1.substring(substrLength).toUpperCase();
+- const substrLength = Math.floor(testSlurMessage1.length / 2);
+- const chatMessage = testSlurMessage1.substring(0, substrLength).toLowerCase()
+- + testSlurMessage1.substring(substrLength).toUpperCase();
- await expect(user.post('/groups/habitrpg/chat', { message: chatMessage }))
- .to.eventually.be.rejected.and.eql({
- code: 400,
@@ -281,10 +287,10 @@ index 50cb211863..d22ba309d5 100644
- });
-
it('creates a chat', async () => {
- const newMessage = await user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage});
+ const newMessage = await user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
const groupMessages = await user.get(`/groups/${groupWithChat._id}/chat`);
diff --git a/test/api/v3/integration/user/PUT-user.test.js b/test/api/v3/integration/user/PUT-user.test.js
-index bef5ec25d0..6c7f49a283 100644
+index b1f576a791..44ce54090c 100644
--- a/test/api/v3/integration/user/PUT-user.test.js
+++ b/test/api/v3/integration/user/PUT-user.test.js
@@ -86,14 +86,6 @@ describe('PUT /user', () => {
@@ -303,7 +309,7 @@ index bef5ec25d0..6c7f49a283 100644
});
diff --git a/test/api/v3/integration/user/auth/PUT-user_update_username.test.js b/test/api/v3/integration/user/auth/PUT-user_update_username.test.js
-index 987f7bd556..dc5efa212b 100644
+index 7e2da12bc0..e20c4ab86d 100644
--- a/test/api/v3/integration/user/auth/PUT-user_update_username.test.js
+++ b/test/api/v3/integration/user/auth/PUT-user_update_username.test.js
@@ -133,58 +133,48 @@ describe('PUT /user/auth/update-username', async () => {
@@ -396,7 +402,7 @@ index 987f7bd556..dc5efa212b 100644
it('errors if username has incorrect length', async () => {
diff --git a/test/api/v4/user/auth/POST-user_verify_display_name.test.js b/test/api/v4/user/auth/POST-user_verify_display_name.test.js
-index 8fa1b9d5b9..b040578b67 100644
+index 77f30f6a4f..be6a1e9a06 100644
--- a/test/api/v4/user/auth/POST-user_verify_display_name.test.js
+++ b/test/api/v4/user/auth/POST-user_verify_display_name.test.js
@@ -30,22 +30,22 @@ describe('POST /user/auth/verify-display-name', async () => {
@@ -433,7 +439,7 @@ index 8fa1b9d5b9..b040578b67 100644
it('errors if display name has incorrect length', async () => {
diff --git a/test/api/v4/user/auth/POST-user_verify_username.test.js b/test/api/v4/user/auth/POST-user_verify_username.test.js
-index c17b789a41..041a418207 100644
+index 2ae95b1c52..189b315971 100644
--- a/test/api/v4/user/auth/POST-user_verify_username.test.js
+++ b/test/api/v4/user/auth/POST-user_verify_username.test.js
@@ -38,34 +38,34 @@ describe('POST /user/auth/verify-username', async () => {
@@ -486,44 +492,44 @@ index c17b789a41..041a418207 100644
});
it('errors if username has incorrect length', async () => {
-diff --git a/website/client/app.vue b/website/client/app.vue
-index f48245c494..2f19b15e08 100644
---- a/website/client/app.vue
-+++ b/website/client/app.vue
-@@ -9,7 +9,6 @@ div
- h2 {{$t('tipTitle', {tipNumber: currentTipNumber})}}
- p {{currentTip}}
- #app(:class='{"casting-spell": castingSpell}')
-- banned-account-modal
- sub-cancel-modal-confirm(v-if='isUserLoaded')
- sub-canceled-modal(v-if='isUserLoaded')
- snackbars
-@@ -188,7 +187,6 @@ import spellsMixin from 'client/mixins/spells';
- import { CONSTANTS, getLocalSetting, removeLocalSetting } from 'client/libs/userlocalManager';
-
- import svgClose from 'assets/svg/close.svg';
--import bannedAccountModal from 'client/components/bannedAccountModal';
-
- const COMMUNITY_MANAGER_EMAIL = process.env.EMAILS.COMMUNITY_MANAGER_EMAIL; // eslint-disable-line
-
-@@ -203,7 +201,6 @@ export default {
+diff --git a/website/client/src/app.vue b/website/client/src/app.vue
+index 8e150d5633..b7c2e6bdb9 100644
+--- a/website/client/src/app.vue
++++ b/website/client/src/app.vue
+@@ -30,7 +30,6 @@
+ id="app"
+ :class="{'casting-spell': castingSpell}"
+ >
+- <banned-account-modal />
+ <sub-cancel-modal-confirm v-if="isUserLoaded" />
+ <sub-canceled-modal v-if="isUserLoaded" />
+ <snackbars />
+@@ -234,7 +233,6 @@ import spellsMixin from '@/mixins/spells';
+ import { CONSTANTS, getLocalSetting, removeLocalSetting } from '@/libs/userlocalManager';
+
+ import svgClose from '@/assets/svg/close.svg';
+-import bannedAccountModal from '@/components/bannedAccountModal';
+
+ const COMMUNITY_MANAGER_EMAIL = process.env.ADMIN_EMAIL; // eslint-disable-line
+
+@@ -248,7 +246,6 @@ export default {
snackbars,
BuyModal,
SelectMembersModal,
- bannedAccountModal,
},
+ mixins: [notifications, spellsMixin],
data () {
- return {
-@@ -296,8 +293,6 @@ export default {
+@@ -343,8 +340,6 @@ export default {
return response;
- }, (error) => {
+ }, error => {
if (error.response.status >= 400) {
- this.checkForBannedUser(error);
-
// Don't show errors from getting user details. These users have delete their account,
// but their chat message still exists.
- let configExists = Boolean(error.response) && Boolean(error.response.config);
-@@ -447,25 +442,6 @@ export default {
+ const configExists = Boolean(error.response) && Boolean(error.response.config);
+@@ -495,25 +490,6 @@ export default {
if (loadingScreen) document.body.removeChild(loadingScreen);
},
methods: {
@@ -550,10 +556,10 @@ index f48245c494..2f19b15e08 100644
// Manage modals
this.$root.$on('bv::show::modal', (modalId, data = {}) => {
diff --git a/website/server/controllers/api-v3/chat.js b/website/server/controllers/api-v3/chat.js
-index 0bac414b58..7aa6a2f15e 100644
+index 648a0739be..65a0fba797 100644
--- a/website/server/controllers/api-v3/chat.js
+++ b/website/server/controllers/api-v3/chat.js
-@@ -4,7 +4,6 @@ import { model as User } from '../../models/user';
+@@ -5,7 +5,6 @@ import { model as User } from '../../models/user';
import { chatModel as Chat } from '../../models/message';
import common from '../../../common';
import {
@@ -561,67 +567,68 @@ index 0bac414b58..7aa6a2f15e 100644
NotFound,
NotAuthorized,
} from '../../libs/errors';
-@@ -13,10 +12,6 @@ import { getUserInfo, getGroupUrl, sendTxn } from '../../libs/email';
+@@ -13,10 +12,6 @@ import { removeFromArray } from '../../libs/collectionManipulators';
+ import { getUserInfo, getGroupUrl, sendTxn } from '../../libs/email';
import { chatReporterFactory } from '../../libs/chatReporting/chatReporterFactory';
- import { getAuthorEmailFromMessage} from '../../libs/chat';
- import nconf from 'nconf';
+ import { getAuthorEmailFromMessage } from '../../libs/chat';
-import bannedWords from '../../libs/bannedWords';
-import guildsAllowingBannedWords from '../../libs/guildsAllowingBannedWords';
-import { getMatchesByWordArray } from '../../libs/stringUtils';
-import bannedSlurs from '../../libs/bannedSlurs';
import apiError from '../../libs/apiError';
+ import { highlightMentions } from '../../libs/highlightMentions';
- const FLAG_REPORT_EMAILS = nconf.get('ADMIN_EMAIL').split(',').map((email) => {
-@@ -45,11 +40,6 @@ const FLAG_REPORT_EMAILS = nconf.get('ADMIN_EMAIL').split(',').map((email) => {
+@@ -44,11 +39,6 @@ const FLAG_REPORT_EMAILS = nconf.get('ADMIN_EMAIL').split(',').map(email => ({ e
- let api = {};
+ const api = {};
-function textContainsBannedSlur (message) {
-- let bannedSlursMatched = getMatchesByWordArray(message, bannedSlurs);
+- const bannedSlursMatched = getMatchesByWordArray(message, bannedSlurs);
- return bannedSlursMatched.length > 0;
-}
-
/**
* @api {get} /api/v3/groups/:groupId/chat Get chat messages from a group
* @apiName GetChat
-@@ -84,10 +74,6 @@ api.getChat = {
+@@ -84,11 +74,6 @@ api.getChat = {
},
};
-function getBannedWordsFromText (message) {
- return getMatchesByWordArray(message, bannedWords);
-}
+-
-
/**
* @api {post} /api/v3/groups/:groupId/chat Post chat message to a group
* @apiName PostChat
-@@ -120,50 +106,12 @@ api.postChat = {
+@@ -123,51 +108,12 @@ api.postChat = {
- let group = await Group.getGroup({user, groupId});
+ const group = await Group.getGroup({ user, groupId });
- // Check message for banned slurs
- if (textContainsBannedSlur(req.body.message)) {
-- let message = req.body.message;
+- const { message } = req.body;
- user.flags.chatRevoked = true;
- await user.save();
-
- // Email the mods
-- let authorEmail = getUserInfo(user, ['email']).email;
-- let groupUrl = getGroupUrl(group);
--
-- let report = [
-- {name: 'MESSAGE_TIME', content: (new Date()).toString()},
-- {name: 'MESSAGE_TEXT', content: message},
--
-- {name: 'AUTHOR_USERNAME', content: user.profile.name},
-- {name: 'AUTHOR_UUID', content: user._id},
-- {name: 'AUTHOR_EMAIL', content: authorEmail},
-- {name: 'AUTHOR_MODAL_URL', content: `/profile/${user._id}`},
--
-- {name: 'GROUP_NAME', content: group.name},
-- {name: 'GROUP_TYPE', content: group.type},
-- {name: 'GROUP_ID', content: group._id},
-- {name: 'GROUP_URL', content: groupUrl},
+- const authorEmail = getUserInfo(user, ['email']).email;
+- const groupUrl = getGroupUrl(group);
+-
+- const report = [
+- { name: 'MESSAGE_TIME', content: (new Date()).toString() },
+- { name: 'MESSAGE_TEXT', content: message },
+-
+- { name: 'AUTHOR_USERNAME', content: user.profile.name },
+- { name: 'AUTHOR_UUID', content: user._id },
+- { name: 'AUTHOR_EMAIL', content: authorEmail },
+- { name: 'AUTHOR_MODAL_URL', content: `/profile/${user._id}` },
+-
+- { name: 'GROUP_NAME', content: group.name },
+- { name: 'GROUP_TYPE', content: group.type },
+- { name: 'GROUP_ID', content: group._id },
+- { name: 'GROUP_URL', content: groupUrl },
- ];
-
- sendTxn(FLAG_REPORT_EMAILS, 'slur-report-to-mods', report);
@@ -635,30 +642,31 @@ index 0bac414b58..7aa6a2f15e 100644
throw new NotAuthorized(res.t('chatPrivilegesRevoked'));
}
-- // prevent banned words being posted, except in private guilds/parties and in certain public guilds with specific topics
+- // prevent banned words being posted, except in private guilds/parties
+- // and in certain public guilds with specific topics
- if (group.privacy === 'public' && !guildsAllowingBannedWords[group._id]) {
-- let matchedBadWords = getBannedWordsFromText(req.body.message);
+- const matchedBadWords = getBannedWordsFromText(req.body.message);
- if (matchedBadWords.length > 0) {
-- throw new BadRequest(res.t('bannedWordUsed', {swearWordsUsed: matchedBadWords.join(', ')}));
+- throw new BadRequest(res.t('bannedWordUsed', { swearWordsUsed: matchedBadWords.join(', ') }));
- }
- }
-
const chatRes = await Group.toJSONCleanChat(group, user);
const lastClientMsg = req.query.previousMsg;
- chatUpdated = lastClientMsg && group.chat && group.chat[0] && group.chat[0].id !== lastClientMsg ? true : false;
+ const chatUpdated = !!(
diff --git a/website/server/libs/user/index.js b/website/server/libs/user/index.js
-index c4321265cc..c65a199049 100644
+index 60a4a1a4d6..0b5aea4984 100644
--- a/website/server/libs/user/index.js
+++ b/website/server/libs/user/index.js
@@ -6,7 +6,6 @@ import {
NotAuthorized,
- } from '../../libs/errors';
- import { model as User } from '../../models/user';
--import {nameContainsSlur} from './validation';
+ } from '../errors';
+ import { model as User, schema as UserSchema } from '../../models/user';
+-import { nameContainsSlur } from './validation';
export async function get (req, res, { isV3 = false }) {
-@@ -113,7 +112,6 @@ export async function update (req, res, { isV3 = false }) {
+@@ -111,7 +110,6 @@ export async function update (req, res, { isV3 = false }) {
const newName = req.body['profile.name'];
if (newName === null) throw new BadRequest(res.t('invalidReqParams'));
if (newName.length > 30) throw new BadRequest(res.t('displaynameIssueLength'));
@@ -667,15 +675,15 @@ index c4321265cc..c65a199049 100644
_.each(req.body, (val, key) => {
diff --git a/website/server/libs/user/validation.js b/website/server/libs/user/validation.js
-index 097ef70cdf..ba850aa013 100644
+index cbdc6487d0..7158b3e868 100644
--- a/website/server/libs/user/validation.js
+++ b/website/server/libs/user/validation.js
@@ -1,25 +1,3 @@
-import bannedSlurs from '../bannedSlurs';
--import {getMatchesByWordArray} from '../stringUtils';
+-import { getMatchesByWordArray } from '../stringUtils';
-import forbiddenUsernames from '../forbiddenUsernames';
-
--const bannedSlurRegexs = bannedSlurs.map((word) => new RegExp(`.*${word}.*`, 'i'));
+-const bannedSlurRegexs = bannedSlurs.map(word => new RegExp(`.*${word}.*`, 'i'));
-
-export function nameContainsSlur (username) {
- for (let i = 0; i < bannedSlurRegexs.length; i += 1) {
@@ -695,17 +703,17 @@ index 097ef70cdf..ba850aa013 100644
-
const invalidCharsRegex = new RegExp('[^a-z0-9_-]', 'i');
function usernameContainsInvalidCharacters (username) {
- let match = username.match(invalidCharsRegex);
+ const match = username.match(invalidCharsRegex);
@@ -29,7 +7,6 @@ function usernameContainsInvalidCharacters (username) {
export function verifyDisplayName (displayName, res) {
- let issues = [];
+ const issues = [];
if (displayName.length < 1 || displayName.length > 30) issues.push(res.t('displaynameIssueLength'));
- if (nameContainsSlur(displayName)) issues.push(res.t('displaynameIssueSlur'));
return issues;
}
@@ -38,8 +15,6 @@ export function verifyUsername (username, res) {
- let issues = [];
+ const issues = [];
if (username.length < 1 || username.length > 20) issues.push(res.t('usernameIssueLength'));
if (usernameContainsInvalidCharacters(username)) issues.push(res.t('usernameIssueInvalidCharacters'));
- if (nameContainsSlur(username)) issues.push(res.t('usernameIssueSlur'));
diff --git a/pkgs/shabitica/patches/no-limit-for-gold-to-gems.patch b/pkgs/shabitica/patches/no-limit-for-gold-to-gems.patch
index 6e54238..b34dc9f 100644
--- a/pkgs/shabitica/patches/no-limit-for-gold-to-gems.patch
+++ b/pkgs/shabitica/patches/no-limit-for-gold-to-gems.patch
@@ -16,57 +16,61 @@ Date: Fri Mar 30 02:41:52 2018 +0200
Filename: no-limit-for-gold-to-gems.patch
diff --git a/test/common/ops/buy/buyGem.js b/test/common/ops/buy/buyGem.js
-index 4ae96a55b7..22b15739bc 100644
+index 2321c4453e..678e7db1d3 100644
--- a/test/common/ops/buy/buyGem.js
+++ b/test/common/ops/buy/buyGem.js
@@ -102,19 +102,6 @@ describe('shared.ops.buyGem', () => {
}
});
-- it('prevents user that have reached the conversion cap from buying gems', (done) => {
+- it('prevents user that have reached the conversion cap from buying gems', done => {
- user.stats.gp = goldPoints;
- user.purchased.plan.gemsBought = gemsBought;
-
- try {
-- buyGem(user, {params: {type: 'gems', key: 'gem'}});
+- buyGem(user, { params: { type: 'gems', key: 'gem' } });
- } catch (err) {
- expect(err).to.be.an.instanceof(NotAuthorized);
-- expect(err.message).to.equal(i18n.t('reachedGoldToGemCap', {convCap: planGemLimits.convCap}));
+- expect(err.message).to.equal(i18n.t('reachedGoldToGemCap', { convCap: planGemLimits.convCap }));
- done();
- }
- });
-
- it('prevents user from buying an invalid quantity', (done) => {
+ it('prevents user from buying an invalid quantity', done => {
user.stats.gp = goldPoints;
user.purchased.plan.gemsBought = gemsBought;
-diff --git a/website/client/components/shops/buyModal.vue b/website/client/components/shops/buyModal.vue
-index 2a230e04b3..15d719f719 100644
---- a/website/client/components/shops/buyModal.vue
-+++ b/website/client/components/shops/buyModal.vue
-@@ -56,13 +56,6 @@
- span.svg-icon.inline.icon-32(aria-hidden="true", v-html="icons[getPriceClass()]")
- span.cost(:class="getPriceClass()") {{ item.value }}
-
-- .gems-left(v-if='item.key === "gem"')
-- strong(v-if='gemsLeft > 0') {{ gemsLeft }} {{ $t('gemsRemaining') }}
-- strong(v-if='gemsLeft === 0') {{ $t('maxBuyGems') }}
--
-- div(v-if='attemptingToPurchaseMoreGemsThanAreLeft')
-- | {{$t('notEnoughGemsToBuy')}}
--
- button.btn.btn-primary(
- @click="purchaseGems()",
- v-if="getPriceClass() === 'gems' && !this.enoughCurrency(getPriceClass(), item.value * selectedAmountToBuy)"
-@@ -71,7 +64,7 @@
- button.btn.btn-primary(
- @click="buyItem()",
- v-else,
-- :disabled='item.key === "gem" && gemsLeft === 0 || attemptingToPurchaseMoreGemsThanAreLeft || numberInvalid',
-+ :disabled='numberInvalid',
- :class="{'notEnough': !preventHealthPotion || !this.enoughCurrency(getPriceClass(), item.value * selectedAmountToBuy)}"
- ) {{ $t('buyNow') }}
-
-@@ -255,10 +248,6 @@
+diff --git a/website/client/src/components/shops/buyModal.vue b/website/client/src/components/shops/buyModal.vue
+index ee84a93ed0..d201a7627b 100644
+--- a/website/client/src/components/shops/buyModal.vue
++++ b/website/client/src/components/shops/buyModal.vue
+@@ -112,16 +112,6 @@
+ >{{ item.value }}</span>
+ </div>
+ </div>
+- <div
+- v-if="item.key === 'gem'"
+- class="gems-left"
+- >
+- <strong v-if="gemsLeft > 0">{{ gemsLeft }} {{ $t('gemsRemaining') }}</strong>
+- <strong v-if="gemsLeft === 0">{{ $t('maxBuyGems') }}</strong>
+- </div>
+- <div v-if="attemptingToPurchaseMoreGemsThanAreLeft">
+- {{ $t('notEnoughGemsToBuy') }}
+- </div>
+ <button
+ v-if="getPriceClass() === 'gems'
+ && !enoughCurrency(getPriceClass(), item.value * selectedAmountToBuy)"
+@@ -133,8 +123,7 @@
+ <button
+ v-else
+ class="btn btn-primary"
+- :disabled="item.key === 'gem' && gemsLeft === 0 ||
+- attemptingToPurchaseMoreGemsThanAreLeft || numberInvalid"
++ :disabled="numberInvalid"
+ :class="{'notEnough': !preventHealthPotion ||
+ !enoughCurrency(getPriceClass(), item.value * selectedAmountToBuy)}"
+ @click="buyItem()"
+@@ -342,10 +331,6 @@
margin: 10px 0 24px;
}
@@ -77,97 +81,104 @@ index 2a230e04b3..15d719f719 100644
.free-rebirth {
background-color: $yellow-5;
color: $white;
-@@ -275,7 +264,6 @@
+@@ -365,7 +350,6 @@ import keys from 'lodash/keys';
+ import reduce from 'lodash/reduce';
+ import moment from 'moment';
+ import spellsMixin from '@/mixins/spells';
+-import planGemLimits from '@/../../common/script/libs/planGemLimits';
+ import numberInvalid from '@/mixins/numberInvalid';
- <script>
- import spellsMixin from 'client/mixins/spells';
-- import planGemLimits from 'common/script/libs/planGemLimits';
- import numberInvalid from 'client/mixins/numberInvalid';
-
- import svgClose from 'assets/svg/close.svg';
-@@ -372,14 +360,6 @@
- limitedString () {
- return this.$t('limitedOffer', {date: moment(seasonalShopConfig.dateRange.end).format('LL')});
- },
-- gemsLeft () {
-- if (!this.user.purchased.plan) return 0;
-- return planGemLimits.convCap + this.user.purchased.plan.consecutive.gemCapExtra - this.user.purchased.plan.gemsBought;
-- },
-- attemptingToPurchaseMoreGemsThanAreLeft () {
-- if (this.item && this.item.key && this.item.key === 'gem' && this.selectedAmountToBuy > this.gemsLeft) return true;
-- return false;
-- },
- notEnoughCurrency () {
- return !this.enoughCurrency(this.getPriceClass(), this.item.value * this.selectedAmountToBuy);
- },
-diff --git a/website/client/components/shops/market/categoryItem.vue b/website/client/components/shops/market/categoryItem.vue
-index bdd4546ca9..50a453312a 100644
---- a/website/client/components/shops/market/categoryItem.vue
-+++ b/website/client/components/shops/market/categoryItem.vue
-@@ -5,8 +5,6 @@ div
- :show="true",
- :count="count"
- )
-- .badge.badge-pill.badge-purple.gems-left(v-if='item.key === "gem"')
-- | {{ gemsLeft }}
- span.badge.badge-pill.badge-item.badge-svg(
- :class="{'item-selected-badge': item.pinned, 'hide': !item.pinned}",
- @click.prevent.stop="togglePinned(item)"
-@@ -19,7 +17,6 @@ import { mapState } from 'client/libs/store';
- import CountBadge from 'client/components/ui/countBadge';
+ import svgClose from '@/assets/svg/close.svg';
+@@ -472,15 +456,6 @@ export default {
+ limitedString () {
+ return this.$t('limitedOffer', { date: moment(seasonalShopConfig.dateRange.end).format('LL') });
+ },
+- gemsLeft () {
+- if (!this.user.purchased.plan) return 0;
+- return planGemLimits.convCap
+- + this.user.purchased.plan.consecutive.gemCapExtra - this.user.purchased.plan.gemsBought;
+- },
+- attemptingToPurchaseMoreGemsThanAreLeft () {
+- if (this.item && this.item.key && this.item.key === 'gem' && this.selectedAmountToBuy > this.gemsLeft) return true;
+- return false;
+- },
+ notEnoughCurrency () {
+ return !this.enoughCurrency(this.getPriceClass(), this.item.value * this.selectedAmountToBuy);
+ },
+diff --git a/website/client/src/components/shops/market/categoryItem.vue b/website/client/src/components/shops/market/categoryItem.vue
+index 1d7613b08e..035fe3119a 100644
+--- a/website/client/src/components/shops/market/categoryItem.vue
++++ b/website/client/src/components/shops/market/categoryItem.vue
+@@ -5,12 +5,6 @@
+ :show="true"
+ :count="count"
+ />
+- <div
+- v-if="item.key === 'gem'"
+- class="badge badge-pill badge-purple gems-left"
+- >
+- {{ gemsLeft }}
+- </div>
+ <span
+ class="badge badge-pill badge-item badge-svg"
+ :class="{'item-selected-badge': item.pinned, 'hide': !item.pinned}"
+@@ -29,7 +23,6 @@ import { mapState } from '@/libs/store';
+ import CountBadge from '@/components/ui/countBadge';
- import svgPin from 'assets/svg/pin.svg';
--import planGemLimits from 'common/script/libs/planGemLimits';
+ import svgPin from '@/assets/svg/pin.svg';
+-import planGemLimits from '@/../../common/script/libs/planGemLimits';
import pinUtils from '../../../mixins/pinUtils';
export default {
-@@ -43,10 +40,6 @@ export default {
+@@ -53,11 +46,6 @@ export default {
count () {
return this.userItems[this.item.purchaseType][this.item.key];
},
- gemsLeft () {
- if (!this.user.purchased.plan) return 0;
-- return planGemLimits.convCap + this.user.purchased.plan.consecutive.gemCapExtra - this.user.purchased.plan.gemsBought;
+- return planGemLimits.convCap
+- + this.user.purchased.plan.consecutive.gemCapExtra - this.user.purchased.plan.gemsBought;
- },
},
};
</script>
-diff --git a/website/client/components/shops/market/categoryRow.vue b/website/client/components/shops/market/categoryRow.vue
-index 9f4b96acd6..d9b8ec7a63 100644
---- a/website/client/components/shops/market/categoryRow.vue
-+++ b/website/client/components/shops/market/categoryRow.vue
-@@ -7,7 +7,6 @@ div.items
- :popoverPosition="'top'",
- @click="itemSelected(item)")
- span(slot="popoverContent")
-- strong(v-if='item.key === "gem" && gemsLeft === 0') {{ $t('maxBuyGems') }}
- h4.popover-content-title {{ item.text }}
- template(slot="itemBadge", slot-scope="ctx")
- category-item(:item='ctx.item')
-@@ -16,7 +15,6 @@ div.items
- <script>
- import { mapState } from 'client/libs/store';
- import pinUtils from 'client/mixins/pinUtils';
-- import planGemLimits from 'common/script/libs/planGemLimits';
+diff --git a/website/client/src/components/shops/market/categoryRow.vue b/website/client/src/components/shops/market/categoryRow.vue
+index eb4a79b6c4..e95f01ad51 100644
+--- a/website/client/src/components/shops/market/categoryRow.vue
++++ b/website/client/src/components/shops/market/categoryRow.vue
+@@ -9,7 +9,6 @@
+ @click="itemSelected(item)"
+ >
+ <span slot="popoverContent">
+- <strong v-if="item.key === 'gem' && gemsLeft === 0">{{ $t('maxBuyGems') }}</strong>
+ <h4 class="popover-content-title">{{ item.text }}</h4>
+ </span>
+ <template
+@@ -28,7 +27,6 @@ import _sortBy from 'lodash/sortBy';
+ import _map from 'lodash/map';
+ import { mapState } from '@/libs/store';
+ import pinUtils from '@/mixins/pinUtils';
+-import planGemLimits from '@/../../common/script/libs/planGemLimits';
- import ShopItem from '../shopItem';
- import CategoryItem from './categoryItem';
-@@ -39,10 +37,6 @@ div.items
- userItems: 'user.data.items',
- userStats: 'user.data.stats',
- }),
-- gemsLeft () {
-- if (!this.user.purchased.plan) return 0;
-- return planGemLimits.convCap + this.user.purchased.plan.consecutive.gemCapExtra - this.user.purchased.plan.gemsBought;
-- },
- sortedMarketItems () {
- let result = _map(this.category.items, (e) => {
- return {
-diff --git a/website/client/components/shops/market/index.vue b/website/client/components/shops/market/index.vue
-index fb2f332da8..fc2e8163b5 100644
---- a/website/client/components/shops/market/index.vue
-+++ b/website/client/components/shops/market/index.vue
-@@ -115,11 +115,6 @@
+ import ShopItem from '../shopItem';
+ import CategoryItem from './categoryItem';
+@@ -48,11 +46,6 @@ export default {
+ userItems: 'user.data.items',
+ userStats: 'user.data.stats',
+ }),
+- gemsLeft () {
+- if (!this.user.purchased.plan) return 0;
+- return planGemLimits.convCap
+- + this.user.purchased.plan.consecutive.gemCapExtra - this.user.purchased.plan.gemsBought;
+- },
+ sortedMarketItems () {
+ let result = _map(this.category.items, e => ({
+ ...e,
+diff --git a/website/client/src/components/shops/market/index.vue b/website/client/src/components/shops/market/index.vue
+index cb660cbf72..3ed1be3ca4 100644
+--- a/website/client/src/components/shops/market/index.vue
++++ b/website/client/src/components/shops/market/index.vue
+@@ -149,11 +149,6 @@
}
}
}
@@ -180,14 +191,15 @@ index fb2f332da8..fc2e8163b5 100644
diff --git a/website/common/script/ops/buy/buyGem.js b/website/common/script/ops/buy/buyGem.js
-index 81fa5be9da..08dc3ee2f7 100644
+index 7a7255c021..7725dfa832 100644
--- a/website/common/script/ops/buy/buyGem.js
+++ b/website/common/script/ops/buy/buyGem.js
-@@ -33,12 +33,6 @@ export class BuyGemOperation extends AbstractGoldItemOperation {
- let key = this.key = get(req, 'params.key');
+@@ -29,13 +29,6 @@ export class BuyGemOperation extends AbstractGoldItemOperation { // eslint-disab
+ this.key = get(req, 'params.key');
+ const { key } = this;
if (!key) throw new BadRequest(this.i18n('missingKeyParam'));
-
-- let convCap = planGemLimits.convCap;
+-
+- let { convCap } = planGemLimits;
- convCap += user.purchased.plan.consecutive.gemCapExtra;
-
- // todo better name?
@@ -196,13 +208,13 @@ index 81fa5be9da..08dc3ee2f7 100644
this.canUserPurchase(user);
}
-@@ -48,17 +42,6 @@ export class BuyGemOperation extends AbstractGoldItemOperation {
+@@ -45,17 +38,6 @@ export class BuyGemOperation extends AbstractGoldItemOperation { // eslint-disab
}
super.canUserPurchase(user, item);
-
- if (user.purchased.plan.gemsBought >= this.convCap) {
-- throw new NotAuthorized(this.i18n('reachedGoldToGemCap', {convCap: this.convCap}));
+- throw new NotAuthorized(this.i18n('reachedGoldToGemCap', { convCap: this.convCap }));
- }
-
- if (user.purchased.plan.gemsBought + this.quantity > this.convCap) {
diff --git a/pkgs/shabitica/patches/one-admin-mailaddr.patch b/pkgs/shabitica/patches/one-admin-mailaddr.patch
index fbb7471..292e590 100644
--- a/pkgs/shabitica/patches/one-admin-mailaddr.patch
+++ b/pkgs/shabitica/patches/one-admin-mailaddr.patch
@@ -18,7 +18,7 @@ Date: Tue Mar 27 05:37:18 2018 +0200
Filename: one-admin-mailaddr.patch
diff --git a/config.json.example b/config.json.example
-index cb82930b49..9fdd842b62 100644
+index e1c6fe35da..30cd9504fb 100644
--- a/config.json.example
+++ b/config.json.example
@@ -4,12 +4,8 @@
@@ -35,45 +35,45 @@ index cb82930b49..9fdd842b62 100644
"MAILER_SOCKET": "/run/habitica/mailer.sock",
"MAINTENANCE_MODE": "false",
diff --git a/test/api/v3/integration/chat/POST-groups_id_chat_id_clear_flags.test.js b/test/api/v3/integration/chat/POST-groups_id_chat_id_clear_flags.test.js
-index 98ce34d35a..a0b90dbc84 100644
+index 9bbc122244..ae9a64cee7 100644
--- a/test/api/v3/integration/chat/POST-groups_id_chat_id_clear_flags.test.js
+++ b/test/api/v3/integration/chat/POST-groups_id_chat_id_clear_flags.test.js
-@@ -3,7 +3,6 @@ import {
+@@ -5,7 +5,6 @@ import {
generateUser,
translate as t,
} from '../../../../helpers/api-integration/v3';
-import config from '../../../../../config.json';
- import moment from 'moment';
- import { v4 as generateUUID } from 'uuid';
-@@ -103,11 +102,7 @@ describe('POST /groups/:id/chat/:id/clearflags', () => {
+ describe('POST /groups/:id/chat/:id/clearflags', () => {
+ const USER_AGE_FOR_FLAGGING = 3;
+@@ -102,11 +101,7 @@ describe('POST /groups/:id/chat/:id/clearflags', () => {
- let [skillMsg] = await member.get(`/groups/${group.id}/chat`);
+ const [skillMsg] = await member.get(`/groups/${group.id}/chat`);
await expect(member.post(`/groups/${group._id}/chat/${skillMsg.id}/flag`))
- .to.eventually.be.rejected.and.eql({
- code: 400,
- error: 'BadRequest',
-- message: t('messageCannotFlagSystemMessages', {communityManagerEmail: config.EMAILS_COMMUNITY_MANAGER_EMAIL}),
+- message: t('messageCannotFlagSystemMessages', { communityManagerEmail: config.EMAILS_COMMUNITY_MANAGER_EMAIL }),
- });
+ .to.eventually.be.rejected;
// let messages = await members[0].get(`/groups/${group._id}/chat`);
// expect(messages[0].id).to.eql(skillMsg.id);
// expect(messages[0].flagCount).to.eql(0);
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 2a648e2bb3..1695d3966d 100644
+index f677f038fe..a3c50c38df 100644
--- a/test/api/v3/integration/groups/POST-groups_invite.test.js
+++ b/test/api/v3/integration/groups/POST-groups_invite.test.js
-@@ -333,7 +333,7 @@ describe('Post /groups/:groupId/invite', () => {
+@@ -336,7 +336,7 @@ describe('Post /groups/:groupId/invite', () => {
.to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
-- message: t('inviteLimitReached', {techAssistanceEmail: nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL')}),
-+ message: t('inviteLimitReached', {techAssistanceEmail: nconf.get('ADMIN_EMAIL')}),
+- message: t('inviteLimitReached', { techAssistanceEmail: nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL') }),
++ message: t('inviteLimitReached', { techAssistanceEmail: nconf.get('ADMIN_EMAIL') }),
});
});
diff --git a/test/api/v3/integration/user/DELETE-user.test.js b/test/api/v3/integration/user/DELETE-user.test.js
-index 1694349e53..a7785fd49c 100644
+index 68eb7e8972..3ae100d9f8 100644
--- a/test/api/v3/integration/user/DELETE-user.test.js
+++ b/test/api/v3/integration/user/DELETE-user.test.js
@@ -63,11 +63,7 @@ describe('DELETE /user', () => {
@@ -90,7 +90,7 @@ index 1694349e53..a7785fd49c 100644
it('returns no error if user has active subscription', async () => {
diff --git a/test/api/v3/integration/user/auth/POST-login-local.test.js b/test/api/v3/integration/user/auth/POST-login-local.test.js
-index 484ff16af5..c3f88ecda2 100644
+index c88176576d..edb0e2d900 100644
--- a/test/api/v3/integration/user/auth/POST-login-local.test.js
+++ b/test/api/v3/integration/user/auth/POST-login-local.test.js
@@ -45,7 +45,7 @@ describe('POST /user/auth/local/login', () => {
@@ -103,7 +103,7 @@ index 484ff16af5..c3f88ecda2 100644
});
diff --git a/test/api/v3/integration/user/auth/PUT-user_update_email.test.js b/test/api/v3/integration/user/auth/PUT-user_update_email.test.js
-index d540dbd27b..d8470644ac 100644
+index d924a99ebf..91b0da293f 100644
--- a/test/api/v3/integration/user/auth/PUT-user_update_email.test.js
+++ b/test/api/v3/integration/user/auth/PUT-user_update_email.test.js
@@ -71,7 +71,7 @@ describe('PUT /user/auth/update-email', () => {
@@ -115,55 +115,66 @@ index d540dbd27b..d8470644ac 100644
});
});
-diff --git a/webpack/config/prod.env.js b/webpack/config/prod.env.js
-index 1609e92969..5bfbbd7ef5 100644
---- a/webpack/config/prod.env.js
-+++ b/webpack/config/prod.env.js
-@@ -17,9 +17,9 @@ let env = {
- NODE_ENV: '"production"',
- // clientVars: CLIENT_VARS,
- EMAILS: {
-- COMMUNITY_MANAGER_EMAIL: `"${nconf.get('EMAILS_COMMUNITY_MANAGER_EMAIL')}"`,
-- TECH_ASSISTANCE_EMAIL: `"${nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL')}"`,
-- PRESS_ENQUIRY_EMAIL: `"${nconf.get('EMAILS_PRESS_ENQUIRY_EMAIL')}"`,
-+ COMMUNITY_MANAGER_EMAIL: `"${nconf.get('ADMIN_EMAIL')}"`,
-+ TECH_ASSISTANCE_EMAIL: `"${nconf.get('ADMIN_EMAIL')}"`,
-+ PRESS_ENQUIRY_EMAIL: `"${nconf.get('ADMIN_EMAIL')}"`,
- },
- };
-
+diff --git a/website/client/src/app.vue b/website/client/src/app.vue
+index 890558f15a..8e150d5633 100644
+--- a/website/client/src/app.vue
++++ b/website/client/src/app.vue
+@@ -236,7 +236,7 @@ import { CONSTANTS, getLocalSetting, removeLocalSetting } from '@/libs/userlocal
+ 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
++const COMMUNITY_MANAGER_EMAIL = process.env.ADMIN_EMAIL; // eslint-disable-line
+
+ export default {
+ name: 'App',
+diff --git a/website/client/vue.config.js b/website/client/vue.config.js
+index b1a7f55529..197d281cf1 100644
+--- a/website/client/vue.config.js
++++ b/website/client/vue.config.js
+@@ -14,9 +14,7 @@ setupNconf(configFile, nconf);
+ const DEV_BASE_URL = nconf.get('BASE_URL');
+
+ const envVars = [
+- 'EMAILS_COMMUNITY_MANAGER_EMAIL',
+- 'EMAILS_TECH_ASSISTANCE_EMAIL',
+- 'EMAILS_PRESS_ENQUIRY_EMAIL',
++ 'ADMIN_EMAIL',
+ 'BASE_URL',
+ // TODO necessary? if yes how not to mess up with vue cli? 'NODE_ENV'
+ ];
diff --git a/website/server/controllers/api-v3/auth.js b/website/server/controllers/api-v3/auth.js
-index 3e3544aa34..4aa06e0335 100644
+index 86269e9c10..dd4191dbbd 100644
--- a/website/server/controllers/api-v3/auth.js
+++ b/website/server/controllers/api-v3/auth.js
-@@ -20,7 +20,7 @@ import {
- import {verifyUsername} from '../../libs/user/validation';
+@@ -19,7 +19,7 @@ import {
+ import { verifyUsername } from '../../libs/user/validation';
const BASE_URL = nconf.get('BASE_URL');
-const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL');
+const TECH_ASSISTANCE_EMAIL = nconf.get('ADMIN_EMAIL');
- let api = {};
+ const api = {};
diff --git a/website/server/controllers/api-v3/chat.js b/website/server/controllers/api-v3/chat.js
-index 4534e45f39..0bac414b58 100644
+index e3836558ec..648a0739be 100644
--- a/website/server/controllers/api-v3/chat.js
+++ b/website/server/controllers/api-v3/chat.js
-@@ -19,7 +19,7 @@ import { getMatchesByWordArray } from '../../libs/stringUtils';
- import bannedSlurs from '../../libs/bannedSlurs';
+@@ -20,7 +20,7 @@ import bannedSlurs from '../../libs/bannedSlurs';
import apiError from '../../libs/apiError';
+ import { highlightMentions } from '../../libs/highlightMentions';
--const FLAG_REPORT_EMAILS = nconf.get('FLAG_REPORT_EMAIL').split(',').map((email) => {
-+const FLAG_REPORT_EMAILS = nconf.get('ADMIN_EMAIL').split(',').map((email) => {
- return { email, canSend: true };
- });
+-const FLAG_REPORT_EMAILS = nconf.get('FLAG_REPORT_EMAIL').split(',').map(email => ({ email, canSend: true }));
++const FLAG_REPORT_EMAILS = nconf.get('ADMIN_EMAIL').split(',').map(email => ({ email, canSend: true }));
+ /**
+ * @apiDefine MessageNotFound
diff --git a/website/server/controllers/api-v3/groups.js b/website/server/controllers/api-v3/groups.js
-index 262361ab39..96ffc6ed7e 100644
+index 5ce1e243f5..7048fba428 100644
--- a/website/server/controllers/api-v3/groups.js
+++ b/website/server/controllers/api-v3/groups.js
-@@ -25,7 +25,7 @@ import common from '../../../common';
- import apiError from '../../libs/apiError';
+@@ -26,7 +26,7 @@ import apiError from '../../libs/apiError';
+ import { model as UserNotification } from '../../models/userNotification';
const MAX_EMAIL_INVITES_BY_USER = 200;
-const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL');
@@ -172,12 +183,12 @@ index 262361ab39..96ffc6ed7e 100644
/**
* @apiDefine GroupBodyInvalid
diff --git a/website/server/controllers/api-v3/user.js b/website/server/controllers/api-v3/user.js
-index 70cd50820c..fe65ba53dc 100644
+index 8f2a991b8e..7f8f0fa941 100644
--- a/website/server/controllers/api-v3/user.js
+++ b/website/server/controllers/api-v3/user.js
-@@ -23,7 +23,7 @@ import * as userLib from '../../libs/user';
- import nconf from 'nconf';
- import get from 'lodash/get';
+@@ -23,7 +23,7 @@ import {
+ import * as inboxLib from '../../libs/inbox';
+ import * as userLib from '../../libs/user';
-const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL');
+const TECH_ASSISTANCE_EMAIL = nconf.get('ADMIN_EMAIL');
@@ -185,7 +196,7 @@ index 70cd50820c..fe65ba53dc 100644
/**
* @apiDefine UserNotFound
diff --git a/website/server/libs/auth/utils.js b/website/server/libs/auth/utils.js
-index 8e9265be22..f5785583c6 100644
+index f500b8fcbb..cc43786788 100644
--- a/website/server/libs/auth/utils.js
+++ b/website/server/libs/auth/utils.js
@@ -2,7 +2,7 @@ import nconf from 'nconf';
@@ -195,43 +206,44 @@ index 8e9265be22..f5785583c6 100644
-const COMMUNITY_MANAGER_EMAIL = nconf.get('EMAILS_COMMUNITY_MANAGER_EMAIL');
+const COMMUNITY_MANAGER_EMAIL = nconf.get('ADMIN_EMAIL');
- function loginRes (user, req, res) {
- if (user.auth.blocked) throw new NotAuthorized(res.t('accountSuspended', {communityManagerEmail: COMMUNITY_MANAGER_EMAIL, userId: user._id}));
+ export function loginRes (user, req, res) {
+ if (user.auth.blocked) {
diff --git a/website/server/libs/chatReporting/groupChatReporter.js b/website/server/libs/chatReporting/groupChatReporter.js
-index 806358dbd7..6e06e122d6 100644
+index 7c7c027837..6add55ae16 100644
--- a/website/server/libs/chatReporting/groupChatReporter.js
+++ b/website/server/libs/chatReporting/groupChatReporter.js
-@@ -11,8 +11,8 @@ import { model as Group } from '../../models/group';
+@@ -11,9 +11,9 @@ import { model as Group } from '../../models/group';
import { chatModel as Chat } from '../../models/message';
import apiError from '../apiError';
-const COMMUNITY_MANAGER_EMAIL = nconf.get('EMAILS_COMMUNITY_MANAGER_EMAIL');
--const FLAG_REPORT_EMAILS = nconf.get('FLAG_REPORT_EMAIL').split(',').map((email) => {
+const COMMUNITY_MANAGER_EMAIL = nconf.get('ADMIN_EMAIL');
-+const FLAG_REPORT_EMAILS = nconf.get('ADMIN_EMAIL').split(',').map((email) => {
- return { email, canSend: true };
- });
+ const FLAG_REPORT_EMAILS = nconf
+- .get('FLAG_REPORT_EMAIL')
++ .get('ADMIN_EMAIL')
+ .split(',')
+ .map(email => ({ email, canSend: true }));
const USER_AGE_FOR_FLAGGING = 3; // accounts less than this many days old don't increment flagCount
diff --git a/website/server/libs/chatReporting/inboxChatReporter.js b/website/server/libs/chatReporting/inboxChatReporter.js
-index e8078d83cf..9ce229cfca 100644
+index b20d5dc5e0..1b823028b1 100644
--- a/website/server/libs/chatReporting/inboxChatReporter.js
+++ b/website/server/libs/chatReporting/inboxChatReporter.js
@@ -11,7 +11,7 @@ import apiError from '../apiError';
import * as inboxLib from '../inbox';
- import {getAuthorEmailFromMessage} from '../chat';
+ import { getAuthorEmailFromMessage } from '../chat';
--const FLAG_REPORT_EMAILS = nconf.get('FLAG_REPORT_EMAIL').split(',').map((email) => {
-+const FLAG_REPORT_EMAILS = nconf.get('ADMIN_EMAIL').split(',').map((email) => {
- return { email, canSend: true };
- });
+-const FLAG_REPORT_EMAILS = nconf.get('FLAG_REPORT_EMAIL')
++const FLAG_REPORT_EMAILS = nconf.get('ADMIN_EMAIL')
+ .split(',')
+ .map(email => ({ email, canSend: true }));
diff --git a/website/server/middlewares/auth.js b/website/server/middlewares/auth.js
-index 0908dd42d7..8cfe379ab7 100644
+index a094e244f6..0cd8e740d9 100644
--- a/website/server/middlewares/auth.js
+++ b/website/server/middlewares/auth.js
@@ -7,7 +7,7 @@ import {
- import nconf from 'nconf';
- import url from 'url';
+ model as User,
+ } from '../models/user';
-const COMMUNITY_MANAGER_EMAIL = nconf.get('EMAILS_COMMUNITY_MANAGER_EMAIL');
+const COMMUNITY_MANAGER_EMAIL = nconf.get('ADMIN_EMAIL');
diff --git a/pkgs/shabitica/patches/privacy-policy.patch b/pkgs/shabitica/patches/privacy-policy.patch
index 8804042..85d3549 100644
--- a/pkgs/shabitica/patches/privacy-policy.patch
+++ b/pkgs/shabitica/patches/privacy-policy.patch
@@ -12,317 +12,337 @@ Date: Thu Mar 29 06:27:23 2018 +0200
Signed-off-by: aszlig <aszlig@nix.build>
Filename: privacy-policy.patch
-diff --git a/website/client/components/static/privacy.vue b/website/client/components/static/privacy.vue
-index 2ecda4b8ad..0a3e8e90be 100644
---- a/website/client/components/static/privacy.vue
-+++ b/website/client/components/static/privacy.vue
-@@ -2,298 +2,18 @@
- .container-fluid
- h1 Privacy Policy
- p.pagemeta
-- | Last updated July 27, 2015
-- br
-- small (Corrected grammar errors and updated company name)
-- br
-- br
-+ | This is a fork of the official Habitica source code and one of the main
-+ | reasons for the fork is its awful privacy policy.
- p
-- strong PLEASE READ THIS PRIVACY POLICY CAREFULLY&period;
-- br
-- | By accessing or otherwise using habitica&period;com or any sub domains thereto &lpar;&quot;the Sites&quot;&rpar;&comma;
-- | or using a habitica&period;com or Habitica application on a mobile device &lpar;&quot;the Applications&quot;&rpar;&comma;
-- | you agree to be bound contractually by this Privacy Policy&period; Individually
-- | or collectively&comma; the Applications and the Sites may be referred to as
-- | the &quot;Services&period;&quot;
-+ | To keep this very short, the only personal information that is
-+ | collected is the email address, the name of the user and data about the
-+ | tasks.
- p
-- | To review material modifications and their effective dates scroll
-- | to the bottom of the page&period;
-+ | All that information is never shared with any third parties and the
-+ | site itself doesn't use any analytics, advertising, social auth or any
-+ | other bullshit that nobody wants to have.
- p
-- strong
-- | 1&period; Privacy Statement&semi; Collection of Personal
-- | Information&period;
-- br
-- | 1&period;1 HabitRPG, Inc. owns and operates this business&period; All
-- | references to &quot;we&quot;&comma; &quot;us&quot;&comma; shall be construed to mean HabitRPG, Inc.&period;
-- p
-- | 1&period;2 We understand that visitors to this website are concerned
-- | about the privacy of information&period; The following describes our privacy
-- | policy regarding information&comma; including personal information&comma; that we
-- | collect through this website&period;
-- p
-- strong 2&period; Modification of Privacy Policy&period;
-- br
-- | We reserve the right to modify this Privacy Policy at any time&comma;
-- | and without prior notice&comma; by posting an amended Privacy Policy that is
-- | always accessible by clicking on the &quot;Privacy Policy&quot; link on this
-- | site&apos;s home page&period; Your continued use of this site indicates your
-- | acceptance of the amended Privacy Policy&period; You should check the Privacy
-- | Policy through this link periodically for modifications by clicking on
-- | the link provided near the top of the Privacy Policy for a listing of
-- | material modifications and their effective dates&period; Regarding personal
-- | information&comma; if any modifications are materially less restrictive on our
-- | use or disclosure of the personal information previously disclosed by
-- | you&comma; we will obtain your consent before implementing such revisions with
-- | respect to such information&period;
-- p
-- strong 3&period; Collection of Anonymous&comma; Passive Information&period;
-- br
-- | We reserve the right to monitor your use of the services&period; As you
-- | navigate through the services&comma; certain anonymous information may be
-- | passively collected &lpar;that is&comma; gathered without your actively providing
-- | the information&rpar; using various technologies&comma; such as cookies&comma; Internet
-- | tags or web beacons&comma; and navigational data collection &lpar;log files&comma; server
-- | logs&comma; clickstream&rpar;&period; The following is a listing and a brief explanation
-- | of passive information collection methodologies which we may use from
-- | time to time to better understand how the Services are being used&period;
-- p
-- | 3&period;1 A &quot;cookie&quot; is a text file that this site sends to your
-- | browser in the form of a text file The information generated by the
-- | cookie about your use of this site &lpar;including your IP address&rpar; will be
-- | transmitted to and stored&period; Most browsers automatically accept cookies&comma;
-- | but they usually can be modified to decline cookies if you prefer&semi;
-- | however&comma; certain features of this site might not work without cookies&period;
-- p
-- | 3&period;2 &quot;Session&quot; cookies are temporary bits of information that are
-- | used to improve navigation&comma; block visitors from providing information
-- | where inappropriate &lpar;the Services &quot;remembers&quot; previous entries of age or
-- | country of origin that were outside the specified parameters and blocks
-- | subsequent changes&rpar;&comma; and collect aggregate statistical information on
-- | the Services&period; They are erased once you exit your Web browser or
-- | otherwise turn off your computer&period;
-- p
-- | 3&period;3 &quot;Persistent&quot; cookies are more permanent bits of information
-- | that are placed on the hard drive of your computer and stay there unless
-- | you delete the cookie&period; Persistent cookies store information on your
-- | computer for a number of purposes&comma; such as retrieving certain
-- | information you have previously provided&comma; helping to determine what
-- | areas of the Services you may find most valuable&comma; and customizing the
-- | Services based on your preferences on an ongoing basis&period; Persistent
-- | cookies placed by this site in your computer do not hold personal
-- | information&period;
-- p
-- | 3&period;4 You can set your browser to accept all cookies&comma; to reject all
-- | cookies&comma; or to notify you whenever a cookie is offered so that you can
-- | decide each time whether to accept it&period; To learn more about cookies and
-- | how to specify your preferences&comma; please search for &quot;cookie&quot; in the
-- | &quot;Help&quot; portion of your browser&period;
-- p
-- | 3&period;5 An Internet Protocol &lpar;IP&rpar; address is a number assigned to
-- | your computer by your Internet service provider so you can access the
-- | Internet and is generally considered to be non-personally identifiable
-- | information&comma; because in most cases an IP address is dynamic &lpar;changing
-- | each time you connect to the Internet&rpar;&comma; rather than static &lpar;unique to a
-- | particular user&apos;s computer&rpar;&period; The IP address can be used to diagnose
-- | problems with a server&comma; report aggregate information&comma; determine the
-- | fastest route for your computer to use in connecting to a site&comma; and
-- | administer and improve the Services&period;
-- p
-- | 3&period;6 &quot;Internet tags&quot; &lpar;also known as Web Beacons&comma; single-pixel
-- | GIFs&comma; clear GIFs&comma; invisible GIFs&comma; and 1-by-1 GIFs&rpar; are smaller than
-- | cookies and tell the Web site server information such as the IP address
-- | and browser type related to the visitor&apos;s computer&period; Tags may be placed
-- | both on online advertisements that bring people to the Services and on
-- | different pages of the Services&period; Such tags indicate how many times a
-- | page is opened and which information is consulted&period;
-- p
-- | 3&period;7 &quot;Navigational data&quot; &lpar;log files&comma; server logs&comma; and clickstream
-- | data&rpar; are used for system management&comma; to improve the content of the
-- | Services&comma; market research purposes&comma; and to communicate information to
-- | visitors&period;
-- p
-- strong 4&period; Use and Sharing of Anonymous&comma; Passive Information&period;
-- br
-- | The Services may make full use of passively collected anonymous
-- | information&comma; including without limitation the right to use such
-- | information to provide better service to Service users&comma; customize the
-- | Services based on your preferences&comma; compile and analyze statistics and
-- | trends&comma; and otherwise administer and improve the Services for your use&period; We
-- | reserve the right to share this anonymous&comma; passive information in
-- | aggregated form&period;
-- p
-- strong 5&period; 3rd Party Behavioral Ads&semi; Google&apos;s AdSense Network&period;
-- br
-- | 5&period;1 We reserve the right to use anonymous&comma; passive information
-- | about your visits to this and other websites &lpar;not including your name&comma;
-- | address&comma; email address or telephone number&rpar; for purposes of serving our
-- | ads and third party ads that are targeted to your interests &lpar;&quot;3rd Party
-- | Behavioral Ads&quot;&rpar;&period; We reserve the right to share anonymous&comma; passive
-- | information collected on the services with third parties for purposes of
-- | serving 3rd Party Behavioral Ads&period; These 3rd Party Behavioral Ads do not
-- | identify you personally&period; Instead&comma; they associate your behavioral data on
-- | visited sites with your browser&comma; so that the ads your computer sees on
-- | this site are more likely to be relevant to your interests&period; 3rd Party
-- | Behavioral Ads require that that you be served with a cookie containing
-- | a tracking code&period; You may refuse the use of cookies by selecting the
-- | appropriate settings on your browser&semi; however&comma; please note that if you
-- | do this you may not be able to use the full functionality of this site&period;
-- p
-- | 5&period;2 We reserve the right to participate in Google&apos;s AdSense
-- | network for purposes of serving 3rd Party Behavioral Ads&period; Google uses
-- | DoubleClick&apos;s DART cookie for serving 3rd Party Behavioral Ads over the
-- | AdSense network&period; You may opt out of the use of the DART cookie&period; For
-- | information regarding how to opt out&comma; go to
-- | http&colon;&sol;&sol;www&period;google&period;com&sol;privacy&UnderBar;ads&period;html&period;
-- p
-- strong 6&period; Use of 3rd Party Analytics&period;
-- br
-- | We reserve the right to use analytics services provided by
-- | third parties&period; These services use 3rd party cookies to collect
-- | anonymous&comma; passive information about your use of this site &lpar;see
-- | explanation of cookies in Collection of Anonymous&comma; Passive Information
-- | above&rpar;&period; We use this information for the purpose of evaluating your use
-- | of the Services&comma; compiling reports on activity&comma; and providing other
-- | services&period; These web analytics services may also transfer this
-- | information to third parties where required to do so by law&comma; or where
-- | such third parties process the information on the service&apos;s behalf&period;
-- p
-- strong 7&period; Collection of Personal Information&semi; Categories&period;
-- br
-- | We will ask you for personal information when you sign up for any
-- | specific benefit or purpose that requires registration&period; Personal
-- | information that we collect may vary with each registration&comma; and it may
-- | include one or more of the following categories&colon; name&comma; physical
-- | address&comma; an email address&comma; phone number&comma; and credit card information
-- | including credit card number&comma; expiration date&comma; and billing address&comma;
-- | emergency contact information&comma; current medications&comma; allergies&comma; medical
-- | insurance information&period;
-- p
-- strong
-- | 8&period; Use And Sharing of Personal Information&colon; General
-- | Policy And Exceptions&period;
-- br
-- | Our general policy is that we will use your personal information&comma;
-- | including combining your personal information with passive information
-- | collected from this site&comma; only for&colon; the performance of the services or
-- | transaction for which it was given&comma; our private&comma; internal reporting for
-- | this site&comma; and security assessments for this site&comma; and we will not
-- | share&comma; sell&comma; or rent your personal information to others&period; The only
-- | exceptions to this general policy&colon; &lpar;i&rpar; are described in the subsections
-- | below&comma; and &lpar;ii&rpar; if you explicitly approve through our site&period;
-- p
-- | 8&period;1 Affiliates And Service Providers&period; We reserve the right to
-- | provide such information to our affiliates or subsidiaries&comma; or trusted
-- | service providers for the purpose of hosting our servers or processing
-- | or archiving personal information for us&period; We require that these parties
-- | agree to privacy and security safeguards for this information that are
-- | consistent with this Privacy Policy&period;
-- p
-- | 8&period;2 Acquisition&semi; Bankruptcy&period; In the event that we are acquired by
-- | or merged with a third party entity&comma; we reserve the right to transfer
-- | such information as part of such merger&comma; acquisition&comma; sale&comma; or other
-- | change of control&period; In the unlikely event of our bankruptcy&comma; insolvency&comma;
-- | reorganization&comma; receivership&comma; or assignment for the benefit of
-- | creditors&comma; or the application of laws or equitable principles affecting
-- | creditors&apos; rights generally&comma; we reserve the right to transfer such
-- | information to protect our rights or as required by law&period;
-- p
-- | 8&period;3 Enforcement&semi; Legal Process&period; We reserve the right to transfer
-- | such information if we have a good faith belief that access&comma; use&comma;
-- | preservation or disclosure of such information is reasonably necessary
-- | &lpar;i&rpar; to satisfy any applicable law&comma; regulation&comma; legal process or
-- | enforceable governmental request&comma; or &lpar;ii&rpar; to investigate or enforce
-- | violations of our rights or the security of this site&period;
-- p
-- | 8&period;4 Miscellaneous&period; We reserve the right to share personal
-- | information with the following additional parties&colon; online organizers
-- | using our tools and resellers of our products and services from whose
-- | site the sale originated &lpar;even though the sale originates at site of the
-- | reseller&comma; registration and collection of personal information occurs at
-- | this site&rpar;&period;
-- p
-- strong
-- | 9&period; Onward Transfer of Personal Information Outside Your
-- | Country of Residence&period;
-- br
-- | Any personal information which we may collect on this site will
-- | be stored and processed in our servers located only in the United
-- | States&period; By using this site&comma; if you reside outside the United States&comma; you
-- | consent to the transfer of personal information outside your country of
-- | residence to the United States&period;
-- p
-- strong 10&period; Security of Personal Information&period;
-- br
-- | We follow reasonable and appropriate industry standards to
-- | protect your personal information and data&period; Unfortunately&comma; no data
-- | transmission over the Internet or method of data storage can be
-- | guaranteed 100&percnt; secure&period; Therefore&comma; while we strive to protect your
-- | personal information by following generally accepted industry standards&comma;
-- | we cannot ensure or warrant the absolute security of any information you
-- | transmit to us or archive at this site&period;
-- p
-- strong 11&period; Changing And Updating Personal Information&period;
-- br
-- | Upon request&comma; we will permit you to request or make changes or
-- | updates to your personal information for legitimate purposes&period; We request
-- | identification prior to approving such requests&period; We reserve the right to
-- | decline any requests that are unreasonably repetitive or systematic&comma;
-- | require unreasonable time or effort of our technical or administrative
-- | personnel&comma; or undermine the privacy rights of others&period; We reserve the
-- | right to permit you to access your personal information in any account
-- | you establish with this site for purposes of making your own changes or
-- | updates&comma; and in such case&comma; instructions for making such changes or
-- | updates will be provided where necessary&period;
-- p
-- strong 12&period; Email From This Site&semi; Opt-Out Rights&period;
-- br
-- | If you supply us with your e-mail address you may receive
-- | periodic messages from us with information specific to the Services and
-- | required for the normal functioning of the Services as well as for new
-- | products or services or upcoming events&period; If you prefer not to receive
-- | periodic email messages&comma; you may opt-out by following the instructions
-- | on the email&period;
-- p
-- strong 13&period; Children&apos;s Online Policy&period;
-- br
-- | We are committed to preserving online privacy for all of our
-- | website visitors&comma; including children&period; This site is a general audience
-- | site&period; Consistent with the Children&apos;s Online Privacy Protection Act
-- | &lpar;COPPA&rpar;&comma; we will not knowingly collect any information from&comma; or sell to&comma;
-- | children under the age of 13&period; If you are a parent or guardian who has
-- | discovered that your child under the age of 13 has submitted his or her
-- | personally identifiable information without your permission or consent&comma;
-- | we will remove the information from our active list&comma; at your request&period; To
-- | request the removal of your child&apos;s information&comma; please email us at
-- | <a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a> and be sure to include in
-- | your message the same login information that your child submitted&period;
-- p
-- strong
-- | 14&period; Email And Other Messages Through This Site&semi; ECPA
-- | Notice&period;
-- br
-- | This site treats email messages and other electronic messages
-- | that are sent through this site and not viewable by others as
-- | confidential and private&comma; except as required by law&comma; including without
-- | limitation&comma; the Electronic Communications Privacy Act of 1986&comma; 18 U&period;S&period;C&period;
-- | Sections 2701-2711 &lpar;the &quot;ECPA&quot;&rpar;&period; The ECPA permits this site&apos;s limited
-- | ability to intercept and&sol;or disclose electronic messages&comma; for example
-- | &lpar;i&rpar; as necessary to operate our system or to protect our rights or
-- | property&comma; &lpar;ii&rpar; upon legal demand &lpar;court orders&comma; warrants&comma; subpoenas&rpar;&comma; or
-- | &lpar;iii&rpar; where we receive information inadvertently which appears to
-- | pertain to the commission of a crime&period; This site is not considered a
-- | &quot;secure communications medium&quot; under the ECPA&period;
-- p
-- strong 15&period; Contact Us&period;
-- br
-- | If you have any questions regarding this Privacy Policy&comma; please
-- | contact the owner and operator of this website business&colon;
-- address
-- strong HabitRPG, Inc.
-- br
-- | 11870 Santa Monica Blvd., Suite 106-577
-- br
-- | Los Angeles, CA 90025
-- br
-- | Email&colon;&nbsp;
-- a(href='mailto:admin@habitica.com') admin@habitica.com
-+ | In the very unlikely event that this situation will change, all users
-+ | will get notified about it 5 months before the changes will take
-+ | effect.
+diff --git a/website/client/src/components/static/privacy.vue b/website/client/src/components/static/privacy.vue
+index 0a0c138f19..3ae6dad564 100644
+--- a/website/client/src/components/static/privacy.vue
++++ b/website/client/src/components/static/privacy.vue
+@@ -3,320 +3,22 @@
+ <div class="container-fluid">
+ <h1>Privacy Policy</h1>
+ <p class="pagemeta">
+- Last updated July 27, 2015
+- <br>
+- <small>(Corrected grammar errors and updated company name)</small>
+- <br>
+- <br>
++ This is a fork of the official Habitica source code and one of the main
++ reasons for the fork is its awful privacy policy.
+ </p>
+ <p>
+- <strong>PLEASE READ THIS PRIVACY POLICY CAREFULLY&period;</strong>
+- <br>By accessing or otherwise using habitica&period;com or any sub domains thereto &lpar;'the Sites'&rpar;&comma;
+- or using a habitica&period;com or Habitica application on a mobile device &lpar;'the Applications'&rpar;&comma;
+- you agree to be bound contractually by this Privacy Policy&period; Individually
+- or collectively&comma; the Applications and the Sites may be referred to as
+- the 'Services&period;'
++ To keep this very short, the only personal information that is collected
++ is the email address, the name of the user and data about the tasks.
+ </p>
+ <p>
+- To review material modifications and their effective dates scroll
+- to the bottom of the page&period;
++ All that information is never shared with any third parties and the site
++ itself doesn't use any analytics, advertising, social auth or any other
++ bullshit that nobody wants to have.
+ </p>
+ <p>
+- <strong>
+- 1&period; Privacy Statement&semi; Collection of Personal
+- Information&period;
+- </strong>
+- <br>1&period;1 HabitRPG, Inc. owns and operates this business&period; All
+- references to 'we'&comma; 'us'&comma; shall be construed to mean HabitRPG, Inc.&period;
++ In the very unlikely event that this situation will change, all users
++ will get notified about it 5 months before the changes will take effect.
+ </p>
+- <p>
+- 1&period;2 We understand that visitors to this website are concerned
+- about the privacy of information&period; The following describes our privacy
+- policy regarding information&comma; including personal information&comma; that we
+- collect through this website&period;
+- </p>
+- <p>
+- <strong>2&period; Modification of Privacy Policy&period;</strong>
+- <br>We reserve the right to modify this Privacy Policy at any time&comma;
+- and without prior notice&comma; by posting an amended Privacy Policy that is
+- always accessible by clicking on the 'Privacy Policy' link on this
+- site&apos;s home page&period; Your continued use of this site indicates your
+- acceptance of the amended Privacy Policy&period; You should check the Privacy
+- Policy through this link periodically for modifications by clicking on
+- the link provided near the top of the Privacy Policy for a listing of
+- material modifications and their effective dates&period; Regarding personal
+- information&comma; if any modifications are materially less restrictive on our
+- use or disclosure of the personal information previously disclosed by
+- you&comma; we will obtain your consent before implementing such revisions with
+- respect to such information&period;
+- </p>
+- <p>
+- <strong>3&period; Collection of Anonymous&comma; Passive Information&period;</strong>
+- <br>We reserve the right to monitor your use of the services&period; As you
+- navigate through the services&comma; certain anonymous information may be
+- passively collected &lpar;that is&comma; gathered without your actively providing
+- the information&rpar; using various technologies&comma; such as cookies&comma; Internet
+- tags or web beacons&comma; and navigational data collection &lpar;log files&comma; server
+- logs&comma; clickstream&rpar;&period; The following is a listing and a brief explanation
+- of passive information collection methodologies which we may use from
+- time to time to better understand how the Services are being used&period;
+- </p>
+- <p>
+- 3&period;1 A 'cookie' is a text file that this site sends to your
+- browser in the form of a text file The information generated by the
+- cookie about your use of this site &lpar;including your IP address&rpar; will be
+- transmitted to and stored&period; Most browsers automatically accept cookies&comma;
+- but they usually can be modified to decline cookies if you prefer&semi;
+- however&comma; certain features of this site might not work without cookies&period;
+- </p>
+- <p>
+- 3&period;2 'Session' cookies are temporary bits of information that are
+- used to improve navigation&comma; block visitors from providing information
+- where inappropriate &lpar;the Services 'remembers' previous entries of age or
+- country of origin that were outside the specified parameters and blocks
+- subsequent changes&rpar;&comma; and collect aggregate statistical information on
+- the Services&period; They are erased once you exit your Web browser or
+- otherwise turn off your computer&period;
+- </p>
+- <p>
+- 3&period;3 'Persistent' cookies are more permanent bits of information
+- that are placed on the hard drive of your computer and stay there unless
+- you delete the cookie&period; Persistent cookies store information on your
+- computer for a number of purposes&comma; such as retrieving certain
+- information you have previously provided&comma; helping to determine what
+- areas of the Services you may find most valuable&comma; and customizing the
+- Services based on your preferences on an ongoing basis&period; Persistent
+- cookies placed by this site in your computer do not hold personal
+- information&period;
+- </p>
+- <p>
+- 3&period;4 You can set your browser to accept all cookies&comma; to reject all
+- cookies&comma; or to notify you whenever a cookie is offered so that you can
+- decide each time whether to accept it&period; To learn more about cookies and
+- how to specify your preferences&comma; please search for 'cookie' in the
+- 'Help' portion of your browser&period;
+- </p>
+- <p>
+- 3&period;5 An Internet Protocol &lpar;IP&rpar; address is a number assigned to
+- your computer by your Internet service provider so you can access the
+- Internet and is generally considered to be non-personally identifiable
+- information&comma; because in most cases an IP address is dynamic &lpar;changing
+- each time you connect to the Internet&rpar;&comma; rather than static &lpar;unique to a
+- particular user&apos;s computer&rpar;&period; The IP address can be used to diagnose
+- problems with a server&comma; report aggregate information&comma; determine the
+- fastest route for your computer to use in connecting to a site&comma; and
+- administer and improve the Services&period;
+- </p>
+- <p>
+- 3&period;6 'Internet tags' &lpar;also known as Web Beacons&comma; single-pixel
+- GIFs&comma; clear GIFs&comma; invisible GIFs&comma; and 1-by-1 GIFs&rpar; are smaller than
+- cookies and tell the Web site server information such as the IP address
+- and browser type related to the visitor&apos;s computer&period; Tags may be placed
+- both on online advertisements that bring people to the Services and on
+- different pages of the Services&period; Such tags indicate how many times a
+- page is opened and which information is consulted&period;
+- </p>
+- <p>
+- 3&period;7 'Navigational data' &lpar;log files&comma; server logs&comma; and clickstream
+- data&rpar; are used for system management&comma; to improve the content of the
+- Services&comma; market research purposes&comma; and to communicate information to
+- visitors&period;
+- </p>
+- <p>
+- <strong>4&period; Use and Sharing of Anonymous&comma; Passive Information&period;</strong>
+- <br>The Services may make full use of passively collected anonymous
+- information&comma; including without limitation the right to use such
+- information to provide better service to Service users&comma; customize the
+- Services based on your preferences&comma; compile and analyze statistics and
+- trends&comma; and otherwise administer and improve the Services for your use&period; We
+- reserve the right to share this anonymous&comma; passive information in
+- aggregated form&period;
+- </p>
+- <p>
+- <strong>5&period; 3rd Party Behavioral Ads&semi; Google&apos;s AdSense Network&period;</strong>
+- <br>5&period;1 We reserve the right to use anonymous&comma; passive information
+- about your visits to this and other websites &lpar;not including your name&comma;
+- address&comma; email address or telephone number&rpar; for purposes of serving our
+- ads and third party ads that are targeted to your interests &lpar;'3rd Party
+- Behavioral Ads'&rpar;&period; We reserve the right to share anonymous&comma; passive
+- information collected on the services with third parties for purposes of
+- serving 3rd Party Behavioral Ads&period; These 3rd Party Behavioral Ads do not
+- identify you personally&period; Instead&comma; they associate your behavioral data on
+- visited sites with your browser&comma; so that the ads your computer sees on
+- this site are more likely to be relevant to your interests&period; 3rd Party
+- Behavioral Ads require that that you be served with a cookie containing
+- a tracking code&period; You may refuse the use of cookies by selecting the
+- appropriate settings on your browser&semi; however&comma; please note that if you
+- do this you may not be able to use the full functionality of this site&period;
+- </p>
+- <p>
+- 5&period;2 We reserve the right to participate in Google&apos;s AdSense
+- network for purposes of serving 3rd Party Behavioral Ads&period; Google uses
+- DoubleClick&apos;s DART cookie for serving 3rd Party Behavioral Ads over the
+- AdSense network&period; You may opt out of the use of the DART cookie&period; For
+- information regarding how to opt out&comma; go to
+- http&colon;&sol;&sol;www&period;google&period;com&sol;privacy&UnderBar;ads&period;html&period;
+- </p>
+- <p>
+- <strong>6&period; Use of 3rd Party Analytics&period;</strong>
+- <br>We reserve the right to use analytics services provided by
+- third parties&period; These services use 3rd party cookies to collect
+- anonymous&comma; passive information about your use of this site &lpar;see
+- explanation of cookies in Collection of Anonymous&comma; Passive Information
+- above&rpar;&period; We use this information for the purpose of evaluating your use
+- of the Services&comma; compiling reports on activity&comma; and providing other
+- services&period; These web analytics services may also transfer this
+- information to third parties where required to do so by law&comma; or where
+- such third parties process the information on the service&apos;s behalf&period;
+- </p>
+- <p>
+- <strong>7&period; Collection of Personal Information&semi; Categories&period;</strong>
+- <br>We will ask you for personal information when you sign up for any
+- specific benefit or purpose that requires registration&period; Personal
+- information that we collect may vary with each registration&comma; and it may
+- include one or more of the following categories&colon; name&comma; physical
+- address&comma; an email address&comma; phone number&comma; and credit card information
+- including credit card number&comma; expiration date&comma; and billing address&comma;
+- emergency contact information&comma; current medications&comma; allergies&comma; medical
+- insurance information&period;
+- </p>
+- <p>
+- <strong>
+- 8&period; Use And Sharing of Personal Information&colon; General
+- Policy And Exceptions&period;
+- </strong>
+- <br>Our general policy is that we will use your personal information&comma;
+- including combining your personal information with passive information
+- collected from this site&comma; only for&colon; the performance of the services or
+- transaction for which it was given&comma; our private&comma; internal reporting for
+- this site&comma; and security assessments for this site&comma; and we will not
+- share&comma; sell&comma; or rent your personal information to others&period; The only
+- exceptions to this general policy&colon; &lpar;i&rpar; are described in the subsections
+- below&comma; and &lpar;ii&rpar; if you explicitly approve through our site&period;
+- </p>
+- <p>
+- 8&period;1 Affiliates And Service Providers&period; We reserve the right to
+- provide such information to our affiliates or subsidiaries&comma; or trusted
+- service providers for the purpose of hosting our servers or processing
+- or archiving personal information for us&period; We require that these parties
+- agree to privacy and security safeguards for this information that are
+- consistent with this Privacy Policy&period;
+- </p>
+- <p>
+- 8&period;2 Acquisition&semi; Bankruptcy&period; In the event that we are acquired by
+- or merged with a third party entity&comma; we reserve the right to transfer
+- such information as part of such merger&comma; acquisition&comma; sale&comma; or other
+- change of control&period; In the unlikely event of our bankruptcy&comma; insolvency&comma;
+- reorganization&comma; receivership&comma; or assignment for the benefit of
+- creditors&comma; or the application of laws or equitable principles affecting
+- creditors&apos; rights generally&comma; we reserve the right to transfer such
+- information to protect our rights or as required by law&period;
+- </p>
+- <p>
+- 8&period;3 Enforcement&semi; Legal Process&period; We reserve the right to transfer
+- such information if we have a good faith belief that access&comma; use&comma;
+- preservation or disclosure of such information is reasonably necessary
+- &lpar;i&rpar; to satisfy any applicable law&comma; regulation&comma; legal process or
+- enforceable governmental request&comma; or &lpar;ii&rpar; to investigate or enforce
+- violations of our rights or the security of this site&period;
+- </p>
+- <p>
+- 8&period;4 Miscellaneous&period; We reserve the right to share personal
+- information with the following additional parties&colon; online organizers
+- using our tools and resellers of our products and services from whose
+- site the sale originated &lpar;even though the sale originates at site of the
+- reseller&comma; registration and collection of personal information occurs at
+- this site&rpar;&period;
+- </p>
+- <p>
+- <strong>
+- 9&period; Onward Transfer of Personal Information Outside Your
+- Country of Residence&period;
+- </strong>
+- <br>Any personal information which we may collect on this site will
+- be stored and processed in our servers located only in the United
+- States&period; By using this site&comma; if you reside outside the United States&comma; you
+- consent to the transfer of personal information outside your country of
+- residence to the United States&period;
+- </p>
+- <p>
+- <strong>10&period; Security of Personal Information&period;</strong>
+- <br>We follow reasonable and appropriate industry standards to
+- protect your personal information and data&period; Unfortunately&comma; no data
+- transmission over the Internet or method of data storage can be
+- guaranteed 100&percnt; secure&period; Therefore&comma; while we strive to protect your
+- personal information by following generally accepted industry standards&comma;
+- we cannot ensure or warrant the absolute security of any information you
+- transmit to us or archive at this site&period;
+- </p>
+- <p>
+- <strong>11&period; Changing And Updating Personal Information&period;</strong>
+- <br>Upon request&comma; we will permit you to request or make changes or
+- updates to your personal information for legitimate purposes&period; We request
+- identification prior to approving such requests&period; We reserve the right to
+- decline any requests that are unreasonably repetitive or systematic&comma;
+- require unreasonable time or effort of our technical or administrative
+- personnel&comma; or undermine the privacy rights of others&period; We reserve the
+- right to permit you to access your personal information in any account
+- you establish with this site for purposes of making your own changes or
+- updates&comma; and in such case&comma; instructions for making such changes or
+- updates will be provided where necessary&period;
+- </p>
+- <p>
+- <strong>12&period; Email From This Site&semi; Opt-Out Rights&period;</strong>
+- <br>If you supply us with your e-mail address you may receive
+- periodic messages from us with information specific to the Services and
+- required for the normal functioning of the Services as well as for new
+- products or services or upcoming events&period; If you prefer not to receive
+- periodic email messages&comma; you may opt-out by following the instructions
+- on the email&period;
+- </p>
+- <p>
+- <strong>13&period; Children&apos;s Online Policy&period;</strong>
+- <br>We are committed to preserving online privacy for all of our
+- website visitors&comma; including children&period; This site is a general audience
+- site&period; Consistent with the Children&apos;s Online Privacy Protection Act
+- &lpar;COPPA&rpar;&comma; we will not knowingly collect any information from&comma; or sell to&comma;
+- children under the age of 13&period; If you are a parent or guardian who has
+- discovered that your child under the age of 13 has submitted his or her
+- personally identifiable information without your permission or consent&comma;
+- we will remove the information from our active list&comma; at your request&period; To
+- request the removal of your child&apos;s information&comma; please email us at
+- <a
+- href="mailto:admin@habitica.com"
+- target="_blank"
+- >admin@habitica.com</a> and be sure to include in
+- your message the same login information that your child submitted&period;
+- </p>
+- <p>
+- <strong>
+- 14&period; Email And Other Messages Through This Site&semi; ECPA
+- Notice&period;
+- </strong>
+- <br>This site treats email messages and other electronic messages
+- that are sent through this site and not viewable by others as
+- confidential and private&comma; except as required by law&comma; including without
+- limitation&comma; the Electronic Communications Privacy Act of 1986&comma; 18 U&period;S&period;C&period;
+- Sections 2701-2711 &lpar;the 'ECPA'&rpar;&period; The ECPA permits this site&apos;s limited
+- ability to intercept and&sol;or disclose electronic messages&comma; for example
+- &lpar;i&rpar; as necessary to operate our system or to protect our rights or
+- property&comma; &lpar;ii&rpar; upon legal demand &lpar;court orders&comma; warrants&comma; subpoenas&rpar;&comma; or
+- &lpar;iii&rpar; where we receive information inadvertently which appears to
+- pertain to the commission of a crime&period; This site is not considered a
+- 'secure communications medium' under the ECPA&period;
+- </p>
+- <p>
+- <strong>15&period; Contact Us&period;</strong>
+- <br>If you have any questions regarding this Privacy Policy&comma; please
+- contact the owner and operator of this website business&colon;
+- </p>
+- <address>
+- <strong>HabitRPG, Inc.</strong>
+- <br>11870 Santa Monica Blvd., Suite 106-577
+- <br>Los Angeles, CA 90025
+- <br>Email&colon;&nbsp;
+- <a href="mailto:admin@habitica.com">admin@habitica.com</a>
+- </address>
+ </div>
+ <!-- eslint-enable max-len -->
</template>
diff --git a/pkgs/shabitica/patches/profile-photo-imageproxy.patch b/pkgs/shabitica/patches/profile-photo-imageproxy.patch
index a8263bb..86705a7 100644
--- a/pkgs/shabitica/patches/profile-photo-imageproxy.patch
+++ b/pkgs/shabitica/patches/profile-photo-imageproxy.patch
@@ -12,20 +12,23 @@ Date: Sun Aug 19 06:56:32 2018 +0200
Signed-off-by: aszlig <aszlig@nix.build>
Filename: profile-photo-imageproxy.patch
-diff --git a/website/client/components/userMenu/profile.vue b/website/client/components/userMenu/profile.vue
-index 81ebebcb8d..9007e4444a 100644
---- a/website/client/components/userMenu/profile.vue
-+++ b/website/client/components/userMenu/profile.vue
-@@ -59,7 +59,7 @@
- p(v-else) {{ $t('noDescription') }}
- .photo.profile-section
- h2 {{ $t('photo') }}
-- img.img-rendering-auto(v-if='user.profile.imageUrl', :src='user.profile.imageUrl')
-+ img.img-rendering-auto(v-if='photoUrl', :src='photoUrl')
- p(v-else) {{ $t('noPhoto') }}
-
- .col-12.col-md-4
-@@ -481,6 +481,17 @@ export default {
+diff --git a/website/client/src/components/userMenu/profile.vue b/website/client/src/components/userMenu/profile.vue
+index 11bab42665..0b17313ed3 100644
+--- a/website/client/src/components/userMenu/profile.vue
++++ b/website/client/src/components/userMenu/profile.vue
+@@ -180,9 +180,9 @@
+ <div class="photo profile-section">
+ <h2>{{ $t('photo') }}</h2>
+ <img
+- v-if="user.profile.imageUrl"
++ v-if="photoUrl"
+ class="img-rendering-auto"
+- :src="user.profile.imageUrl"
++ :src="photoUrl"
+ >
+ <p v-else>
+ {{ $t('noPhoto') }}
+@@ -736,6 +736,17 @@ export default {
hasClass () {
return this.$store.getters['members:hasClass'](this.userLoggedIn);
},
@@ -41,5 +44,5 @@ index 81ebebcb8d..9007e4444a 100644
+ return photourl;
+ },
},
- mounted () {
- this.loadUser();
+ watch: {
+ startingPage () {
diff --git a/pkgs/shabitica/patches/remove-community-guidelines.patch b/pkgs/shabitica/patches/remove-community-guidelines.patch
index 409de76..88bf9b3 100644
--- a/pkgs/shabitica/patches/remove-community-guidelines.patch
+++ b/pkgs/shabitica/patches/remove-community-guidelines.patch
@@ -10,79 +10,89 @@ Date: Fri Mar 30 20:29:49 2018 +0200
Signed-off-by: aszlig <aszlig@nix.build>
Filename: remove-community-guidelines.patch
-diff --git a/website/client/components/chat/chatCard.vue b/website/client/components/chat/chatCard.vue
-index b4daaf2ef7..8da4868b57 100644
---- a/website/client/components/chat/chatCard.vue
-+++ b/website/client/components/chat/chatCard.vue
-@@ -19,7 +19,7 @@ div
- .action.d-flex.align-items-center(v-if='!inbox', @click='copyAsTodo(msg)')
- .svg-icon(v-html="icons.copy")
- div {{$t('copyAsTodo')}}
-- .action.d-flex.align-items-center(v-if='(inbox || (user.flags.communityGuidelinesAccepted && msg.uuid !== "system")) && (!isMessageReported || user.contributor.admin)', @click='report(msg)')
-+ .action.d-flex.align-items-center(v-if='(inbox || (msg.uuid !== "system")) && (!isMessageReported || user.contributor.admin)', @click='report(msg)')
- .svg-icon(v-html="icons.report", v-once)
- div(v-once) {{$t('report')}}
- .action.d-flex.align-items-center(v-if='msg.uuid === user._id || inbox || user.contributor.admin', @click='remove()')
-diff --git a/website/client/components/groups/chat.vue b/website/client/components/groups/chat.vue
-index 424fc71e33..f6e76095ad 100644
---- a/website/client/components/groups/chat.vue
-+++ b/website/client/components/groups/chat.vue
-@@ -1,10 +1,10 @@
- <template lang="pug">
- .row.chat-row
- .col-12
-- h3.float-left.label(:class="{accepted: communityGuidelinesAccepted }") {{ label }}
-+ h3.float-left.label {{ label }}
- div.float-right(v-markdown='$t("markdownFormattingHelp")')
+diff --git a/website/client/src/components/chat/chatCard.vue b/website/client/src/components/chat/chatCard.vue
+index 9341d9002d..00f6cf3895 100644
+--- a/website/client/src/components/chat/chatCard.vue
++++ b/website/client/src/components/chat/chatCard.vue
+@@ -62,7 +62,7 @@
+ <div>{{ $t('copyAsTodo') }}</div>
+ </div>
+ <div
+- v-if="(inbox || (user.flags.communityGuidelinesAccepted && msg.uuid !== 'system'))
++ v-if="(inbox || msg.uuid !== 'system')
+ && (!isMessageReported || user.contributor.admin)"
+ class="action d-flex align-items-center"
+ @click="report(msg)"
+diff --git a/website/client/src/components/groups/chat.vue b/website/client/src/components/groups/chat.vue
+index 80d1a6a8f2..aef529e6a0 100644
+--- a/website/client/src/components/groups/chat.vue
++++ b/website/client/src/components/groups/chat.vue
+@@ -1,20 +1,14 @@
+ <template>
+ <div class="row chat-row">
+ <div class="col-12">
+- <h3
+- class="float-left label"
+- :class="{accepted: communityGuidelinesAccepted }"
+- >
++ <h3 class="float-left label">
+ {{ label }}
+ </h3>
+ <div
+ v-markdown="$t('markdownFormattingHelp')"
+ class="float-right"
+ ></div>
+- <div
+- v-if="communityGuidelinesAccepted"
+- class="row"
+- >
++ <div class="row">
+ <textarea
+ ref="user-entry"
+ v-model="newMessage"
+@@ -41,7 +35,6 @@
+ @select="selectedAutocomplete"
+ />
+ </div>
+- <community-guidelines />
+ <div class="row chat-actions">
+ <div class="col-6 chat-receive-actions">
+ <button
+@@ -62,7 +55,6 @@
+ <div class="col-6 chat-send-actions">
+ <button
+ class="btn btn-primary send-chat float-right"
+- :disabled="!communityGuidelinesAccepted"
+ @click="sendMessage()"
+ >
+ {{ $t('send') }}
+@@ -87,7 +79,6 @@
+ import debounce from 'lodash/debounce';
-- .row(v-if="communityGuidelinesAccepted")
-+ .row
- textarea(:placeholder='placeholder',
- v-model='newMessage',
- ref='user-entry',
-@@ -29,14 +29,12 @@
- :caretPosition = 'caretPosition',
- :chat='group.chat')
-
-- community-guidelines
--
- .row.chat-actions
- .col-6.chat-receive-actions
- button.btn.btn-secondary.float-left.fetch(v-once, @click='fetchRecentMessages()') {{ $t('fetchRecentMessages') }}
- button.btn.btn-secondary.float-left(v-once, @click='reverseChat()') {{ $t('reverseChat') }}
- .col-6.chat-send-actions
-- button.btn.btn-primary.send-chat.float-right(:disabled="!communityGuidelinesAccepted", @click='sendMessage()') {{ $t('send') }}
-+ button.btn.btn-primary.send-chat.float-right(@click='sendMessage()') {{ $t('send') }}
-
- slot(
- name="additionRow",
-@@ -51,7 +49,6 @@
- import debounce from 'lodash/debounce';
-
- import autocomplete from '../chat/autoComplete';
-- import communityGuidelines from './communityGuidelines';
- import chatMessage from '../chat/chatMessages';
- import { mapState } from 'client/libs/store';
- import markdownDirective from 'client/directives/markdown';
-@@ -63,7 +60,6 @@
- },
- components: {
- autocomplete,
-- communityGuidelines,
- chatMessage,
- },
- data () {
-@@ -87,9 +83,6 @@
- currentLength () {
- return this.newMessage.length;
- },
-- communityGuidelinesAccepted () {
-- return this.user.flags.communityGuidelinesAccepted;
-- },
+ import autocomplete from '../chat/autoComplete';
+-import communityGuidelines from './communityGuidelines';
+ import chatMessage from '../chat/chatMessages';
+ import { mapState } from '@/libs/store';
+ import markdownDirective from '@/directives/markdown';
+@@ -98,7 +89,6 @@ export default {
+ },
+ components: {
+ autocomplete,
+- communityGuidelines,
+ chatMessage,
+ },
+ props: ['label', 'group', 'placeholder'],
+@@ -123,9 +113,6 @@ export default {
+ currentLength () {
+ return this.newMessage.length;
},
- methods: {
- // https://medium.com/@_jh3y/how-to-where-s-the-caret-getting-the-xy-position-of-the-caret-a24ba372990a
-@@ -261,10 +254,6 @@
+- communityGuidelinesAccepted () {
+- return this.user.flags.communityGuidelinesAccepted;
+- },
+ },
+ methods: {
+ // https://medium.com/@_jh3y/how-to-where-s-the-caret-getting-the-xy-position-of-the-caret-a24ba372990a
+@@ -297,10 +284,6 @@ export default {
.chat-row {
position: relative;
@@ -93,76 +103,86 @@ index 424fc71e33..f6e76095ad 100644
.row {
margin-left: 0;
margin-right: 0;
-diff --git a/website/client/components/groups/group.vue b/website/client/components/groups/group.vue
-index 2695b6fac5..d4f43348e0 100644
---- a/website/client/components/groups/group.vue
-+++ b/website/client/components/groups/group.vue
-@@ -375,9 +375,6 @@ export default {
- },
+diff --git a/website/client/src/components/groups/group.vue b/website/client/src/components/groups/group.vue
+index a437e99878..14c152991e 100644
+--- a/website/client/src/components/groups/group.vue
++++ b/website/client/src/components/groups/group.vue
+@@ -498,9 +498,6 @@ export default {
+ next();
},
methods: {
- acceptCommunityGuidelines () {
-- this.$store.dispatch('user:set', {'flags.communityGuidelinesAccepted': true});
+- this.$store.dispatch('user:set', { 'flags.communityGuidelinesAccepted': true });
- },
async load () {
if (this.isParty) {
this.searchId = 'party';
-diff --git a/website/client/components/groups/tavern.vue b/website/client/components/groups/tavern.vue
-index 8915ef24d8..bbdfb4f9ac 100644
---- a/website/client/components/groups/tavern.vue
-+++ b/website/client/components/groups/tavern.vue
-@@ -10,7 +10,6 @@
- chat(
- :label="$t('tavernChat')",
- :group="group",
-- :placeholder="$t('tavernCommunityGuidelinesPlaceholder')",
- @fetchRecentMessages="fetchRecentMessages()"
- )
- .col-12.col-sm-4.sidebar
-@@ -101,8 +100,6 @@
-
- sidebar-section(:title="$t('helpfulLinks')")
- ul
-- li
-- router-link(to='/static/community-guidelines', v-once) {{ $t('communityGuidelinesLink') }}
- li
- router-link(to="/groups/guild/f2db2a7f-13c5-454d-b3ee-ea1f5089e601") {{ $t('lookingForGroup') }}
- li
-diff --git a/website/client/components/userMenu/profile.vue b/website/client/components/userMenu/profile.vue
-index dba76d8a65..81ebebcb8d 100644
---- a/website/client/components/userMenu/profile.vue
-+++ b/website/client/components/userMenu/profile.vue
-@@ -83,8 +83,6 @@
- .row(v-if='editing')
- h1 {{$t('editProfile')}}
- .col-12
-- .alert.alert-info.alert-sm(v-html='$t("communityGuidelinesWarning", managerEmail)')
--
- .form-group
- label {{ $t('displayName') }}
- input.form-control(type='text', :placeholder="$t('fullName')", v-model='editingProfile.name')
-diff --git a/website/client/router/index.js b/website/client/router/index.js
-index cd97a355fd..246d9214f0 100644
---- a/website/client/router/index.js
-+++ b/website/client/router/index.js
-@@ -10,7 +10,6 @@ const HomePage = () => import(/* webpackChunkName: "entry" */'client/components/
+diff --git a/website/client/src/components/groups/tavern.vue b/website/client/src/components/groups/tavern.vue
+index 68104e2951..6e7fd6e4d7 100644
+--- a/website/client/src/components/groups/tavern.vue
++++ b/website/client/src/components/groups/tavern.vue
+@@ -13,7 +13,6 @@
+ <chat
+ :label="$t('tavernChat')"
+ :group="group"
+- :placeholder="$t('tavernCommunityGuidelinesPlaceholder')"
+ @fetchRecentMessages="fetchRecentMessages()"
+ />
+ </div>
+@@ -306,14 +305,6 @@
+ </sidebar-section>
+ <sidebar-section :title="$t('helpfulLinks')">
+ <ul>
+- <li>
+- <router-link
+- v-once
+- to="/static/community-guidelines"
+- >
+- {{ $t('communityGuidelinesLink') }}
+- </router-link>
+- </li>
+ <li>
+ <router-link
+ to="/groups/guild/f2db2a7f-13c5-454d-b3ee-ea1f5089e601"
+diff --git a/website/client/src/components/userMenu/profile.vue b/website/client/src/components/userMenu/profile.vue
+index 97bf877a28..11bab42665 100644
+--- a/website/client/src/components/userMenu/profile.vue
++++ b/website/client/src/components/userMenu/profile.vue
+@@ -240,10 +240,6 @@
+ >
+ <h1>{{ $t('editProfile') }}</h1>
+ <div class="col-12">
+- <div
+- class="alert alert-info alert-sm"
+- v-html="$t('communityGuidelinesWarning', managerEmail)"
+- ></div>
+ <div class="form-group">
+ <label>{{ $t('displayName') }}</label>
+ <input
+diff --git a/website/client/src/router/index.js b/website/client/src/router/index.js
+index 087387b5d0..0067b19f6e 100644
+--- a/website/client/src/router/index.js
++++ b/website/client/src/router/index.js
+@@ -10,7 +10,6 @@ const HomePage = () => import(/* webpackChunkName: "entry" */'@/components/stati
- const AppPage = () => import(/* webpackChunkName: "static" */'client/components/static/app');
- const ClearBrowserDataPage = () => import(/* webpackChunkName: "static" */'client/components/static/clearBrowserData');
--const CommunityGuidelinesPage = () => import(/* webpackChunkName: "static" */'client/components/static/communityGuidelines');
- const FAQPage = () => import(/* webpackChunkName: "static" */'client/components/static/faq');
- const FeaturesPage = () => import(/* webpackChunkName: "static" */'client/components/static/features');
- const GroupPlansPage = () => import(/* webpackChunkName: "static" */'client/components/static/groupPlans');
-@@ -251,7 +250,6 @@ const router = new VueRouter({
- children: [
- { name: 'app', path: 'app', component: AppPage, 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: 'faq', path: 'faq', component: FAQPage, meta: {requiresLogin: false}},
- { name: 'features', path: 'features', component: FeaturesPage, meta: {requiresLogin: false}},
- { name: 'groupPlans', path: 'group-plans', component: GroupPlansPage, meta: {requiresLogin: false}},
+ const AppPage = () => import(/* webpackChunkName: "static" */'@/components/static/app');
+ const ClearBrowserDataPage = () => import(/* webpackChunkName: "static" */'@/components/static/clearBrowserData');
+-const CommunityGuidelinesPage = () => import(/* webpackChunkName: "static" */'@/components/static/communityGuidelines');
+ const FAQPage = () => import(/* webpackChunkName: "static" */'@/components/static/faq');
+ const FeaturesPage = () => import(/* webpackChunkName: "static" */'@/components/static/features');
+ const GroupPlansPage = () => import(/* webpackChunkName: "static" */'@/components/static/groupPlans');
+@@ -262,9 +261,6 @@ const router = new VueRouter({
+ {
+ name: 'clearBrowserData', path: 'clear-browser-data', component: ClearBrowserDataPage, meta: { requiresLogin: false },
+ },
+- {
+- name: 'communityGuidelines', path: 'community-guidelines', component: CommunityGuidelinesPage, meta: { requiresLogin: false },
+- },
+ {
+ name: 'faq', path: 'faq', component: FAQPage, meta: { requiresLogin: false },
+ },
diff --git a/website/server/libs/user/index.js b/website/server/libs/user/index.js
-index 5737a9ed6c..c4321265cc 100644
+index 54f0358b33..60a4a1a4d6 100644
--- a/website/server/libs/user/index.js
+++ b/website/server/libs/user/index.js
@@ -39,7 +39,6 @@ const updatablePaths = [
@@ -174,14 +194,14 @@ index 5737a9ed6c..c4321265cc 100644
'flags.cardReceived',
'flags.warnedLowHealth',
diff --git a/website/server/models/user/schema.js b/website/server/models/user/schema.js
-index 75efb7f937..4e8c3db98e 100644
+index 6fdea247aa..74ae75a45a 100644
--- a/website/server/models/user/schema.js
+++ b/website/server/models/user/schema.js
-@@ -227,7 +227,6 @@ let schema = new Schema({
+@@ -239,7 +239,6 @@ export default new Schema({
// Used to enable weekly recap emails as users login
lastWeeklyRecapDiscriminator: Boolean,
onboardingEmailsPhase: String, // Keep track of the latest onboarding email sent
-- communityGuidelinesAccepted: {$type: Boolean, default: false},
- cronCount: {$type: Number, default: 0},
- welcomed: {$type: Boolean, default: false},
- armoireEnabled: {$type: Boolean, default: true},
+- communityGuidelinesAccepted: { $type: Boolean, default: false },
+ cronCount: { $type: Number, default: 0 },
+ welcomed: { $type: Boolean, default: false },
+ armoireEnabled: { $type: Boolean, default: true },
diff --git a/pkgs/shabitica/patches/remove-contact-form.patch b/pkgs/shabitica/patches/remove-contact-form.patch
index a55c3a6..de32ac9 100644
--- a/pkgs/shabitica/patches/remove-contact-form.patch
+++ b/pkgs/shabitica/patches/remove-contact-form.patch
@@ -12,29 +12,33 @@ Date: Fri Mar 30 19:32:26 2018 +0200
Signed-off-by: aszlig <aszlig@nix.build>
Filename: remove-contact-form.patch
-diff --git a/website/client/components/groups/tavern.vue b/website/client/components/groups/tavern.vue
-index 86776fb7d9..8915ef24d8 100644
---- a/website/client/components/groups/tavern.vue
-+++ b/website/client/components/groups/tavern.vue
-@@ -101,8 +101,6 @@
-
- sidebar-section(:title="$t('helpfulLinks')")
- ul
-- li
-- a(href='', @click.prevent='modForm()') {{ $t('contactForm') }}
- li
- router-link(to='/static/community-guidelines', v-once) {{ $t('communityGuidelinesLink') }}
- li
-@@ -429,7 +427,6 @@
+diff --git a/website/client/src/components/groups/tavern.vue b/website/client/src/components/groups/tavern.vue
+index ab1b16df14..68104e2951 100644
+--- a/website/client/src/components/groups/tavern.vue
++++ b/website/client/src/components/groups/tavern.vue
+@@ -306,12 +306,6 @@
+ </sidebar-section>
+ <sidebar-section :title="$t('helpfulLinks')">
+ <ul>
+- <li>
+- <a
+- href
+- @click.prevent="modForm()"
+- >{{ $t('contactForm') }}</a>
+- </li>
+ <li>
+ <router-link
+ v-once
+@@ -768,7 +762,6 @@
<script>
- import { mapState } from 'client/libs/store';
--import { goToModForm } from 'client/libs/modform';
+ import { mapState } from '@/libs/store';
+-import { goToModForm } from '@/libs/modform';
- import { TAVERN_ID } from '../../../common/script/constants';
+ import { TAVERN_ID } from '@/../../common/script/constants';
import worldBossInfoModal from '../world-boss/worldBossInfoModal';
-@@ -511,9 +508,6 @@ export default {
- this.group = await this.$store.dispatch('guilds:getGroup', {groupId: TAVERN_ID});
+@@ -850,9 +843,6 @@ export default {
+ this.group = await this.$store.dispatch('guilds:getGroup', { groupId: TAVERN_ID });
},
methods: {
- modForm () {
@@ -43,27 +47,30 @@ index 86776fb7d9..8915ef24d8 100644
toggleSleep () {
this.$store.dispatch('user:sleep');
},
-diff --git a/website/client/components/header/menu.vue b/website/client/components/header/menu.vue
-index fcb6aba088..1347b766d1 100644
---- a/website/client/components/header/menu.vue
-+++ b/website/client/components/header/menu.vue
-@@ -69,7 +69,6 @@ div
- a.topbar-dropdown-item.dropdown-item(href="https://trello.com/c/odmhIqyW/440-read-first-table-of-contents", target='_blank') {{ $t('requestAF') }}
- a.topbar-dropdown-item.dropdown-item(href="http://habitica.fandom.com/wiki/Contributing_to_Habitica", target='_blank') {{ $t('contributing') }}
- a.topbar-dropdown-item.dropdown-item(href="http://habitica.fandom.com/wiki/Habitica_Wiki", target='_blank') {{ $t('wiki') }}
-- a.topbar-dropdown-item.dropdown-item(@click='modForm()') {{ $t('contactForm') }}
- .currency-tray.form-inline
- .item-with-icon(v-if="userHourglasses > 0")
- .top-menu-icon.svg-icon(v-html="icons.hourglasses", v-b-tooltip.hover.bottom="$t('mysticHourglassesTooltip')")
-@@ -392,7 +391,6 @@ div
+diff --git a/website/client/src/components/header/menu.vue b/website/client/src/components/header/menu.vue
+index e8dbc3a177..eee6ea8f5a 100644
+--- a/website/client/src/components/header/menu.vue
++++ b/website/client/src/components/header/menu.vue
+@@ -341,10 +341,6 @@
+ href="http://habitica.fandom.com/wiki/Habitica_Wiki"
+ target="_blank"
+ >{{ $t('wiki') }}</a>
+- <a
+- class="topbar-dropdown-item dropdown-item"
+- @click="modForm()"
+- >{{ $t('contactForm') }}</a>
+ </div>
+ </li>
+ </b-navbar-nav>
+@@ -709,7 +705,6 @@
<script>
- import { mapState, mapGetters } from 'client/libs/store';
--import { goToModForm } from 'client/libs/modform';
+ import { mapState, mapGetters } from '@/libs/store';
+-import { goToModForm } from '@/libs/modform';
- import gemIcon from 'assets/svg/gem.svg';
- import goldIcon from 'assets/svg/gold.svg';
-@@ -462,9 +460,6 @@ export default {
+ import gemIcon from '@/assets/svg/gem.svg';
+ import goldIcon from '@/assets/svg/gold.svg';
+@@ -779,9 +774,6 @@ export default {
});
},
methods: {
@@ -73,36 +80,46 @@ index fcb6aba088..1347b766d1 100644
toggleUserDropdown () {
this.isUserDropdownOpen = !this.isUserDropdownOpen;
},
-diff --git a/website/client/components/static/header.vue b/website/client/components/static/header.vue
-index 4f148b29c5..fefaa20896 100644
---- a/website/client/components/static/header.vue
-+++ b/website/client/components/static/header.vue
-@@ -16,8 +16,6 @@
- a.nav-link(href='http://blog.habitrpg.com/', target='_blank') {{ $t('tumblr') }}
- router-link.nav-item(tag='li', to='/static/press-kit')
- a.nav-link(v-once) {{ $t('presskit') }}
-- router-link.nav-item(tag='li', to='/static/contact')
-- a.nav-link(v-once) {{ $t('contactUs') }}
- ul.navbar-nav.mr-auto(v-else)
- router-link.nav-item(tag='li', to='/register')
- a.nav-link(v-once) {{ $t('getStarted') }}
-diff --git a/website/client/router/index.js b/website/client/router/index.js
-index 0a760836f0..cd97a355fd 100644
---- a/website/client/router/index.js
-+++ b/website/client/router/index.js
-@@ -11,7 +11,6 @@ const HomePage = () => import(/* webpackChunkName: "entry" */'client/components/
- const AppPage = () => import(/* webpackChunkName: "static" */'client/components/static/app');
- const ClearBrowserDataPage = () => import(/* webpackChunkName: "static" */'client/components/static/clearBrowserData');
- const CommunityGuidelinesPage = () => import(/* webpackChunkName: "static" */'client/components/static/communityGuidelines');
--const ContactPage = () => import(/* webpackChunkName: "static" */'client/components/static/contact');
- const FAQPage = () => import(/* webpackChunkName: "static" */'client/components/static/faq');
- const FeaturesPage = () => import(/* webpackChunkName: "static" */'client/components/static/features');
- const GroupPlansPage = () => import(/* webpackChunkName: "static" */'client/components/static/groupPlans');
-@@ -253,7 +252,6 @@ const router = new VueRouter({
- { name: 'app', path: 'app', component: AppPage, 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: 'features', path: 'features', component: FeaturesPage, meta: {requiresLogin: false}},
- { name: 'groupPlans', path: 'group-plans', component: GroupPlansPage, meta: {requiresLogin: false}},
+diff --git a/website/client/src/components/static/header.vue b/website/client/src/components/static/header.vue
+index 2010b8c96d..21046b842d 100644
+--- a/website/client/src/components/static/header.vue
++++ b/website/client/src/components/static/header.vue
+@@ -66,16 +66,6 @@
+ class="nav-link"
+ >{{ $t('presskit') }}</a>
+ </router-link>
+- <router-link
+- class="nav-item"
+- tag="li"
+- to="/static/contact"
+- >
+- <a
+- v-once
+- class="nav-link"
+- >{{ $t('contactUs') }}</a>
+- </router-link>
+ </ul>
+ <ul
+ v-else
+diff --git a/website/client/src/router/index.js b/website/client/src/router/index.js
+index 06e44b2707..087387b5d0 100644
+--- a/website/client/src/router/index.js
++++ b/website/client/src/router/index.js
+@@ -11,7 +11,6 @@ const HomePage = () => import(/* webpackChunkName: "entry" */'@/components/stati
+ const AppPage = () => import(/* webpackChunkName: "static" */'@/components/static/app');
+ 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');
+@@ -266,9 +265,6 @@ const router = new VueRouter({
+ {
+ 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 },
+ },
diff --git a/pkgs/shabitica/patches/remove-external-links.patch b/pkgs/shabitica/patches/remove-external-links.patch
index 2af9b4b..196360f 100644
--- a/pkgs/shabitica/patches/remove-external-links.patch
+++ b/pkgs/shabitica/patches/remove-external-links.patch
@@ -19,165 +19,226 @@ Date: Sat Mar 31 00:52:13 2018 +0200
Signed-off-by: aszlig <aszlig@nix.build>
Filename: remove-external-links.patch
-diff --git a/website/client/components/groups/tavern.vue b/website/client/components/groups/tavern.vue
-index bbdfb4f9ac..e37284fec1 100644
---- a/website/client/components/groups/tavern.vue
-+++ b/website/client/components/groups/tavern.vue
-@@ -101,23 +101,13 @@
- sidebar-section(:title="$t('helpfulLinks')")
- ul
- li
-- router-link(to="/groups/guild/f2db2a7f-13c5-454d-b3ee-ea1f5089e601") {{ $t('lookingForGroup') }}
-- li
-- router-link(to='/static/faq', v-once) {{ $t('faq') }}
-+ router-link(to='/static/faq', v-once) {{ $t('faq') }}
- li
- a(href='', v-html="$t('glossary')")
- li
- a(href='http://habitica.fandom.com/wiki/Habitica_Wiki' target='_blank', v-once) {{ $t('wiki') }}
- li
- a(href='https://oldgods.net/habitrpg/habitrpg_user_data_display.html', target='_blank', v-once) {{ $t('dataDisplayTool') }}
-- li
-- router-link(to="/groups/guild/a29da26b-37de-4a71-b0c6-48e72a900dac") {{ $t('reportProblem') }}
-- li
-- a(href='https://trello.com/c/odmhIqyW/440-read-first-table-of-contents', target='_blank', v-once) {{ $t('requestFeature') }}
-- li
-- a(href='', v-html="$t('communityForum')")
-- li
-- router-link(to="/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a") {{ $t('askQuestionGuild') }}
+diff --git a/website/client/src/components/groups/tavern.vue b/website/client/src/components/groups/tavern.vue
+index 6e7fd6e4d7..c5c7a23014 100644
+--- a/website/client/src/components/groups/tavern.vue
++++ b/website/client/src/components/groups/tavern.vue
+@@ -305,13 +305,6 @@
+ </sidebar-section>
+ <sidebar-section :title="$t('helpfulLinks')">
+ <ul>
+- <li>
+- <router-link
+- to="/groups/guild/f2db2a7f-13c5-454d-b3ee-ea1f5089e601"
+- >
+- {{ $t('lookingForGroup') }}
+- </router-link>
+- </li>
+ <li>
+ <router-link
+ v-once
+@@ -340,33 +333,6 @@
+ target="_blank"
+ >{{ $t('dataDisplayTool') }}</a>
+ </li>
+- <li>
+- <router-link
+- to="/groups/guild/a29da26b-37de-4a71-b0c6-48e72a900dac"
+- >
+- {{ $t('reportProblem') }}
+- </router-link>
+- </li>
+- <li>
+- <a
+- v-once
+- href="https://trello.com/c/odmhIqyW/440-read-first-table-of-contents"
+- target="_blank"
+- >{{ $t('requestFeature') }}</a>
+- </li>
+- <li>
+- <a
+- href
+- v-html="$t('communityForum')"
+- ></a>
+- </li>
+- <li>
+- <router-link
+- to="/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a"
+- >
+- {{ $t('askQuestionGuild') }}
+- </router-link>
+- </li>
+ </ul>
+ </sidebar-section>
+ <sidebar-section :title="$t('playerTiers')">
+diff --git a/website/client/src/components/hall/heroes.vue b/website/client/src/components/hall/heroes.vue
+index 0fe8dad9b7..0c6f133e48 100644
+--- a/website/client/src/components/hall/heroes.vue
++++ b/website/client/src/components/hall/heroes.vue
+@@ -59,15 +59,7 @@
+ type="number"
+ >
+ <small>
+- 1-7 for normal contributors, 8 for moderators, 9 for staff. This determines which items, pets, and mounts are available, and name-tag coloring. Tiers 8 and 9 are automatically given admin status.&nbsp; <!-- eslint-disable-line max-len -->
+- <a
+- target="_blank"
+- href="https://trello.com/c/wkFzONhE/277-contributor-gear"
+- >More details (1-7)</a>,&nbsp;
+- <a
+- target="_blank"
+- href="https://github.com/HabitRPG/habitica/issues/3801"
+- >more details (8-9)</a>
++ 1-7 for normal contributors, 8 for moderators, 9 for staff. This determines which items, pets, and mounts are available, and name-tag coloring. Tiers 8 and 9 are automatically given admin status.<!-- eslint-disable-line max-len -->
+ </small>
+ </div>
+ <div class="form-group">
+diff --git a/website/client/src/components/header/menu.vue b/website/client/src/components/header/menu.vue
+index eee6ea8f5a..f5a8e8504f 100644
+--- a/website/client/src/components/header/menu.vue
++++ b/website/client/src/components/header/menu.vue
+@@ -314,23 +314,6 @@
+ >
+ {{ $t('overview') }}
+ </router-link>
+- <router-link
+- class="topbar-dropdown-item dropdown-item"
+- to="/groups/guild/a29da26b-37de-4a71-b0c6-48e72a900dac"
+- >
+- {{ $t('reportBug') }}
+- </router-link>
+- <router-link
+- class="topbar-dropdown-item dropdown-item"
+- to="/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a"
+- >
+- {{ $t('askAQuestion') }}
+- </router-link>
+- <a
+- class="topbar-dropdown-item dropdown-item"
+- href="https://trello.com/c/odmhIqyW/440-read-first-table-of-contents"
+- target="_blank"
+- >{{ $t('requestAF') }}</a>
+ <a
+ class="topbar-dropdown-item dropdown-item"
+ href="http://habitica.fandom.com/wiki/Contributing_to_Habitica"
+diff --git a/website/client/src/components/settings/api.vue b/website/client/src/components/settings/api.vue
+index 6572961729..38c091e194 100644
+--- a/website/client/src/components/settings/api.vue
++++ b/website/client/src/components/settings/api.vue
+@@ -21,40 +21,6 @@
+ </div>
+ <p v-html="$t('APITokenWarning', { hrefTechAssistanceEmail })"></p>
+ </div>
+- <div class="section">
+- <h3>{{ $t('thirdPartyApps') }}</h3>
+- <ul>
+- <li>
+- <a
+- target="_blank"
+- href="https://www.beeminder.com/habitica"
+- >{{ $t('beeminder') }}</a>
+- <br>
+- {{ $t('beeminderDesc') }}
+- </li>
+- <li>
+- <a
+- target="_blank"
+- href="https://chrome.google.com/webstore/detail/habitrpg-chat-client/hidkdfgonpoaiannijofifhjidbnilbb"
+- >{{ $t('chromeChatExtension') }}</a>
+- <br>
+- {{ $t('chromeChatExtensionDesc') }}
+- </li>
+- <li>
+- <a
+- target="_blank"
+- :href="`https://oldgods.net/habitica/habitrpg_user_data_display.html?uuid=` + user._id"
+- >{{ $t('dataTool') }}</a>
+- <br>
+- {{ $t('dataToolDesc') }}
+- </li>
+- <li v-html="$t('otherExtensions')">
+- <br>
+- {{ $t('otherDesc') }}
+- </li>
+- </ul>
+- <hr>
+- </div>
+ </div>
+ <div class="col-6">
+ <h2>{{ $t('webhooks') }}</h2>
+diff --git a/website/client/src/components/static/faq.vue b/website/client/src/components/static/faq.vue
+index ad4ac66354..189dad3e9c 100644
+--- a/website/client/src/components/static/faq.vue
++++ b/website/client/src/components/static/faq.vue
+@@ -12,6 +12,7 @@
+ v-for="(heading, index) in headings"
+ :key="index"
+ class="faq-question"
++ v-if="heading != ''"
+ >
+ <h2
+ v-b-toggle="heading"
+@@ -91,8 +92,8 @@ export default {
+ 'character-classes',
+ 'blue-mana-bar',
+ 'monsters-quests',
+- 'gems',
+- 'bugs-features',
++ '', // No gems
++ '', // No bugs & feature requests
+ 'world-boss',
+ ];
- sidebar-section(:title="$t('playerTiers')")
- .row
-diff --git a/website/client/components/hall/heroes.vue b/website/client/components/hall/heroes.vue
-index fe13b65723..376b599e99 100644
---- a/website/client/components/hall/heroes.vue
-+++ b/website/client/components/hall/heroes.vue
-@@ -25,10 +25,6 @@
- label Contributor Tier
- input.form-control(type='number', v-model='hero.contributor.level')
- small 1-7 for normal contributors, 8 for moderators, 9 for staff. This determines which items, pets, and mounts are available, and name-tag coloring. Tiers 8 and 9 are automatically given admin status.
-- |&nbsp;
-- a(target='_blank', href='https://trello.com/c/wkFzONhE/277-contributor-gear') More details (1-7)
-- |,&nbsp;
-- a(target='_blank', href='https://github.com/HabitRPG/habitica/issues/3801') more details (8-9)
- .form-group
- label Contributions
- textarea.form-control(cols=5, v-model='hero.contributor.contributions')
-diff --git a/website/client/components/header/menu.vue b/website/client/components/header/menu.vue
-index 1347b766d1..1aa0759a54 100644
---- a/website/client/components/header/menu.vue
-+++ b/website/client/components/header/menu.vue
-@@ -64,9 +64,6 @@ div
- .topbar-dropdown
- router-link.topbar-dropdown-item.dropdown-item(:to="{name: 'faq'}") {{ $t('faq') }}
- router-link.topbar-dropdown-item.dropdown-item(:to="{name: 'overview'}") {{ $t('overview') }}
-- router-link.topbar-dropdown-item.dropdown-item(to="/groups/guild/a29da26b-37de-4a71-b0c6-48e72a900dac") {{ $t('reportBug') }}
-- router-link.topbar-dropdown-item.dropdown-item(to="/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a") {{ $t('askAQuestion') }}
-- a.topbar-dropdown-item.dropdown-item(href="https://trello.com/c/odmhIqyW/440-read-first-table-of-contents", target='_blank') {{ $t('requestAF') }}
- a.topbar-dropdown-item.dropdown-item(href="http://habitica.fandom.com/wiki/Contributing_to_Habitica", target='_blank') {{ $t('contributing') }}
- a.topbar-dropdown-item.dropdown-item(href="http://habitica.fandom.com/wiki/Habitica_Wiki", target='_blank') {{ $t('wiki') }}
- .currency-tray.form-inline
-diff --git a/website/client/components/settings/api.vue b/website/client/components/settings/api.vue
-index 291c3640f8..ccacd0f280 100644
---- a/website/client/components/settings/api.vue
-+++ b/website/client/components/settings/api.vue
-@@ -15,27 +15,6 @@
- pre.prettyprint.ml-4.mb-0(v-if="showApiToken") {{apiToken}}
- p(v-html='$t("APITokenWarning", { hrefTechAssistanceEmail })')
-
-- .section
-- h3 {{ $t('thirdPartyApps') }}
-- ul
-- li
-- a(target='_blank' href='https://www.beeminder.com/habitica') {{ $t('beeminder') }}
-- br
-- | {{ $t('beeminderDesc') }}
-- li
-- a(target='_blank' href='https://chrome.google.com/webstore/detail/habitrpg-chat-client/hidkdfgonpoaiannijofifhjidbnilbb') {{ $t('chromeChatExtension') }}
-- br
-- | {{ $t('chromeChatExtensionDesc') }}
-- li
-- a(target='_blank' :href='`https://oldgods.net/habitica/habitrpg_user_data_display.html?uuid=` + user._id') {{ $t('dataTool') }}
-- br
-- | {{ $t('dataToolDesc') }}
-- li(v-html="$t('otherExtensions')")
-- br
-- | {{ $t('otherDesc') }}
--
-- hr
--
- .col-6
- h2 {{ $t('webhooks') }}
- p(v-html="$t('webhooksInfo')")
-diff --git a/website/client/components/static/faq.vue b/website/client/components/static/faq.vue
-index 7a8ca6792d..5000dac10c 100644
---- a/website/client/components/static/faq.vue
-+++ b/website/client/components/static/faq.vue
-@@ -3,7 +3,7 @@
- .row
- .col-12.col-md-6.offset-md-3
- h1#faq-heading {{ $t('frequentlyAskedQuestions') }}
-- .faq-question(v-for='(heading, index) in headings', :key="index")
-+ .faq-question(v-for='(heading, index) in headings', :key="index", v-if="heading != ''")
- h2(role="tab", v-b-toggle="heading", @click="handleClick($event)", variant="info") {{ $t(`faqQuestion${index}`) }}
- b-collapse(:id="heading", :visible="isVisible(heading)", accordion="faq", role="tabpanel")
- div.card-body(v-markdown="$t('webFaqAnswer' + index, replacements)")
-@@ -62,8 +62,8 @@
- 'character-classes',
- 'blue-mana-bar',
- 'monsters-quests',
-- 'gems',
-- 'bugs-features',
-+ '', // No gems
-+ '', // No bugs & feature requests
- 'world-boss',
- ];
-
-@@ -76,11 +76,6 @@
- wikiTechAssistanceEmail: `mailto:${TECH_ASSISTANCE_EMAIL}`,
- },
- visible: hash && headings.includes(hash) ? hash : null,
-- // @TODO webFaqStillNeedHelp: {
-- // linkStart: '[',
-- // linkEnd: '](/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a)',
-- // },
-- // "webFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.fandom.com/wiki/FAQ), come ask in the <%= linkStart %>Habitica Help guild<%= linkEnd %>! We're happy to help."
- };
- },
- methods: {
-diff --git a/website/client/components/static/overview.vue b/website/client/components/static/overview.vue
-index 5866630186..7fd00b1ec7 100644
---- a/website/client/components/static/overview.vue
-+++ b/website/client/components/static/overview.vue
-@@ -8,7 +8,6 @@
- h3 {{ $t('step'+step) }}
- p(v-markdown="$t('webStep'+step+'Text', stepVars[step])")
- hr
-- p(v-markdown="$t('overviewQuestions', {faqUrl: '/static/faq/', helpGuildUrl: '/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a'})")
- </template>
-
- <style lang='scss'>
+@@ -105,11 +106,6 @@ export default {
+ wikiTechAssistanceEmail: `mailto:${TECH_ASSISTANCE_EMAIL}`,
+ },
+ visible: hash && headings.includes(hash) ? hash : null,
+- // @TODO webFaqStillNeedHelp: {
+- // linkStart: '[',
+- // linkEnd: '](/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a)',
+- // },
+- // "webFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.fandom.com/wiki/FAQ), come ask in the <%= linkStart %>Habitica Help guild<%= linkEnd %>! We're happy to help."
+ };
+ },
+ methods: {
+diff --git a/website/client/src/components/static/overview.vue b/website/client/src/components/static/overview.vue
+index 47a8a2ed83..9c73231bec 100644
+--- a/website/client/src/components/static/overview.vue
++++ b/website/client/src/components/static/overview.vue
+@@ -12,12 +12,6 @@
+ <p v-markdown="$t('webStep'+step+'Text', stepVars[step])"></p>
+ <hr>
+ </div>
+- <p
+- v-markdown="$t('overviewQuestions', {
+- faqUrl: '/static/faq/',
+- helpGuildUrl: '/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a'
+- })"
+- ></p>
+ </div>
+ </div>
+ </div>
diff --git a/website/server/controllers/api-v3/groups.js b/website/server/controllers/api-v3/groups.js
-index 6cbaf0f342..aa6b2f4f8a 100644
+index 5248d6e2bd..0a622ea7aa 100644
--- a/website/server/controllers/api-v3/groups.js
+++ b/website/server/controllers/api-v3/groups.js
-@@ -714,7 +714,6 @@ function _sendMessageToRemoved (group, removedUser, message, isInGroup) {
- {name: 'GROUP_NAME', content: group.name},
- {name: 'MESSAGE', content: message},
- {name: 'GUILDS_LINK', content: '/groups/discovery'},
-- {name: 'PARTY_WANTED_GUILD', content: '/groups/guild/f2db2a7f-13c5-454d-b3ee-ea1f5089e601'},
+@@ -796,7 +796,6 @@ function _sendMessageToRemoved (group, removedUser, message, isInGroup) {
+ { name: 'GROUP_NAME', content: group.name },
+ { name: 'MESSAGE', content: message },
+ { name: 'GUILDS_LINK', content: '/groups/discovery' },
+- { name: 'PARTY_WANTED_GUILD', content: '/groups/guild/f2db2a7f-13c5-454d-b3ee-ea1f5089e601' },
]);
}
}
diff --git a/website/server/models/user/schema.js b/website/server/models/user/schema.js
-index 4e8c3db98e..700c5e51bc 100644
+index 74ae75a45a..7ab6dde58e 100644
--- a/website/server/models/user/schema.js
+++ b/website/server/models/user/schema.js
-@@ -119,7 +119,6 @@ let schema = new Schema({
+@@ -123,8 +123,6 @@ export default new Schema({
},
contributor: {
-- // 1-9, see https://trello.com/c/wkFzONhE/277-contributor-gear https://github.com/HabitRPG/habitica/issues/3801
+- // 1-9, see https://trello.com/c/wkFzONhE/277-contributor-gear
+- // https://github.com/HabitRPG/habitica/issues/3801
level: {
$type: Number,
min: 0,
diff --git a/pkgs/shabitica/patches/remove-external-services.patch b/pkgs/shabitica/patches/remove-external-services.patch
index d3f5989..cc4271f 100644
--- a/pkgs/shabitica/patches/remove-external-services.patch
+++ b/pkgs/shabitica/patches/remove-external-services.patch
@@ -40,7 +40,7 @@ Date: Tue Mar 27 05:37:11 2018 +0200
Filename: remove-external-services.patch
diff --git a/config.json.example b/config.json.example
-index ae805b0561..e13607e0ee 100644
+index 32ba8cf1a1..ff01e0294e 100644
--- a/config.json.example
+++ b/config.json.example
@@ -1,12 +1,5 @@
@@ -56,7 +56,7 @@ index ae805b0561..e13607e0ee 100644
"BASE_URL": "http://localhost:3000",
"CRON_SAFE_MODE": "false",
"CRON_SEMI_SAFE_MODE": "false",
-@@ -19,58 +12,20 @@
+@@ -19,59 +12,21 @@
"EMAIL_SERVER_URL": "http://example.com",
"ENABLE_CONSOLE_LOGS_IN_PROD": "false",
"ENABLE_CONSOLE_LOGS_IN_TEST": "false",
@@ -74,6 +74,7 @@ index ae805b0561..e13607e0ee 100644
- "LOGGLY_TOKEN": "example-token",
"MAINTENANCE_MODE": "false",
"NODE_DB_URI": "mongodb://localhost/habitrpg",
+ "MONGODB_POOL_SIZE": "10",
"NODE_ENV": "development",
"PATH": "bin:node_modules/.bin:/usr/local/bin:/usr/bin:/bin",
- "PAYPAL_BILLING_PLANS_basic_12mo": "basic_12mo",
@@ -116,18 +117,18 @@ index ae805b0561..e13607e0ee 100644
"SKIP_SSL_CHECK_KEY": "key",
"ENABLE_STACKDRIVER_TRACING": "false"
diff --git a/gulp/taskHelper.js b/gulp/taskHelper.js
-index 270573ba70..75d2ae7596 100644
+index b22897747e..e7db03fa14 100644
--- a/gulp/taskHelper.js
+++ b/gulp/taskHelper.js
-@@ -2,7 +2,6 @@ import { exec } from 'child_process';
- import psTree from 'ps-tree';
- import nconf from 'nconf';
- import net from 'net';
--import { post } from 'superagent';
- import { sync as glob } from 'glob';
- import Mocha from 'mocha';
- import { resolve } from 'path';
-@@ -79,31 +78,6 @@ export function pipe (child) {
+@@ -2,7 +2,6 @@ import { exec } from 'child_process';
+ import psTree from 'ps-tree';
+ import nconf from 'nconf';
+ import net from 'net';
+-import { post } from 'superagent';
+ import { sync as glob } from 'glob';
+ import Mocha from 'mocha'; // eslint-disable-line import/no-extraneous-dependencies
+ import { resolve } from 'path';
+@@ -78,31 +77,6 @@ export function pipe (child) {
});
}
@@ -135,7 +136,7 @@ index 270573ba70..75d2ae7596 100644
- * Post request to notify configured slack channel
- */
-export function postToSlack (msg, config = {}) {
-- let slackUrl = nconf.get('SLACK_URL');
+- const slackUrl = nconf.get('SLACK_URL');
-
- if (!slackUrl) {
- console.error('No slack post url specified. Your message was:'); // eslint-disable-line no-console
@@ -151,7 +152,7 @@ index 270573ba70..75d2ae7596 100644
- text: msg,
- icon_emoji: `:${config.emoji || 'gulp'}:`, // eslint-disable-line camelcase
- })
-- .end((err) => {
+- .end(err => {
- if (err) console.error('Unable to post to slack', err); // eslint-disable-line no-console
- });
-}
@@ -160,18 +161,18 @@ index 270573ba70..75d2ae7596 100644
require('../test/helpers/globals.helper'); // eslint-disable-line global-require
diff --git a/test/api/unit/libs/cron.test.js b/test/api/unit/libs/cron.test.js
-index 61e7499393..2666f11cdf 100644
+index 5f6c6c95d8..22bb5b2064 100644
--- a/test/api/unit/libs/cron.test.js
+++ b/test/api/unit/libs/cron.test.js
@@ -6,7 +6,6 @@ import { recoverCron, cron } from '../../../../website/server/libs/cron';
import { model as User } from '../../../../website/server/models/user';
import * as Tasks from '../../../../website/server/models/task';
import common from '../../../../website/common';
--import analytics from '../../../../website/server/libs/analyticsService';
+-import * as analytics from '../../../../website/server/libs/analyticsService';
// const scoreTask = common.ops.scoreTask;
-@@ -30,47 +29,33 @@ describe('cron', () => {
+@@ -32,20 +31,17 @@ describe('cron', () => {
},
},
});
@@ -180,1214 +181,1270 @@ index 61e7499393..2666f11cdf 100644
});
afterEach(() => {
- if (clock !== null)
- clock.restore();
+ if (clock !== null) clock.restore();
- analytics.track.restore();
});
it('updates user.preferences.timezoneOffsetAtLastCron', () => {
- let timezoneOffsetFromUserPrefs = 1;
+ const timezoneOffsetFromUserPrefs = 1;
-- cron({user, tasksByType, daysMissed, analytics, timezoneOffsetFromUserPrefs});
-+ cron({user, tasksByType, daysMissed, timezoneOffsetFromUserPrefs});
+ cron({
+- user, tasksByType, daysMissed, analytics, timezoneOffsetFromUserPrefs,
++ user, tasksByType, daysMissed, timezoneOffsetFromUserPrefs,
+ });
expect(user.preferences.timezoneOffsetAtLastCron).to.equal(timezoneOffsetFromUserPrefs);
- });
-
+@@ -54,7 +50,7 @@ describe('cron', () => {
it('resets user.items.lastDrop.count', () => {
user.items.lastDrop.count = 4;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.items.lastDrop.count).to.equal(0);
});
-
+@@ -62,26 +58,11 @@ describe('cron', () => {
it('increments user cron count', () => {
- let cronCountBefore = user.flags.cronCount;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ const cronCountBefore = user.flags.cronCount;
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.flags.cronCount).to.be.greaterThan(cronCountBefore);
});
- it('calls analytics', () => {
-- cron({user, tasksByType, daysMissed, analytics});
+- cron({
+- user, tasksByType, daysMissed, analytics,
+- });
- expect(analytics.track.callCount).to.equal(1);
- });
-
- it('calls analytics when user is sleeping', () => {
- user.preferences.sleep = true;
-- cron({user, tasksByType, daysMissed, analytics});
+- cron({
+- user, tasksByType, daysMissed, analytics,
+- });
- expect(analytics.track.callCount).to.equal(1);
- });
-
describe('end of the month perks', () => {
beforeEach(() => {
user.purchased.plan.customerId = 'subscribedId';
-@@ -79,14 +64,14 @@ describe('cron', () => {
-
+@@ -91,7 +72,7 @@ describe('cron', () => {
it('resets plan.gemsBought on a new month', () => {
user.purchased.plan.gemsBought = 10;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.purchased.plan.gemsBought).to.equal(0);
});
-
- it('resets plan.gemsBought on a new month if user does not have purchased.plan.dateUpdated', () => {
+@@ -100,7 +81,7 @@ describe('cron', () => {
user.purchased.plan.gemsBought = 10;
user.purchased.plan.dateUpdated = undefined;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.purchased.plan.gemsBought).to.equal(0);
});
-
-@@ -95,32 +80,32 @@ describe('cron', () => {
- user.purchased.plan.dateUpdated = moment().startOf('month').toDate();
+@@ -111,7 +92,7 @@ describe('cron', () => {
user.purchased.plan.gemsBought = 10;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.purchased.plan.gemsBought).to.equal(10);
});
-
+@@ -119,7 +100,7 @@ describe('cron', () => {
it('resets plan.dateUpdated on a new month', () => {
- let currentMonth = moment().startOf('month');
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ const currentMonth = moment().startOf('month');
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(moment(user.purchased.plan.dateUpdated).startOf('month').isSame(currentMonth)).to.eql(true);
});
-
+@@ -127,7 +108,7 @@ describe('cron', () => {
it('increments plan.consecutive.count', () => {
user.purchased.plan.consecutive.count = 0;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.purchased.plan.consecutive.count).to.equal(1);
});
-
- it('increments plan.consecutive.count by more than 1 if user skipped months between logins', () => {
+@@ -136,7 +117,7 @@ describe('cron', () => {
user.purchased.plan.dateUpdated = moment().subtract(2, 'months').toDate();
user.purchased.plan.consecutive.count = 0;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.purchased.plan.consecutive.count).to.equal(2);
});
-
+@@ -144,7 +125,7 @@ describe('cron', () => {
it('decrements plan.consecutive.offset when offset is greater than 0', () => {
user.purchased.plan.consecutive.offset = 2;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.purchased.plan.consecutive.offset).to.equal(1);
});
-
-@@ -130,7 +115,7 @@ describe('cron', () => {
- user.purchased.plan.consecutive.count = 5;
+@@ -156,7 +137,7 @@ describe('cron', () => {
user.purchased.plan.consecutive.trinkets = 1;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.purchased.plan.consecutive.trinkets).to.equal(1);
- });
-@@ -138,13 +123,13 @@ describe('cron', () => {
- it('does not increment plan.consecutive.gemCapExtra when user has reached the gemCap limit', () => {
+@@ -166,7 +147,7 @@ describe('cron', () => {
user.purchased.plan.consecutive.gemCapExtra = 25;
user.purchased.plan.consecutive.count = 5;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.purchased.plan.consecutive.gemCapExtra).to.equal(25);
});
-
+@@ -174,7 +155,7 @@ describe('cron', () => {
it('does not reset plan stats if we are before the last day of the cancelled month', () => {
- user.purchased.plan.dateTerminated = moment(new Date()).add({days: 1});
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ user.purchased.plan.dateTerminated = moment(new Date()).add({ days: 1 });
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.purchased.plan.customerId).to.exist;
});
-
-@@ -154,7 +139,7 @@ describe('cron', () => {
- user.purchased.plan.consecutive.count = 5;
+@@ -186,7 +167,7 @@ describe('cron', () => {
user.purchased.plan.consecutive.offset = 1;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.purchased.plan.customerId).to.not.exist;
- expect(user.purchased.plan.consecutive.gemCapExtra).to.equal(0);
-@@ -188,7 +173,7 @@ describe('cron', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(1, 'months').add(2, 'days').toDate());
- // Add 1 month to simulate what happens a month after the subscription was created.
- // Add 2 days so that we're sure we're not affected by any start-of-month effects e.g., from time zone oddness.
-- cron({user: user1, tasksByType, daysMissed, analytics});
-+ cron({user: user1, tasksByType, daysMissed});
+@@ -225,7 +206,7 @@ describe('cron', () => {
+ // Add 2 days so that we're sure we're not affected by any start-of-month effects
+ // e.g., from time zone oddness.
+ cron({
+- user: user1, tasksByType, daysMissed, analytics,
++ user: user1, tasksByType, daysMissed,
+ });
expect(user1.purchased.plan.consecutive.count).to.equal(1);
expect(user1.purchased.plan.consecutive.offset).to.equal(0);
- expect(user1.purchased.plan.consecutive.trinkets).to.equal(0);
-@@ -199,7 +184,7 @@ describe('cron', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(2, 'months').add(2, 'days').toDate());
- // Add 1 month to simulate what happens a month after the subscription was created.
- // Add 2 days so that we're sure we're not affected by any start-of-month effects e.g., from time zone oddness.
-- cron({user: user1, tasksByType, daysMissed, analytics});
-+ cron({user: user1, tasksByType, daysMissed});
+@@ -241,7 +222,7 @@ describe('cron', () => {
+ // Add 2 days so that we're sure we're not affected by any start-of-month effects
+ // e.g., from time zone oddness.
+ cron({
+- user: user1, tasksByType, daysMissed, analytics,
++ user: user1, tasksByType, daysMissed,
+ });
expect(user1.purchased.plan.consecutive.count).to.equal(2);
expect(user1.purchased.plan.consecutive.offset).to.equal(0);
- expect(user1.purchased.plan.consecutive.trinkets).to.equal(0);
-@@ -210,7 +195,7 @@ describe('cron', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(3, 'months').add(2, 'days').toDate());
- // Add 1 month to simulate what happens a month after the subscription was created.
- // Add 2 days so that we're sure we're not affected by any start-of-month effects e.g., from time zone oddness.
-- cron({user: user1, tasksByType, daysMissed, analytics});
-+ cron({user: user1, tasksByType, daysMissed});
+@@ -257,7 +238,7 @@ describe('cron', () => {
+ // Add 2 days so that we're sure we're not affected by any start-of-month effects
+ // e.g., from time zone oddness.
+ cron({
+- user: user1, tasksByType, daysMissed, analytics,
++ user: user1, tasksByType, daysMissed,
+ });
expect(user1.purchased.plan.consecutive.count).to.equal(3);
expect(user1.purchased.plan.consecutive.offset).to.equal(0);
- expect(user1.purchased.plan.consecutive.trinkets).to.equal(1);
-@@ -221,7 +206,7 @@ describe('cron', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(4, 'months').add(2, 'days').toDate());
- // Add 1 month to simulate what happens a month after the subscription was created.
- // Add 2 days so that we're sure we're not affected by any start-of-month effects e.g., from time zone oddness.
-- cron({user: user1, tasksByType, daysMissed, analytics});
-+ cron({user: user1, tasksByType, daysMissed});
+@@ -273,7 +254,7 @@ describe('cron', () => {
+ // Add 2 days so that we're sure we're not affected by any start-of-month effects
+ // e.g., from time zone oddness.
+ cron({
+- user: user1, tasksByType, daysMissed, analytics,
++ user: user1, tasksByType, daysMissed,
+ });
expect(user1.purchased.plan.consecutive.count).to.equal(4);
expect(user1.purchased.plan.consecutive.offset).to.equal(0);
- expect(user1.purchased.plan.consecutive.trinkets).to.equal(1);
-@@ -230,7 +215,7 @@ describe('cron', () => {
-
- it('increments consecutive benefits correctly if user has been absent with continuous subscription', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(10, 'months').add(2, 'days').toDate());
-- cron({user: user1, tasksByType, daysMissed, analytics});
-+ cron({user: user1, tasksByType, daysMissed});
+@@ -286,7 +267,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user1, tasksByType, daysMissed, analytics,
++ user: user1, tasksByType, daysMissed,
+ });
expect(user1.purchased.plan.consecutive.count).to.equal(10);
expect(user1.purchased.plan.consecutive.offset).to.equal(0);
- expect(user1.purchased.plan.consecutive.trinkets).to.equal(3);
-@@ -261,7 +246,7 @@ describe('cron', () => {
-
- it('does not increment consecutive benefits in the first month of the first paid period that they already have benefits for', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(1, 'months').add(2, 'days').toDate());
-- cron({user: user3, tasksByType, daysMissed, analytics});
-+ cron({user: user3, tasksByType, daysMissed});
+@@ -321,7 +302,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user3, tasksByType, daysMissed, analytics,
++ user: user3, tasksByType, daysMissed,
+ });
expect(user3.purchased.plan.consecutive.count).to.equal(1);
expect(user3.purchased.plan.consecutive.offset).to.equal(2);
- expect(user3.purchased.plan.consecutive.trinkets).to.equal(1);
-@@ -270,7 +255,7 @@ describe('cron', () => {
-
- it('does not increment consecutive benefits in the middle of the period that they already have benefits for', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(2, 'months').add(2, 'days').toDate());
-- cron({user: user3, tasksByType, daysMissed, analytics});
-+ cron({user: user3, tasksByType, daysMissed});
+@@ -334,7 +315,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user3, tasksByType, daysMissed, analytics,
++ user: user3, tasksByType, daysMissed,
+ });
expect(user3.purchased.plan.consecutive.count).to.equal(2);
expect(user3.purchased.plan.consecutive.offset).to.equal(1);
- expect(user3.purchased.plan.consecutive.trinkets).to.equal(1);
-@@ -279,7 +264,7 @@ describe('cron', () => {
-
- it('does not increment consecutive benefits in the final month of the period that they already have benefits for', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(3, 'months').add(2, 'days').toDate());
-- cron({user: user3, tasksByType, daysMissed, analytics});
-+ cron({user: user3, tasksByType, daysMissed});
+@@ -347,7 +328,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user3, tasksByType, daysMissed, analytics,
++ user: user3, tasksByType, daysMissed,
+ });
expect(user3.purchased.plan.consecutive.count).to.equal(3);
expect(user3.purchased.plan.consecutive.offset).to.equal(0);
- expect(user3.purchased.plan.consecutive.trinkets).to.equal(1);
-@@ -288,7 +273,7 @@ describe('cron', () => {
-
- it('increments consecutive benefits the month after the second paid period has started', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(4, 'months').add(2, 'days').toDate());
-- cron({user: user3, tasksByType, daysMissed, analytics});
-+ cron({user: user3, tasksByType, daysMissed});
+@@ -360,7 +341,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user3, tasksByType, daysMissed, analytics,
++ user: user3, tasksByType, daysMissed,
+ });
expect(user3.purchased.plan.consecutive.count).to.equal(4);
expect(user3.purchased.plan.consecutive.offset).to.equal(2);
- expect(user3.purchased.plan.consecutive.trinkets).to.equal(2);
-@@ -297,7 +282,7 @@ describe('cron', () => {
-
- it('does not increment consecutive benefits in the second month of the second period that they already have benefits for', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(5, 'months').add(2, 'days').toDate());
-- cron({user: user3, tasksByType, daysMissed, analytics});
-+ cron({user: user3, tasksByType, daysMissed});
+@@ -373,7 +354,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user3, tasksByType, daysMissed, analytics,
++ user: user3, tasksByType, daysMissed,
+ });
expect(user3.purchased.plan.consecutive.count).to.equal(5);
expect(user3.purchased.plan.consecutive.offset).to.equal(1);
- expect(user3.purchased.plan.consecutive.trinkets).to.equal(2);
-@@ -306,7 +291,7 @@ describe('cron', () => {
-
- it('does not increment consecutive benefits in the final month of the second period that they already have benefits for', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(6, 'months').add(2, 'days').toDate());
-- cron({user: user3, tasksByType, daysMissed, analytics});
-+ cron({user: user3, tasksByType, daysMissed});
+@@ -386,7 +367,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user3, tasksByType, daysMissed, analytics,
++ user: user3, tasksByType, daysMissed,
+ });
expect(user3.purchased.plan.consecutive.count).to.equal(6);
expect(user3.purchased.plan.consecutive.offset).to.equal(0);
- expect(user3.purchased.plan.consecutive.trinkets).to.equal(2);
-@@ -315,7 +300,7 @@ describe('cron', () => {
-
- it('increments consecutive benefits the month after the third paid period has started', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(7, 'months').add(2, 'days').toDate());
-- cron({user: user3, tasksByType, daysMissed, analytics});
-+ cron({user: user3, tasksByType, daysMissed});
+@@ -399,7 +380,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user3, tasksByType, daysMissed, analytics,
++ user: user3, tasksByType, daysMissed,
+ });
expect(user3.purchased.plan.consecutive.count).to.equal(7);
expect(user3.purchased.plan.consecutive.offset).to.equal(2);
- expect(user3.purchased.plan.consecutive.trinkets).to.equal(3);
-@@ -324,7 +309,7 @@ describe('cron', () => {
-
- it('increments consecutive benefits correctly if user has been absent with continuous subscription', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(10, 'months').add(2, 'days').toDate());
-- cron({user: user3, tasksByType, daysMissed, analytics});
-+ cron({user: user3, tasksByType, daysMissed});
+@@ -412,7 +393,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user3, tasksByType, daysMissed, analytics,
++ user: user3, tasksByType, daysMissed,
+ });
expect(user3.purchased.plan.consecutive.count).to.equal(10);
expect(user3.purchased.plan.consecutive.offset).to.equal(2);
- expect(user3.purchased.plan.consecutive.trinkets).to.equal(4);
-@@ -355,7 +340,7 @@ describe('cron', () => {
-
- it('does not increment consecutive benefits in the first month of the first paid period that they already have benefits for', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(1, 'months').add(2, 'days').toDate());
-- cron({user: user6, tasksByType, daysMissed, analytics});
-+ cron({user: user6, tasksByType, daysMissed});
+@@ -447,7 +428,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user6, tasksByType, daysMissed, analytics,
++ user: user6, tasksByType, daysMissed,
+ });
expect(user6.purchased.plan.consecutive.count).to.equal(1);
expect(user6.purchased.plan.consecutive.offset).to.equal(5);
- expect(user6.purchased.plan.consecutive.trinkets).to.equal(2);
-@@ -364,7 +349,7 @@ describe('cron', () => {
-
- it('does not increment consecutive benefits in the final month of the period that they already have benefits for', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(6, 'months').add(2, 'days').toDate());
-- cron({user: user6, tasksByType, daysMissed, analytics});
-+ cron({user: user6, tasksByType, daysMissed});
+@@ -460,7 +441,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user6, tasksByType, daysMissed, analytics,
++ user: user6, tasksByType, daysMissed,
+ });
expect(user6.purchased.plan.consecutive.count).to.equal(6);
expect(user6.purchased.plan.consecutive.offset).to.equal(0);
- expect(user6.purchased.plan.consecutive.trinkets).to.equal(2);
-@@ -373,7 +358,7 @@ describe('cron', () => {
-
- it('increments consecutive benefits the month after the second paid period has started', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(7, 'months').add(2, 'days').toDate());
-- cron({user: user6, tasksByType, daysMissed, analytics});
-+ cron({user: user6, tasksByType, daysMissed});
+@@ -473,7 +454,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user6, tasksByType, daysMissed, analytics,
++ user: user6, tasksByType, daysMissed,
+ });
expect(user6.purchased.plan.consecutive.count).to.equal(7);
expect(user6.purchased.plan.consecutive.offset).to.equal(5);
- expect(user6.purchased.plan.consecutive.trinkets).to.equal(4);
-@@ -382,7 +367,7 @@ describe('cron', () => {
-
- it('increments consecutive benefits the month after the third paid period has started', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(13, 'months').add(2, 'days').toDate());
-- cron({user: user6, tasksByType, daysMissed, analytics});
-+ cron({user: user6, tasksByType, daysMissed});
+@@ -486,7 +467,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user6, tasksByType, daysMissed, analytics,
++ user: user6, tasksByType, daysMissed,
+ });
expect(user6.purchased.plan.consecutive.count).to.equal(13);
expect(user6.purchased.plan.consecutive.offset).to.equal(5);
- expect(user6.purchased.plan.consecutive.trinkets).to.equal(6);
-@@ -391,7 +376,7 @@ describe('cron', () => {
-
- it('increments consecutive benefits correctly if user has been absent with continuous subscription', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(19, 'months').add(2, 'days').toDate());
-- cron({user: user6, tasksByType, daysMissed, analytics});
-+ cron({user: user6, tasksByType, daysMissed});
+@@ -499,7 +480,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user6, tasksByType, daysMissed, analytics,
++ user: user6, tasksByType, daysMissed,
+ });
expect(user6.purchased.plan.consecutive.count).to.equal(19);
expect(user6.purchased.plan.consecutive.offset).to.equal(5);
- expect(user6.purchased.plan.consecutive.trinkets).to.equal(8);
-@@ -422,7 +407,7 @@ describe('cron', () => {
-
- it('does not increment consecutive benefits in the first month of the first paid period that they already have benefits for', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(1, 'months').add(2, 'days').toDate());
-- cron({user: user12, tasksByType, daysMissed, analytics});
-+ cron({user: user12, tasksByType, daysMissed});
+@@ -534,7 +515,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user12, tasksByType, daysMissed, analytics,
++ user: user12, tasksByType, daysMissed,
+ });
expect(user12.purchased.plan.consecutive.count).to.equal(1);
expect(user12.purchased.plan.consecutive.offset).to.equal(11);
- expect(user12.purchased.plan.consecutive.trinkets).to.equal(4);
-@@ -431,7 +416,7 @@ describe('cron', () => {
-
- it('does not increment consecutive benefits in the final month of the period that they already have benefits for', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(12, 'months').add(2, 'days').toDate());
-- cron({user: user12, tasksByType, daysMissed, analytics});
-+ cron({user: user12, tasksByType, daysMissed});
+@@ -547,7 +528,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user12, tasksByType, daysMissed, analytics,
++ user: user12, tasksByType, daysMissed,
+ });
expect(user12.purchased.plan.consecutive.count).to.equal(12);
expect(user12.purchased.plan.consecutive.offset).to.equal(0);
- expect(user12.purchased.plan.consecutive.trinkets).to.equal(4);
-@@ -440,7 +425,7 @@ describe('cron', () => {
-
- it('increments consecutive benefits the month after the second paid period has started', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(13, 'months').add(2, 'days').toDate());
-- cron({user: user12, tasksByType, daysMissed, analytics});
-+ cron({user: user12, tasksByType, daysMissed});
+@@ -560,7 +541,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user12, tasksByType, daysMissed, analytics,
++ user: user12, tasksByType, daysMissed,
+ });
expect(user12.purchased.plan.consecutive.count).to.equal(13);
expect(user12.purchased.plan.consecutive.offset).to.equal(11);
- expect(user12.purchased.plan.consecutive.trinkets).to.equal(8);
-@@ -449,7 +434,7 @@ describe('cron', () => {
-
- it('increments consecutive benefits the month after the third paid period has started', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(25, 'months').add(2, 'days').toDate());
-- cron({user: user12, tasksByType, daysMissed, analytics});
-+ cron({user: user12, tasksByType, daysMissed});
+@@ -573,7 +554,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user12, tasksByType, daysMissed, analytics,
++ user: user12, tasksByType, daysMissed,
+ });
expect(user12.purchased.plan.consecutive.count).to.equal(25);
expect(user12.purchased.plan.consecutive.offset).to.equal(11);
- expect(user12.purchased.plan.consecutive.trinkets).to.equal(12);
-@@ -458,7 +443,7 @@ describe('cron', () => {
-
- it('increments consecutive benefits correctly if user has been absent with continuous subscription', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(37, 'months').add(2, 'days').toDate());
-- cron({user: user12, tasksByType, daysMissed, analytics});
-+ cron({user: user12, tasksByType, daysMissed});
+@@ -586,7 +567,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user12, tasksByType, daysMissed, analytics,
++ user: user12, tasksByType, daysMissed,
+ });
expect(user12.purchased.plan.consecutive.count).to.equal(37);
expect(user12.purchased.plan.consecutive.offset).to.equal(11);
- expect(user12.purchased.plan.consecutive.trinkets).to.equal(16);
-@@ -490,7 +475,7 @@ describe('cron', () => {
-
- it('does not increment consecutive benefits in the first month of the gift subscription', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(1, 'months').add(2, 'days').toDate());
-- cron({user: user3g, tasksByType, daysMissed, analytics});
-+ cron({user: user3g, tasksByType, daysMissed});
+@@ -623,7 +604,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user3g, tasksByType, daysMissed, analytics,
++ user: user3g, tasksByType, daysMissed,
+ });
expect(user3g.purchased.plan.consecutive.count).to.equal(1);
expect(user3g.purchased.plan.consecutive.offset).to.equal(2);
- expect(user3g.purchased.plan.consecutive.trinkets).to.equal(1);
-@@ -499,7 +484,7 @@ describe('cron', () => {
-
- it('does not increment consecutive benefits in the second month of the gift subscription', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(2, 'months').add(2, 'days').toDate());
-- cron({user: user3g, tasksByType, daysMissed, analytics});
-+ cron({user: user3g, tasksByType, daysMissed});
+@@ -636,7 +617,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user3g, tasksByType, daysMissed, analytics,
++ user: user3g, tasksByType, daysMissed,
+ });
expect(user3g.purchased.plan.consecutive.count).to.equal(2);
expect(user3g.purchased.plan.consecutive.offset).to.equal(1);
- expect(user3g.purchased.plan.consecutive.trinkets).to.equal(1);
-@@ -508,7 +493,7 @@ describe('cron', () => {
-
- it('does not increment consecutive benefits in the third month of the gift subscription', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(3, 'months').add(2, 'days').toDate());
-- cron({user: user3g, tasksByType, daysMissed, analytics});
-+ cron({user: user3g, tasksByType, daysMissed});
+@@ -649,7 +630,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user3g, tasksByType, daysMissed, analytics,
++ user: user3g, tasksByType, daysMissed,
+ });
expect(user3g.purchased.plan.consecutive.count).to.equal(3);
expect(user3g.purchased.plan.consecutive.offset).to.equal(0);
- expect(user3g.purchased.plan.consecutive.trinkets).to.equal(1);
-@@ -517,7 +502,7 @@ describe('cron', () => {
-
- it('does not increment consecutive benefits in the month after the gift subscription has ended', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(4, 'months').add(2, 'days').toDate());
-- cron({user: user3g, tasksByType, daysMissed, analytics});
-+ cron({user: user3g, tasksByType, daysMissed});
- expect(user3g.purchased.plan.consecutive.count).to.equal(0); // subscription has been erased by now
- expect(user3g.purchased.plan.consecutive.offset).to.equal(0);
- expect(user3g.purchased.plan.consecutive.trinkets).to.equal(1);
-@@ -548,7 +533,7 @@ describe('cron', () => {
-
- it('increments consecutive benefits in the first month since the fix for #4819 goes live', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(1, 'months').add(2, 'days').toDate());
-- cron({user: user6x, tasksByType, daysMissed, analytics});
-+ cron({user: user6x, tasksByType, daysMissed});
+@@ -662,7 +643,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user3g, tasksByType, daysMissed, analytics,
++ user: user3g, tasksByType, daysMissed,
+ });
+ // subscription has been erased by now
+ expect(user3g.purchased.plan.consecutive.count).to.equal(0);
+@@ -699,7 +680,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user6x, tasksByType, daysMissed, analytics,
++ user: user6x, tasksByType, daysMissed,
+ });
expect(user6x.purchased.plan.consecutive.count).to.equal(9);
expect(user6x.purchased.plan.consecutive.offset).to.equal(5);
- expect(user6x.purchased.plan.consecutive.trinkets).to.equal(5);
-@@ -557,7 +542,7 @@ describe('cron', () => {
-
- it('does not increment consecutive benefits in the second month after the fix goes live', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(2, 'months').add(2, 'days').toDate());
-- cron({user: user6x, tasksByType, daysMissed, analytics});
-+ cron({user: user6x, tasksByType, daysMissed});
+@@ -712,7 +693,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user6x, tasksByType, daysMissed, analytics,
++ user: user6x, tasksByType, daysMissed,
+ });
expect(user6x.purchased.plan.consecutive.count).to.equal(10);
expect(user6x.purchased.plan.consecutive.offset).to.equal(4);
- expect(user6x.purchased.plan.consecutive.trinkets).to.equal(5);
-@@ -566,7 +551,7 @@ describe('cron', () => {
-
- it('does not increment consecutive benefits in the third month after the fix goes live', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(3, 'months').add(2, 'days').toDate());
-- cron({user: user6x, tasksByType, daysMissed, analytics});
-+ cron({user: user6x, tasksByType, daysMissed});
+@@ -725,7 +706,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user6x, tasksByType, daysMissed, analytics,
++ user: user6x, tasksByType, daysMissed,
+ });
expect(user6x.purchased.plan.consecutive.count).to.equal(11);
expect(user6x.purchased.plan.consecutive.offset).to.equal(3);
- expect(user6x.purchased.plan.consecutive.trinkets).to.equal(5);
-@@ -575,7 +560,7 @@ describe('cron', () => {
-
- it('increments consecutive benefits in the seventh month after the fix goes live', () => {
- clock = sinon.useFakeTimers(moment().zone(0).startOf('month').add(7, 'months').add(2, 'days').toDate());
-- cron({user: user6x, tasksByType, daysMissed, analytics});
-+ cron({user: user6x, tasksByType, daysMissed});
+@@ -738,7 +719,7 @@ describe('cron', () => {
+ .add(2, 'days')
+ .toDate());
+ cron({
+- user: user6x, tasksByType, daysMissed, analytics,
++ user: user6x, tasksByType, daysMissed,
+ });
expect(user6x.purchased.plan.consecutive.count).to.equal(15);
expect(user6x.purchased.plan.consecutive.offset).to.equal(5);
- expect(user6x.purchased.plan.consecutive.trinkets).to.equal(7);
-@@ -591,7 +576,7 @@ describe('cron', () => {
-
+@@ -756,7 +737,7 @@ describe('cron', () => {
it('resets plan.gemsBought on a new month', () => {
user.purchased.plan.gemsBought = 10;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.purchased.plan.gemsBought).to.equal(0);
});
-
-@@ -600,49 +585,49 @@ describe('cron', () => {
- user.purchased.plan.dateUpdated = moment().startOf('month').toDate();
+@@ -767,14 +748,14 @@ describe('cron', () => {
user.purchased.plan.gemsBought = 10;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.purchased.plan.gemsBought).to.equal(10);
});
it('does not reset plan.dateUpdated on a new month', () => {
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.purchased.plan.dateUpdated).to.be.empty;
});
-
+@@ -782,7 +763,7 @@ describe('cron', () => {
it('does not increment plan.consecutive.count', () => {
user.purchased.plan.consecutive.count = 0;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.purchased.plan.consecutive.count).to.equal(0);
});
-
+@@ -790,7 +771,7 @@ describe('cron', () => {
it('does not decrement plan.consecutive.offset when offset is greater than 0', () => {
user.purchased.plan.consecutive.offset = 1;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.purchased.plan.consecutive.offset).to.equal(1);
});
-
+@@ -798,7 +779,7 @@ describe('cron', () => {
it('does not increment plan.consecutive.trinkets when user has reached a month that is a multiple of 3', () => {
user.purchased.plan.consecutive.count = 5;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.purchased.plan.consecutive.trinkets).to.equal(0);
});
-
+@@ -806,7 +787,7 @@ describe('cron', () => {
it('does not increment plan.consecutive.gemCapExtra when user has reached a month that is a multiple of 3', () => {
user.purchased.plan.consecutive.count = 5;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.purchased.plan.consecutive.gemCapExtra).to.equal(0);
});
-
- it('does not increment plan.consecutive.gemCapExtra when user has reached the gemCap limit', () => {
+@@ -815,7 +796,7 @@ describe('cron', () => {
user.purchased.plan.consecutive.gemCapExtra = 25;
user.purchased.plan.consecutive.count = 5;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.purchased.plan.consecutive.gemCapExtra).to.equal(25);
});
-
+@@ -823,7 +804,7 @@ describe('cron', () => {
it('does nothing to plan stats if we are before the last day of the cancelled month', () => {
- user.purchased.plan.dateTerminated = moment(new Date()).add({days: 1});
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ user.purchased.plan.dateTerminated = moment(new Date()).add({ days: 1 });
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.purchased.plan.customerId).to.not.exist;
});
-
-@@ -652,7 +637,7 @@ describe('cron', () => {
- user.purchased.plan.consecutive.count = 5;
+@@ -835,7 +816,7 @@ describe('cron', () => {
user.purchased.plan.consecutive.offset = 1;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.purchased.plan.customerId).to.exist;
- expect(user.purchased.plan.consecutive.gemCapExtra).to.exist;
-@@ -675,14 +660,14 @@ describe('cron', () => {
-
+@@ -860,7 +841,7 @@ describe('cron', () => {
it('should make uncompleted todos redder', () => {
- let valueBefore = tasksByType.todos[0].value;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ const valueBefore = tasksByType.todos[0].value;
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.todos[0].value).to.be.lessThan(valueBefore);
});
-
- it('should add history of completed todos to user history', () => {
+@@ -869,7 +850,7 @@ describe('cron', () => {
tasksByType.todos[0].completed = true;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.history.todos).to.be.lengthOf(1);
- });
-@@ -711,7 +696,7 @@ describe('cron', () => {
- expect(tasksByType.todos).to.be.lengthOf(2);
+@@ -899,7 +880,7 @@ describe('cron', () => {
expect(user.tasksOrder.todos).to.be.lengthOf(3);
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
// user.tasksOrder.todos should be filtered while tasks by type remains unchanged
- expect(tasksByType.todos).to.be.lengthOf(2);
-@@ -740,7 +725,7 @@ describe('cron', () => {
- }).reverse();
- let original = user.tasksOrder.todos; // Preserve the original order
+@@ -928,7 +909,7 @@ describe('cron', () => {
+ const original = user.tasksOrder.todos; // Preserve the original order
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
let listsAreEqual = true;
- user.tasksOrder.todos.forEach((taskId, index) => {
-@@ -778,7 +763,7 @@ describe('cron', () => {
- tasksByType.dailys[0].frequency = 'daily';
+@@ -968,7 +949,7 @@ describe('cron', () => {
tasksByType.dailys[0].everyX = 5;
tasksByType.dailys[0].startDate = moment().add(1, 'days').toDate();
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.dailys[0].isDue).to.be.false;
});
-
-@@ -787,7 +772,7 @@ describe('cron', () => {
- tasksByType.dailys[0].frequency = 'daily';
+@@ -979,7 +960,7 @@ describe('cron', () => {
tasksByType.dailys[0].everyX = 5;
tasksByType.dailys[0].startDate = moment().toDate();
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.dailys[0].isDue).to.exist;
});
-
-@@ -795,32 +780,32 @@ describe('cron', () => {
- tasksByType.dailys[0].frequency = 'daily';
+@@ -989,14 +970,14 @@ describe('cron', () => {
tasksByType.dailys[0].everyX = 5;
tasksByType.dailys[0].startDate = moment().add(1, 'days').toDate();
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.dailys[0].nextDue.length).to.eql(6);
});
it('should add history', () => {
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.dailys[0].history).to.be.lengthOf(1);
});
-
+@@ -1004,7 +985,7 @@ describe('cron', () => {
it('should set tasks completed to false', () => {
tasksByType.dailys[0].completed = true;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.dailys[0].completed).to.be.false;
});
-
- it('should set tasks completed to false when user is sleeping', () => {
+@@ -1013,7 +994,7 @@ describe('cron', () => {
user.preferences.sleep = true;
tasksByType.dailys[0].completed = true;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.dailys[0].completed).to.be.false;
});
-
- it('should reset task checklist for completed dailys', () => {
- tasksByType.dailys[0].checklist.push({title: 'test', completed: false});
+@@ -1022,7 +1003,7 @@ describe('cron', () => {
+ tasksByType.dailys[0].checklist.push({ title: 'test', completed: false });
tasksByType.dailys[0].completed = true;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.dailys[0].checklist[0].completed).to.be.false;
});
-
-@@ -828,7 +813,7 @@ describe('cron', () => {
- user.preferences.sleep = true;
- tasksByType.dailys[0].checklist.push({title: 'test', completed: false});
+@@ -1032,7 +1013,7 @@ describe('cron', () => {
+ tasksByType.dailys[0].checklist.push({ title: 'test', completed: false });
tasksByType.dailys[0].completed = true;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.dailys[0].checklist[0].completed).to.be.false;
});
-
-@@ -836,7 +821,7 @@ describe('cron', () => {
- daysMissed = 10;
- tasksByType.dailys[0].checklist.push({title: 'test', completed: false});
- tasksByType.dailys[0].startDate = moment(new Date()).subtract({days: 1});
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+@@ -1042,7 +1023,7 @@ describe('cron', () => {
+ tasksByType.dailys[0].checklist.push({ title: 'test', completed: false });
+ tasksByType.dailys[0].startDate = moment(new Date()).subtract({ days: 1 });
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.dailys[0].checklist[0].completed).to.be.false;
});
-
-@@ -844,7 +829,7 @@ describe('cron', () => {
- daysMissed = 1;
- let hpBefore = user.stats.hp;
- tasksByType.dailys[0].startDate = moment(new Date()).subtract({days: 1});
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+@@ -1052,7 +1033,7 @@ describe('cron', () => {
+ const hpBefore = user.stats.hp;
+ tasksByType.dailys[0].startDate = moment(new Date()).subtract({ days: 1 });
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.stats.hp).to.be.lessThan(hpBefore);
});
-
-@@ -853,7 +838,7 @@ describe('cron', () => {
- daysMissed = 1;
- let hpBefore = user.stats.hp;
- tasksByType.dailys[0].startDate = moment(new Date()).subtract({days: 1});
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+@@ -1063,7 +1044,7 @@ describe('cron', () => {
+ const hpBefore = user.stats.hp;
+ tasksByType.dailys[0].startDate = moment(new Date()).subtract({ days: 1 });
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.stats.hp).to.equal(hpBefore);
});
+@@ -1077,7 +1058,7 @@ describe('cron', () => {
+ tasksByType.dailys[0].startDate = moment(new Date()).subtract({ days: 1 });
-@@ -865,7 +850,7 @@ describe('cron', () => {
- let hpBefore = user.stats.hp;
- tasksByType.dailys[0].startDate = moment(new Date()).subtract({days: 1});
-
-- cronOverride({user, tasksByType, daysMissed, analytics});
-+ cronOverride({user, tasksByType, daysMissed});
+ cronOverride({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.stats.hp).to.equal(hpBefore);
- });
-@@ -876,7 +861,7 @@ describe('cron', () => {
- user.stats.buffs.stealth = 2;
- tasksByType.dailys[0].startDate = moment(new Date()).subtract({days: 1});
+@@ -1090,7 +1071,7 @@ describe('cron', () => {
+ tasksByType.dailys[0].startDate = moment(new Date()).subtract({ days: 1 });
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.stats.hp).to.equal(hpBefore);
- });
-@@ -885,13 +870,13 @@ describe('cron', () => {
- daysMissed = 1;
+@@ -1101,7 +1082,7 @@ describe('cron', () => {
let hpBefore = user.stats.hp;
- tasksByType.dailys[0].startDate = moment(new Date()).subtract({days: 1});
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
- let hpDifferenceOfFullyIncompleteDaily = hpBefore - user.stats.hp;
-
- hpBefore = user.stats.hp;
- tasksByType.dailys[0].checklist.push({title: 'test', completed: true});
- tasksByType.dailys[0].checklist.push({title: 'test2', completed: false});
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
- let hpDifferenceOfPartiallyIncompleteDaily = hpBefore - user.stats.hp;
-
- expect(hpDifferenceOfPartiallyIncompleteDaily).to.be.lessThan(hpDifferenceOfFullyIncompleteDaily);
-@@ -901,7 +886,7 @@ describe('cron', () => {
- daysMissed = 1;
- tasksByType.dailys[0].startDate = moment(new Date()).subtract({days: 1});
-
-- let progress = cron({user, tasksByType, daysMissed, analytics});
-+ let progress = cron({user, tasksByType, daysMissed});
+ tasksByType.dailys[0].startDate = moment(new Date()).subtract({ days: 1 });
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
+ const hpDifferenceOfFullyIncompleteDaily = hpBefore - user.stats.hp;
+
+@@ -1109,7 +1090,7 @@ describe('cron', () => {
+ tasksByType.dailys[0].checklist.push({ title: 'test', completed: true });
+ tasksByType.dailys[0].checklist.push({ title: 'test2', completed: false });
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
+ const hpDifferenceOfPartiallyIncompleteDaily = hpBefore - user.stats.hp;
+
+@@ -1122,7 +1103,7 @@ describe('cron', () => {
+ tasksByType.dailys[0].startDate = moment(new Date()).subtract({ days: 1 });
+
+ const progress = cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(progress.down).to.equal(-1);
- });
-@@ -911,7 +896,7 @@ describe('cron', () => {
- daysMissed = 1;
- tasksByType.dailys[0].startDate = moment(new Date()).subtract({days: 1});
+@@ -1134,7 +1115,7 @@ describe('cron', () => {
+ tasksByType.dailys[0].startDate = moment(new Date()).subtract({ days: 1 });
-- let progress = cron({user, tasksByType, daysMissed, analytics});
-+ let progress = cron({user, tasksByType, daysMissed});
+ const progress = cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(progress.down).to.equal(0);
- });
-@@ -930,7 +915,7 @@ describe('cron', () => {
- tasksByType.dailys[1].everyX = 2;
+@@ -1155,7 +1136,7 @@ describe('cron', () => {
tasksByType.dailys[1].frequency = 'daily';
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.stats.hp).to.equal(48);
- });
-@@ -952,7 +937,7 @@ describe('cron', () => {
- tasksByType.habits[0].value = 1;
+@@ -1179,7 +1160,7 @@ describe('cron', () => {
tasksByType.habits[0].down = false;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.habits[0].value).to.be.lessThan(1);
- });
-@@ -961,7 +946,7 @@ describe('cron', () => {
- tasksByType.habits[0].value = 1;
+@@ -1190,7 +1171,7 @@ describe('cron', () => {
tasksByType.habits[0].up = false;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.habits[0].value).to.be.lessThan(1);
- });
-@@ -971,7 +956,7 @@ describe('cron', () => {
- tasksByType.habits[0].up = true;
+@@ -1202,7 +1183,7 @@ describe('cron', () => {
tasksByType.habits[0].down = true;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.habits[0].value).to.equal(1);
- });
-@@ -988,7 +973,7 @@ describe('cron', () => {
- tasksByType.habits[0].counterUp = 1;
+@@ -1221,7 +1202,7 @@ describe('cron', () => {
tasksByType.habits[0].counterDown = 1;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.habits[0].counterUp).to.equal(0);
- expect(tasksByType.habits[0].counterDown).to.equal(0);
-@@ -999,7 +984,7 @@ describe('cron', () => {
- tasksByType.habits[0].counterUp = 1;
+@@ -1234,7 +1215,7 @@ describe('cron', () => {
tasksByType.habits[0].counterDown = 1;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.habits[0].counterUp).to.equal(0);
- expect(tasksByType.habits[0].counterDown).to.equal(0);
-@@ -1011,14 +996,14 @@ describe('cron', () => {
- tasksByType.habits[0].counterDown = 1;
+@@ -1248,7 +1229,7 @@ describe('cron', () => {
// should not reset
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.habits[0].counterUp).to.equal(1);
- expect(tasksByType.habits[0].counterDown).to.equal(1);
-
+@@ -1257,7 +1238,7 @@ describe('cron', () => {
// should reset
daysMissed = 8;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.habits[0].counterUp).to.equal(0);
- expect(tasksByType.habits[0].counterDown).to.equal(0);
-@@ -1040,7 +1025,7 @@ describe('cron', () => {
- daysMissed = 1;
+@@ -1281,7 +1262,7 @@ describe('cron', () => {
// should not reset
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.habits[0].counterUp).to.equal(1);
- expect(tasksByType.habits[0].counterDown).to.equal(1);
-@@ -1052,7 +1037,7 @@ describe('cron', () => {
- clock = sinon.useFakeTimers(monday);
+@@ -1295,7 +1276,7 @@ describe('cron', () => {
// should reset after user CDS
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.habits[0].counterUp).to.equal(0);
- expect(tasksByType.habits[0].counterDown).to.equal(0);
-@@ -1074,7 +1059,7 @@ describe('cron', () => {
- daysMissed = 1;
+@@ -1319,7 +1300,7 @@ describe('cron', () => {
// should not reset
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.habits[0].counterUp).to.equal(1);
- expect(tasksByType.habits[0].counterDown).to.equal(1);
-@@ -1082,7 +1067,7 @@ describe('cron', () => {
- // User missed one cron, which will subtract User clock back to Monday 1am UTC + 2
+@@ -1329,7 +1310,7 @@ describe('cron', () => {
// should reset
daysMissed = 2;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.habits[0].counterUp).to.equal(0);
- expect(tasksByType.habits[0].counterDown).to.equal(0);
-@@ -1104,7 +1089,7 @@ describe('cron', () => {
- daysMissed = 1;
+@@ -1353,7 +1334,7 @@ describe('cron', () => {
// should reset
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.habits[0].counterUp).to.equal(0);
- expect(tasksByType.habits[0].counterDown).to.equal(0);
-@@ -1126,7 +1111,7 @@ describe('cron', () => {
- daysMissed = 1;
+@@ -1377,7 +1358,7 @@ describe('cron', () => {
// should not reset
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.habits[0].counterUp).to.equal(1);
- expect(tasksByType.habits[0].counterDown).to.equal(1);
-@@ -1138,14 +1123,14 @@ describe('cron', () => {
- tasksByType.habits[0].counterDown = 1;
+@@ -1391,7 +1372,7 @@ describe('cron', () => {
// should not reset
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.habits[0].counterUp).to.equal(1);
- expect(tasksByType.habits[0].counterDown).to.equal(1);
-
+@@ -1400,7 +1381,7 @@ describe('cron', () => {
// should reset
daysMissed = 32;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.habits[0].counterUp).to.equal(0);
- expect(tasksByType.habits[0].counterDown).to.equal(0);
-@@ -1168,7 +1153,7 @@ describe('cron', () => {
- daysMissed = 1;
+@@ -1425,7 +1406,7 @@ describe('cron', () => {
// should reset
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.habits[0].counterUp).to.equal(0);
- expect(tasksByType.habits[0].counterDown).to.equal(0);
-@@ -1190,7 +1175,7 @@ describe('cron', () => {
- daysMissed = 1;
+@@ -1449,7 +1430,7 @@ describe('cron', () => {
// should not reset
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.habits[0].counterUp).to.equal(1);
- expect(tasksByType.habits[0].counterDown).to.equal(1);
-@@ -1198,7 +1183,7 @@ describe('cron', () => {
- // User missed one day, which will subtract User clock back to 5/1/17 2am UTC + 3
+@@ -1459,7 +1440,7 @@ describe('cron', () => {
// should reset
daysMissed = 2;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(tasksByType.habits[0].counterUp).to.equal(0);
- expect(tasksByType.habits[0].counterDown).to.equal(0);
-@@ -1229,7 +1214,7 @@ describe('cron', () => {
- it('stores a new entry in user.history.exp', () => {
+@@ -1492,7 +1473,7 @@ describe('cron', () => {
user.stats.lvl = 2;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.history.exp).to.have.lengthOf(1);
- expect(user.history.exp[0].value).to.equal(25);
-@@ -1240,7 +1225,7 @@ describe('cron', () => {
- tasksByType.dailys[0].completed = true;
- tasksByType.dailys[0].startDate = moment(new Date()).subtract({days: 1});
+@@ -1505,7 +1486,7 @@ describe('cron', () => {
+ tasksByType.dailys[0].startDate = moment(new Date()).subtract({ days: 1 });
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.achievements.perfect).to.equal(1);
- });
-@@ -1250,7 +1235,7 @@ describe('cron', () => {
- tasksByType.dailys[0].completed = true;
- tasksByType.dailys[0].startDate = moment(new Date()).add({days: 1});
+@@ -1517,7 +1498,7 @@ describe('cron', () => {
+ tasksByType.dailys[0].startDate = moment(new Date()).add({ days: 1 });
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.achievements.perfect).to.equal(0);
- });
-@@ -1262,7 +1247,7 @@ describe('cron', () => {
-
- let previousBuffs = user.stats.buffs.toObject();
+@@ -1531,7 +1512,7 @@ describe('cron', () => {
+ const previousBuffs = user.stats.buffs.toObject();
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.stats.buffs.str).to.be.greaterThan(previousBuffs.str);
- expect(user.stats.buffs.int).to.be.greaterThan(previousBuffs.int);
-@@ -1278,7 +1263,7 @@ describe('cron', () => {
-
- let previousBuffs = user.stats.buffs.toObject();
+@@ -1549,7 +1530,7 @@ describe('cron', () => {
+ const previousBuffs = user.stats.buffs.toObject();
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.stats.buffs.str).to.be.greaterThan(previousBuffs.str);
- expect(user.stats.buffs.int).to.be.greaterThan(previousBuffs.int);
-@@ -1300,7 +1285,7 @@ describe('cron', () => {
- streaks: true,
+@@ -1573,7 +1554,7 @@ describe('cron', () => {
};
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.stats.buffs.str).to.equal(0);
- expect(user.stats.buffs.int).to.equal(0);
-@@ -1325,7 +1310,7 @@ describe('cron', () => {
- streaks: true,
+@@ -1600,7 +1581,7 @@ describe('cron', () => {
};
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.stats.buffs.str).to.equal(0);
- expect(user.stats.buffs.int).to.equal(0);
-@@ -1349,7 +1334,7 @@ describe('cron', () => {
- streaks: true,
+@@ -1626,7 +1607,7 @@ describe('cron', () => {
};
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.stats.buffs.str).to.equal(0);
- expect(user.stats.buffs.int).to.equal(0);
-@@ -1374,7 +1359,7 @@ describe('cron', () => {
- streaks: true,
+@@ -1653,7 +1634,7 @@ describe('cron', () => {
};
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.stats.buffs.str).to.equal(0);
- expect(user.stats.buffs.int).to.equal(0);
-@@ -1393,7 +1378,7 @@ describe('cron', () => {
+@@ -1674,7 +1655,7 @@ describe('cron', () => {
+ const previousBuffs = user.stats.buffs.toObject();
- let previousBuffs = user.stats.buffs.toObject();
-
-- cronOverride({user, tasksByType, daysMissed, analytics});
-+ cronOverride({user, tasksByType, daysMissed});
+ cronOverride({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.stats.buffs.str).to.be.greaterThan(previousBuffs.str);
- expect(user.stats.buffs.int).to.be.greaterThan(previousBuffs.int);
-@@ -1411,7 +1396,7 @@ describe('cron', () => {
+@@ -1694,7 +1675,7 @@ describe('cron', () => {
+ const previousBuffs = user.stats.buffs.toObject();
- let previousBuffs = user.stats.buffs.toObject();
-
-- cronOverride({user, tasksByType, daysMissed, analytics});
-+ cronOverride({user, tasksByType, daysMissed});
+ cronOverride({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.stats.buffs.str).to.be.greaterThan(previousBuffs.str);
- expect(user.stats.buffs.int).to.be.greaterThan(previousBuffs.int);
-@@ -1428,7 +1413,7 @@ describe('cron', () => {
- let mpBefore = user.stats.mp;
+@@ -1713,7 +1694,7 @@ describe('cron', () => {
tasksByType.dailys[0].completed = true;
- stubbedStatsComputed.returns(Object.assign(statsComputedRes, {maxMP: 100}));
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ stubbedStatsComputed.returns(Object.assign(statsComputedRes, { maxMP: 100 }));
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.stats.mp).to.be.greaterThan(mpBefore);
- common.statsComputed.restore();
-@@ -1442,7 +1427,7 @@ describe('cron', () => {
- let mpBefore = user.stats.mp;
+@@ -1729,7 +1710,7 @@ describe('cron', () => {
tasksByType.dailys[0].completed = true;
- stubbedStatsComputed.returns(Object.assign(statsComputedRes, {maxMP: 100}));
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ stubbedStatsComputed.returns(Object.assign(statsComputedRes, { maxMP: 100 }));
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.stats.mp).to.equal(mpBefore);
- common.statsComputed.restore();
-@@ -1453,7 +1438,7 @@ describe('cron', () => {
- const stubbedStatsComputed = sinon.stub(common, 'statsComputed');
+@@ -1742,7 +1723,7 @@ describe('cron', () => {
user.stats.mp = 120;
- stubbedStatsComputed.returns(Object.assign(statsComputedRes, {maxMP: 100}));
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ stubbedStatsComputed.returns(Object.assign(statsComputedRes, { maxMP: 100 }));
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.stats.mp).to.equal(common.statsComputed(user).maxMP);
- common.statsComputed.restore();
-@@ -1484,14 +1469,14 @@ describe('cron', () => {
- });
+@@ -1775,7 +1756,7 @@ describe('cron', () => {
it('resets user progress', () => {
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.party.quest.progress.up).to.equal(0);
expect(user.party.quest.progress.down).to.equal(0);
- expect(user.party.quest.progress.collectedItems).to.equal(0);
- });
+@@ -1784,7 +1765,7 @@ describe('cron', () => {
it('applies the user progress', () => {
-- let progress = cron({user, tasksByType, daysMissed, analytics});
-+ let progress = cron({user, tasksByType, daysMissed});
+ const progress = cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(progress.down).to.equal(-1);
});
- });
-@@ -1509,7 +1494,7 @@ describe('cron', () => {
- let hpBefore = user.stats.hp;
- tasksByType.dailys[0].startDate = moment(new Date()).subtract({days: 1});
+@@ -1804,7 +1785,7 @@ describe('cron', () => {
+ tasksByType.dailys[0].startDate = moment(new Date()).subtract({ days: 1 });
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.notifications.length).to.be.greaterThan(0);
- expect(user.notifications[1].type).to.equal('CRON');
-@@ -1533,7 +1518,7 @@ describe('cron', () => {
- let hpBefore1 = user.stats.hp;
- tasksByType.dailys[0].startDate = moment(new Date()).subtract({days: 1});
+@@ -1830,7 +1811,7 @@ describe('cron', () => {
+ tasksByType.dailys[0].startDate = moment(new Date()).subtract({ days: 1 });
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.notifications.length).to.be.greaterThan(0);
- expect(user.notifications[1].type).to.equal('CRON');
-@@ -1548,7 +1533,7 @@ describe('cron', () => {
+@@ -1847,7 +1828,7 @@ describe('cron', () => {
+ user.lastCron = moment(new Date()).subtract({ days: 2 });
- user.lastCron = moment(new Date()).subtract({days: 2});
-
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.notifications.length - notifsBefore2).to.equal(0);
- expect(user.notifications[0].type).to.not.equal('CRON');
-@@ -1593,23 +1578,23 @@ describe('cron', () => {
-
+@@ -1894,19 +1875,19 @@ describe('cron', () => {
describe('login incentives', () => {
it('increments incentive counter each cron', () => {
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.loginIncentives).to.eql(1);
- user.lastCron = moment(new Date()).subtract({days: 1});
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ user.lastCron = moment(new Date()).subtract({ days: 1 });
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.loginIncentives).to.eql(2);
});
it('pushes a notification of the day\'s incentive each cron', () => {
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.notifications.length).to.be.greaterThan(1);
expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
- });
+@@ -1914,13 +1895,13 @@ describe('cron', () => {
it('replaces previous notifications', () => {
-- cron({user, tasksByType, daysMissed, analytics});
-- cron({user, tasksByType, daysMissed, analytics});
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
-+ cron({user, tasksByType, daysMissed});
-+ cron({user, tasksByType, daysMissed});
-
- let filteredNotifications = user.notifications.filter(n => n.type === 'LOGIN_INCENTIVE');
-
-@@ -1618,18 +1603,18 @@ describe('cron', () => {
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
+ const filteredNotifications = user.notifications.filter(n => n.type === 'LOGIN_INCENTIVE');
+@@ -1931,7 +1912,7 @@ describe('cron', () => {
it('increments loginIncentives by 1 even if days are skipped in between', () => {
daysMissed = 3;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.loginIncentives).to.eql(1);
});
-
+@@ -1939,14 +1920,14 @@ describe('cron', () => {
it('increments loginIncentives by 1 even if user is sleeping', () => {
user.preferences.sleep = true;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.loginIncentives).to.eql(1);
});
it('awards user bard robes if login incentive is 1', () => {
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.loginIncentives).to.eql(1);
expect(user.items.gear.owned.armor_special_bardRobes).to.eql(true);
- expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
-@@ -1637,7 +1622,7 @@ describe('cron', () => {
-
+@@ -1956,7 +1937,7 @@ describe('cron', () => {
it('awards user incentive backgrounds if login incentive is 2', () => {
user.loginIncentives = 1;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.loginIncentives).to.eql(2);
expect(user.purchased.background.blue).to.eql(true);
- expect(user.purchased.background.green).to.eql(true);
-@@ -1649,7 +1634,7 @@ describe('cron', () => {
-
+@@ -1970,7 +1951,7 @@ describe('cron', () => {
it('awards user Bard Hat if login incentive is 3', () => {
user.loginIncentives = 2;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.loginIncentives).to.eql(3);
expect(user.items.gear.owned.head_special_bardHat).to.eql(true);
- expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
-@@ -1657,7 +1642,7 @@ describe('cron', () => {
-
+@@ -1980,7 +1961,7 @@ describe('cron', () => {
it('awards user RoyalPurple Hatching Potion if login incentive is 4', () => {
user.loginIncentives = 3;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.loginIncentives).to.eql(4);
expect(user.items.hatchingPotions.RoyalPurple).to.eql(1);
- expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
-@@ -1665,7 +1650,7 @@ describe('cron', () => {
-
+@@ -1990,7 +1971,7 @@ describe('cron', () => {
it('awards user a Chocolate, Meat and Pink Contton Candy if login incentive is 5', () => {
user.loginIncentives = 4;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.loginIncentives).to.eql(5);
- expect(user.items.food.Chocolate).to.eql(1);
-@@ -1677,7 +1662,7 @@ describe('cron', () => {
-
+@@ -2004,7 +1985,7 @@ describe('cron', () => {
it('awards user moon quest if login incentive is 7', () => {
user.loginIncentives = 6;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.loginIncentives).to.eql(7);
expect(user.items.quests.moon1).to.eql(1);
- expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
-@@ -1685,7 +1670,7 @@ describe('cron', () => {
-
+@@ -2014,7 +1995,7 @@ describe('cron', () => {
it('awards user RoyalPurple Hatching Potion if login incentive is 10', () => {
user.loginIncentives = 9;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.loginIncentives).to.eql(10);
expect(user.items.hatchingPotions.RoyalPurple).to.eql(1);
- expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
-@@ -1693,7 +1678,7 @@ describe('cron', () => {
-
+@@ -2024,7 +2005,7 @@ describe('cron', () => {
it('awards user a Strawberry, Patato and Blue Contton Candy if login incentive is 14', () => {
user.loginIncentives = 13;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.loginIncentives).to.eql(14);
- expect(user.items.food.Strawberry).to.eql(1);
-@@ -1705,7 +1690,7 @@ describe('cron', () => {
-
+@@ -2038,7 +2019,7 @@ describe('cron', () => {
it('awards user a bard instrument if login incentive is 18', () => {
user.loginIncentives = 17;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.loginIncentives).to.eql(18);
expect(user.items.gear.owned.weapon_special_bardInstrument).to.eql(true);
- expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
-@@ -1713,7 +1698,7 @@ describe('cron', () => {
-
+@@ -2048,7 +2029,7 @@ describe('cron', () => {
it('awards user second moon quest if login incentive is 22', () => {
user.loginIncentives = 21;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.loginIncentives).to.eql(22);
expect(user.items.quests.moon2).to.eql(1);
- expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
-@@ -1721,7 +1706,7 @@ describe('cron', () => {
-
+@@ -2058,7 +2039,7 @@ describe('cron', () => {
it('awards user a RoyalPurple hatching potion if login incentive is 26', () => {
user.loginIncentives = 25;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.loginIncentives).to.eql(26);
expect(user.items.hatchingPotions.RoyalPurple).to.eql(1);
- expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
-@@ -1729,7 +1714,7 @@ describe('cron', () => {
-
+@@ -2068,7 +2049,7 @@ describe('cron', () => {
it('awards user Fish, Milk, Rotten Meat and Honey if login incentive is 30', () => {
user.loginIncentives = 29;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.loginIncentives).to.eql(30);
- expect(user.items.food.Fish).to.eql(1);
-@@ -1742,7 +1727,7 @@ describe('cron', () => {
-
+@@ -2083,7 +2064,7 @@ describe('cron', () => {
it('awards user a RoyalPurple hatching potion if login incentive is 35', () => {
user.loginIncentives = 34;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.loginIncentives).to.eql(35);
expect(user.items.hatchingPotions.RoyalPurple).to.eql(1);
- expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
-@@ -1750,7 +1735,7 @@ describe('cron', () => {
-
+@@ -2093,7 +2074,7 @@ describe('cron', () => {
it('awards user the third moon quest if login incentive is 40', () => {
user.loginIncentives = 39;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.loginIncentives).to.eql(40);
expect(user.items.quests.moon3).to.eql(1);
- expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
-@@ -1758,7 +1743,7 @@ describe('cron', () => {
-
+@@ -2103,7 +2084,7 @@ describe('cron', () => {
it('awards user a RoyalPurple hatching potion if login incentive is 45', () => {
user.loginIncentives = 44;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.loginIncentives).to.eql(45);
expect(user.items.hatchingPotions.RoyalPurple).to.eql(1);
- expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
-@@ -1766,7 +1751,7 @@ describe('cron', () => {
-
+@@ -2113,7 +2094,7 @@ describe('cron', () => {
it('awards user a saddle if login incentive is 50', () => {
user.loginIncentives = 49;
-- cron({user, tasksByType, daysMissed, analytics});
-+ cron({user, tasksByType, daysMissed});
+ cron({
+- user, tasksByType, daysMissed, analytics,
++ user, tasksByType, daysMissed,
+ });
expect(user.loginIncentives).to.eql(50);
expect(user.items.food.Saddle).to.eql(1);
- expect(user.notifications[0].type).to.eql('LOGIN_INCENTIVE');
diff --git a/test/api/unit/libs/email.test.js b/test/api/unit/libs/email.test.js
-index 6b4d368aa6..93cffd8693 100644
+index 057766eddd..9179ba9642 100644
--- a/test/api/unit/libs/email.test.js
+++ b/test/api/unit/libs/email.test.js
-@@ -51,22 +51,6 @@ describe('emails', () => {
- expect(data).to.have.property('_id', user._id);
+@@ -52,21 +52,6 @@ describe('emails', () => {
expect(data).to.have.property('canSend', true);
});
--
+
- it('returns correct user data [facebook users]', () => {
-- let attachEmail = requireAgain(pathToEmailLib);
-- let getUserInfo = attachEmail.getUserInfo;
-- let user = getUser();
+- const attachEmail = requireAgain(pathToEmailLib);
+- const { getUserInfo } = attachEmail;
+- const user = getUser();
- delete user.profile.name;
- delete user.auth.local.email;
-
-- let data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
+- 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.facebook.emails[0].value);
@@ -1396,22 +1453,22 @@ index 6b4d368aa6..93cffd8693 100644
- });
-
it('has fallbacks for missing data', () => {
- let attachEmail = requireAgain(pathToEmailLib);
- let getUserInfo = attachEmail.getUserInfo;
+ const attachEmail = requireAgain(pathToEmailLib);
+ const { getUserInfo } = attachEmail;
diff --git a/test/api/unit/libs/payments/payments.test.js b/test/api/unit/libs/payments/payments.test.js
-index f37c5c511b..d33a0095cf 100644
+index 76d0d3d00e..b9144665bb 100644
--- a/test/api/unit/libs/payments/payments.test.js
+++ b/test/api/unit/libs/payments/payments.test.js
-@@ -2,8 +2,6 @@ import moment from 'moment';
+@@ -1,8 +1,6 @@
+ import moment from 'moment';
import * as sender from '../../../../../website/server/libs/email';
- import * as api from '../../../../../website/server/libs/payments/payments';
--import analytics from '../../../../../website/server/libs/analyticsService';
--import notifications from '../../../../../website/server/libs/pushNotifications';
+-import api from '../../../../../website/server/libs/payments/payments';
+-import * as analytics from '../../../../../website/server/libs/analyticsService';
+ import * as notifications from '../../../../../website/server/libs/pushNotifications';
import { model as User } from '../../../../../website/server/models/user';
import { translate as t } from '../../../../helpers/api-integration/v3';
- import {
-@@ -29,9 +27,6 @@ describe('payments/index', () => {
+@@ -30,9 +28,6 @@ describe('payments/index', () => {
sandbox.stub(sender, 'sendTxn');
sandbox.stub(user, 'sendMessage');
@@ -1421,7 +1478,7 @@ index f37c5c511b..d33a0095cf 100644
data = {
user,
-@@ -225,28 +220,6 @@ describe('payments/index', () => {
+@@ -229,28 +224,6 @@ describe('payments/index', () => {
it('sends a push notification about the gift', async () => {
await api.createSubscription(data);
@@ -1450,7 +1507,7 @@ index f37c5c511b..d33a0095cf 100644
});
});
-@@ -302,14 +275,6 @@ describe('payments/index', () => {
+@@ -306,14 +279,6 @@ describe('payments/index', () => {
expect(user.purchased.plan.gemsBought).to.eql(10);
});
@@ -1465,7 +1522,7 @@ index f37c5c511b..d33a0095cf 100644
it('increases the user\'s transaction count', async () => {
expect(user.purchased.txnCount).to.eql(0);
-@@ -324,27 +289,6 @@ describe('payments/index', () => {
+@@ -328,27 +293,6 @@ describe('payments/index', () => {
expect(sender.sendTxn).to.be.calledOnce;
expect(sender.sendTxn).to.be.calledWith(data.user, 'subscription-begins');
});
@@ -1493,8 +1550,8 @@ index f37c5c511b..d33a0095cf 100644
});
context('Block subscription perks', () => {
-@@ -655,11 +599,6 @@ describe('payments/index', () => {
- expect(user.sendMessage).to.be.calledWith(recipient, { receiverMsg: msg, senderMsg: msg, save: false });
+@@ -661,11 +605,6 @@ describe('payments/index', () => {
+ .calledWith(recipient, { receiverMsg: msg, senderMsg: msg, save: false });
});
- it('sends a push notification if user did not gift to self', async () => {
@@ -1506,18 +1563,18 @@ index f37c5c511b..d33a0095cf 100644
// TODO using english for both users because other languages are not loaded
// for api.buyGems
diff --git a/test/api/unit/middlewares/cronMiddleware.js b/test/api/unit/middlewares/cronMiddleware.js
-index 28d4135e25..2deb852285 100644
+index bd93b06e65..8300399107 100644
--- a/test/api/unit/middlewares/cronMiddleware.js
+++ b/test/api/unit/middlewares/cronMiddleware.js
-@@ -9,7 +9,6 @@ import moment from 'moment';
+@@ -10,7 +10,6 @@ import cronMiddleware from '../../../../website/server/middlewares/cron';
import { model as User } from '../../../../website/server/models/user';
import { model as Group } from '../../../../website/server/models/group';
import * as Tasks from '../../../../website/server/models/task';
--import analyticsService from '../../../../website/server/libs/analyticsService';
+-import * as analyticsService from '../../../../website/server/libs/analyticsService';
import * as cronLib from '../../../../website/server/libs/cron';
- import { v4 as generateUUID } from 'uuid';
-@@ -38,7 +37,6 @@ describe('cron middleware', () => {
+ const CRON_TIMEOUT_WAIT = new Date(60 * 60 * 1000).getTime();
+@@ -39,7 +38,6 @@ describe('cron middleware', () => {
user.save()
.then(savedUser => {
res.locals.user = savedUser;
@@ -1526,31 +1583,35 @@ index 28d4135e25..2deb852285 100644
})
.catch(done);
diff --git a/test/api/v3/integration/chat/POST-chat.flag.test.js b/test/api/v3/integration/chat/POST-chat.flag.test.js
-index 723715c80b..322e5853a0 100644
+index d3484452f3..c0172114a2 100644
--- a/test/api/v3/integration/chat/POST-chat.flag.test.js
+++ b/test/api/v3/integration/chat/POST-chat.flag.test.js
-@@ -4,10 +4,6 @@ import {
- } from '../../../../helpers/api-integration/v3';
+@@ -1,14 +1,10 @@
import { find } from 'lodash';
import moment from 'moment';
-import nconf from 'nconf';
-import { IncomingWebhook } from '@slack/client';
--
--const BASE_URL = nconf.get('BASE_URL');
+ import {
+ generateUser,
+ translate as t,
+ } from '../../../../helpers/api-integration/v3';
+-const BASE_URL = nconf.get('BASE_URL');
+-
describe('POST /chat/:chatId/flag', () => {
- let user, admin, anotherUser, newUser, group;
-@@ -19,7 +15,6 @@ describe('POST /chat/:chatId/flag', () => {
- admin = await generateUser({balance: 1, 'contributor.admin': true});
- anotherUser = await generateUser({'auth.timestamps.created': moment().subtract(USER_AGE_FOR_FLAGGING + 1, 'days').toDate()});
- newUser = await generateUser({'auth.timestamps.created': moment().subtract(1, 'days').toDate()});
+ let user; let admin; let anotherUser; let newUser; let
+ group;
+@@ -20,7 +16,6 @@ describe('POST /chat/:chatId/flag', () => {
+ admin = await generateUser({ balance: 1, 'contributor.admin': true });
+ anotherUser = await generateUser({ 'auth.timestamps.created': moment().subtract(USER_AGE_FOR_FLAGGING + 1, 'days').toDate() });
+ newUser = await generateUser({ 'auth.timestamps.created': moment().subtract(1, 'days').toDate() });
- sandbox.stub(IncomingWebhook.prototype, 'send');
group = await user.post('/groups', {
name: 'Test Guild',
-@@ -57,31 +52,9 @@ describe('POST /chat/:chatId/flag', () => {
+@@ -58,31 +53,9 @@ describe('POST /chat/:chatId/flag', () => {
- let messageToCheck = find(groupWithFlags.chat, {id: message.id});
+ const messageToCheck = find(groupWithFlags.chat, { id: message.id });
expect(messageToCheck.flags[user._id]).to.equal(true);
-
- // Slack message to mods
@@ -1576,13 +1637,13 @@ index 723715c80b..322e5853a0 100644
});
it('Does not increment message flag count and sends different message to moderator Slack when user is new', async () => {
-- let automatedComment = `The post's flag count has not been increased because the flagger's account is less than ${USER_AGE_FOR_FLAGGING} days old.`;
- let { message } = await newUser.post(`/groups/${group._id}/chat`, {message: TEST_MESSAGE});
+- const automatedComment = `The post's flag count has not been increased because the flagger's account is less than ${USER_AGE_FOR_FLAGGING} days old.`;
+ const { message } = await newUser.post(`/groups/${group._id}/chat`, { message: TEST_MESSAGE });
- let flagResult = await newUser.post(`/groups/${group._id}/chat/${message.id}/flag`);
-@@ -92,27 +65,6 @@ describe('POST /chat/:chatId/flag', () => {
+ const flagResult = await newUser.post(`/groups/${group._id}/chat/${message.id}/flag`);
+@@ -93,27 +66,6 @@ describe('POST /chat/:chatId/flag', () => {
- let messageToCheck = find(groupWithFlags.chat, {id: message.id});
+ const messageToCheck = find(groupWithFlags.chat, { id: message.id });
expect(messageToCheck.flags[newUser._id]).to.equal(true);
-
- // Slack message to mods
@@ -1609,15 +1670,15 @@ index 723715c80b..322e5853a0 100644
it('Flags a chat when the author\'s account was deleted', async () => {
diff --git a/test/api/v3/integration/chat/POST-chat.test.js b/test/api/v3/integration/chat/POST-chat.test.js
-index 73ac2d3bf9..50cb211863 100644
+index 73abe0728c..6fbb138251 100644
--- a/test/api/v3/integration/chat/POST-chat.test.js
+++ b/test/api/v3/integration/chat/POST-chat.test.js
@@ -1,5 +1,3 @@
-import { IncomingWebhook } from '@slack/client';
-import nconf from 'nconf';
+ import { v4 as generateUUID } from 'uuid';
import {
createAndPopulateGroup,
- generateUser,
@@ -19,8 +17,6 @@ import bannedWords from '../../../../../website/server/libs/bannedWords';
import guildsAllowingBannedWords from '../../../../../website/server/libs/guildsAllowingBannedWords';
import * as email from '../../../../../website/server/libs/email';
@@ -1625,9 +1686,9 @@ index 73ac2d3bf9..50cb211863 100644
-const BASE_URL = nconf.get('BASE_URL');
-
describe('POST /chat', () => {
- let user, groupWithChat, member, additionalMember;
- let testMessage = 'Test Message';
-@@ -358,7 +354,6 @@ describe('POST /chat', () => {
+ let user; let groupWithChat; let member; let
+ additionalMember;
+@@ -363,7 +359,6 @@ describe('POST /chat', () => {
context('banned slur', () => {
beforeEach(() => {
sandbox.spy(email, 'sendTxn');
@@ -1635,7 +1696,7 @@ index 73ac2d3bf9..50cb211863 100644
});
afterEach(() => {
-@@ -378,25 +373,6 @@ describe('POST /chat', () => {
+@@ -383,25 +378,6 @@ describe('POST /chat', () => {
expect(email.sendTxn).to.be.calledOnce;
expect(email.sendTxn.args[0][1]).to.eql('slur-report-to-mods');
@@ -1659,9 +1720,9 @@ index 73ac2d3bf9..50cb211863 100644
- /* eslint-enable camelcase */
-
// Chat privileges are revoked
- await expect(user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage})).to.eventually.be.rejected.and.eql({
+ await expect(user.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage })).to.eventually.be.rejected.and.eql({
code: 401,
-@@ -426,25 +402,6 @@ describe('POST /chat', () => {
+@@ -431,25 +407,6 @@ describe('POST /chat', () => {
expect(email.sendTxn).to.be.calledThrice;
expect(email.sendTxn.args[2][1]).to.eql('slur-report-to-mods');
@@ -1685,10 +1746,10 @@ index 73ac2d3bf9..50cb211863 100644
- /* eslint-enable camelcase */
-
// Chat privileges are revoked
- await expect(members[0].post(`/groups/${groupWithChat._id}/chat`, { message: testMessage})).to.eventually.be.rejected.and.eql({
+ await expect(members[0].post(`/groups/${groupWithChat._id}/chat`, { message: testMessage })).to.eventually.be.rejected.and.eql({
code: 401,
diff --git a/test/api/v3/integration/user/DELETE-user.test.js b/test/api/v3/integration/user/DELETE-user.test.js
-index 2fbe493d43..1e70c3486e 100644
+index 644a2d57ba..a7b75bfb1f 100644
--- a/test/api/v3/integration/user/DELETE-user.test.js
+++ b/test/api/v3/integration/user/DELETE-user.test.js
@@ -17,8 +17,6 @@ import {
@@ -1699,8 +1760,8 @@ index 2fbe493d43..1e70c3486e 100644
-
describe('DELETE /user', () => {
let user;
- let password = 'password'; // from habitrpg/test/helpers/api-integration/v3/object-generators.js
-@@ -290,62 +288,4 @@ describe('DELETE /user', () => {
+ const password = 'password'; // from habitrpg/test/helpers/api-integration/v3/object-generators.js
+@@ -288,62 +286,4 @@ describe('DELETE /user', () => {
});
});
});
@@ -1722,7 +1783,7 @@ index 2fbe493d43..1e70c3486e 100644
- })).to.eventually.be.rejected.and.eql({
- code: 401,
- error: 'NotAuthorized',
-- message: t('incorrectDeletePhrase', {magicWord: 'DELETE'}),
+- message: t('incorrectDeletePhrase', { magicWord: 'DELETE' }),
- });
- });
-
@@ -1764,7 +1825,7 @@ index 2fbe493d43..1e70c3486e 100644
- });
});
diff --git a/test/api/v3/integration/user/POST-user_sleep.test.js b/test/api/v3/integration/user/POST-user_sleep.test.js
-index 292b77e9db..0e9773150e 100644
+index 9afb4a1956..9db5958663 100644
--- a/test/api/v3/integration/user/POST-user_sleep.test.js
+++ b/test/api/v3/integration/user/POST-user_sleep.test.js
@@ -1,7 +1,6 @@
@@ -1792,7 +1853,7 @@ index 292b77e9db..0e9773150e 100644
- });
});
diff --git a/test/api/v3/integration/user/auth/POST-register_local.test.js b/test/api/v3/integration/user/auth/POST-register_local.test.js
-index c6b3248258..5b559aae5b 100644
+index 896e20a0c0..59e518fcb8 100644
--- a/test/api/v3/integration/user/auth/POST-register_local.test.js
+++ b/test/api/v3/integration/user/auth/POST-register_local.test.js
@@ -440,40 +440,6 @@ describe('POST /user/auth/local/register', () => {
@@ -1801,9 +1862,9 @@ index c6b3248258..5b559aae5b 100644
- context('attach to facebook user', () => {
- let user;
-- let email = 'some@email.net';
-- let username = 'some-username';
-- let password = 'some-password';
+- const email = 'some@email.net';
+- const username = 'some-username';
+- const password = 'some-password';
- beforeEach(async () => {
- user = await generateUser();
- });
@@ -1834,10 +1895,10 @@ index c6b3248258..5b559aae5b 100644
- });
-
context('login is already taken', () => {
- let username, email, api;
-
+ let username; let email; let
+ api;
diff --git a/test/api/v4/user/auth/POST-register_local.test.js b/test/api/v4/user/auth/POST-register_local.test.js
-index 62df06f307..b75c9b4c55 100644
+index 5d5b3abdbb..7dc4f265b6 100644
--- a/test/api/v4/user/auth/POST-register_local.test.js
+++ b/test/api/v4/user/auth/POST-register_local.test.js
@@ -423,40 +423,6 @@ describe('POST /user/auth/local/register', () => {
@@ -1846,9 +1907,9 @@ index 62df06f307..b75c9b4c55 100644
- context('attach to facebook user', () => {
- let user;
-- let email = 'some@email.net';
-- let username = 'some-username';
-- let password = 'some-password';
+- const email = 'some@email.net';
+- const username = 'some-username';
+- const password = 'some-password';
- beforeEach(async () => {
- user = await generateUser();
- });
@@ -1879,17 +1940,17 @@ index 62df06f307..b75c9b4c55 100644
- });
-
context('login is already taken', () => {
- let username, email, api;
-
+ let username; let email; let
+ api;
diff --git a/test/common/ops/buy/buy.js b/test/common/ops/buy/buy.js
-index 582166e9a9..8bbf38b496 100644
+index eed601e10a..1cb901e7d1 100644
--- a/test/common/ops/buy/buy.js
+++ b/test/common/ops/buy/buy.js
-@@ -13,7 +13,6 @@ import { defaultsDeep } from 'lodash';
+@@ -13,7 +13,6 @@ import errorMessage from '../../../../website/common/script/libs/errorMessage';
describe('shared.ops.buy', () => {
let user;
-- let analytics = {track () {}};
+- const analytics = { track () {} };
beforeEach(() => {
user = generateUser({
@@ -1905,13 +1966,13 @@ index 582166e9a9..8bbf38b496 100644
- analytics.track.restore();
});
- it('returns error when key is not provided', (done) => {
+ it('returns error when key is not provided', done => {
@@ -52,10 +45,8 @@ describe('shared.ops.buy', () => {
it('recovers 15 hp', () => {
user.stats.hp = 30;
-- buy(user, {params: {key: 'potion'}}, analytics);
-+ buy(user, {params: {key: 'potion'}});
+- buy(user, { params: { key: 'potion' } }, analytics);
++ buy(user, { params: { key: 'potion' } });
expect(user.stats.hp).to.eql(45);
-
- expect(analytics.track).to.be.calledOnce;
@@ -1919,14 +1980,14 @@ index 582166e9a9..8bbf38b496 100644
it('adds equipment to inventory', () => {
diff --git a/test/common/ops/buy/buyArmoire.js b/test/common/ops/buy/buyArmoire.js
-index 3c58585022..aa4ddd17d5 100644
+index a3a79d8341..ab3ccafbb8 100644
--- a/test/common/ops/buy/buyArmoire.js
+++ b/test/common/ops/buy/buyArmoire.js
@@ -31,10 +31,9 @@ describe('shared.ops.buyArmoire', () => {
- let YIELD_EQUIPMENT = 0.5;
- let YIELD_FOOD = 0.7;
- let YIELD_EXP = 0.9;
-- let analytics = {track () {}};
+ const YIELD_EQUIPMENT = 0.5;
+ const YIELD_FOOD = 0.7;
+ const YIELD_EXP = 0.9;
+- const analytics = { track () {} };
- function buyArmoire (_user, _req, _analytics) {
- const buyOp = new BuyArmoireOperation(_user, _req, _analytics);
@@ -1938,12 +1999,12 @@ index 3c58585022..aa4ddd17d5 100644
@@ -52,12 +51,10 @@ describe('shared.ops.buyArmoire', () => {
user.items.food = {};
- sandbox.stub(randomVal, 'trueRandom');
+ sandbox.stub(randomValFns, 'trueRandom');
- sinon.stub(analytics, 'track');
});
afterEach(() => {
- randomVal.trueRandom.restore();
+ randomValFns.trueRandom.restore();
- analytics.track.restore();
});
@@ -1966,7 +2027,7 @@ index 3c58585022..aa4ddd17d5 100644
});
});
diff --git a/test/common/ops/buy/buyGem.js b/test/common/ops/buy/buyGem.js
-index fc3d00f708..4ae96a55b7 100644
+index d0a726a86d..2321c4453e 100644
--- a/test/common/ops/buy/buyGem.js
+++ b/test/common/ops/buy/buyGem.js
@@ -1,6 +1,5 @@
@@ -1977,23 +2038,23 @@ index fc3d00f708..4ae96a55b7 100644
generateUser,
} from '../../../helpers/common.helper';
@@ -11,15 +10,14 @@ import i18n from '../../../../website/common/script/i18n';
- import {BuyGemOperation} from '../../../../website/common/script/ops/buy/buyGem';
+ import { BuyGemOperation } from '../../../../website/common/script/ops/buy/buyGem';
import planGemLimits from '../../../../website/common/script/libs/planGemLimits';
-function buyGem (user, req, analytics) {
-- let buyOp = new BuyGemOperation(user, req, analytics);
+- const buyOp = new BuyGemOperation(user, req, analytics);
+function buyGem (user, req) {
-+ let buyOp = new BuyGemOperation(user, req);
++ const buyOp = new BuyGemOperation(user, req);
return buyOp.purchase();
}
describe('shared.ops.buyGem', () => {
let user;
-- let analytics = {track () {}};
- let goldPoints = 40;
- let gemsBought = 40;
- let userGemAmount = 10;
+- const analytics = { track () {} };
+ const goldPoints = 40;
+ const gemsBought = 40;
+ const userGemAmount = 10;
@@ -35,23 +33,16 @@ describe('shared.ops.buyGem', () => {
},
},
@@ -2008,10 +2069,10 @@ index fc3d00f708..4ae96a55b7 100644
context('Gems', () => {
it('purchases gems', () => {
-- let [, message] = buyGem(user, {params: {type: 'gems', key: 'gem'}}, analytics);
-+ let [, message] = buyGem(user, {params: {type: 'gems', key: 'gem'}});
+- const [, message] = buyGem(user, { params: { type: 'gems', key: 'gem' } }, analytics);
++ const [, message] = buyGem(user, { params: { type: 'gems', key: 'gem' } });
- expect(message).to.equal(i18n.t('plusGem', {count: 1}));
+ expect(message).to.equal(i18n.t('plusGem', { count: 1 }));
expect(user.balance).to.equal(userGemAmount + 0.25);
expect(user.purchased.plan.gemsBought).to.equal(1);
expect(user.stats.gp).to.equal(goldPoints - planGemLimits.convRate);
@@ -2020,14 +2081,14 @@ index fc3d00f708..4ae96a55b7 100644
it('purchases gems with a different language than the default', () => {
diff --git a/test/common/ops/buy/buyHealthPotion.js b/test/common/ops/buy/buyHealthPotion.js
-index 9f04c4d6bb..01fcc829d2 100644
+index 5ed2df7e19..2bc1574edd 100644
--- a/test/common/ops/buy/buyHealthPotion.js
+++ b/test/common/ops/buy/buyHealthPotion.js
@@ -10,10 +10,9 @@ import i18n from '../../../../website/common/script/i18n';
describe('shared.ops.buyHealthPotion', () => {
let user;
-- let analytics = {track () {}};
+- const analytics = { track () {} };
- function buyHealthPotion (_user, _req, _analytics) {
- const buyOp = new BuyHealthPotionOperation(_user, _req, _analytics);
@@ -2058,24 +2119,24 @@ index 9f04c4d6bb..01fcc829d2 100644
it('does not increase hp above 50', () => {
diff --git a/test/common/ops/buy/buyMarketGear.js b/test/common/ops/buy/buyMarketGear.js
-index a732afa4e0..d91b70e921 100644
+index 3b123d5a6c..8e87bd355e 100644
--- a/test/common/ops/buy/buyMarketGear.js
+++ b/test/common/ops/buy/buyMarketGear.js
-@@ -13,15 +13,14 @@ import i18n from '../../../../website/common/script/i18n';
+@@ -13,15 +13,14 @@ import {
+ import i18n from '../../../../website/common/script/i18n';
import errorMessage from '../../../../website/common/script/libs/errorMessage';
- import { defaultsDeep } from 'lodash';
-function buyGear (user, req, analytics) {
-- let buyOp = new BuyMarketGearOperation(user, req, analytics);
+- const buyOp = new BuyMarketGearOperation(user, req, analytics);
+function buyGear (user, req) {
-+ let buyOp = new BuyMarketGearOperation(user, req);
++ const buyOp = new BuyMarketGearOperation(user, req);
return buyOp.purchase();
}
describe('shared.ops.buyMarketGear', () => {
let user;
-- let analytics = {track () {}};
+- const analytics = { track () {} };
beforeEach(() => {
user = generateUser({
@@ -2096,8 +2157,8 @@ index a732afa4e0..d91b70e921 100644
it('adds equipment to inventory', () => {
user.stats.gp = 31;
-- buyGear(user, {params: {key: 'armor_warrior_1'}}, analytics);
-+ buyGear(user, {params: {key: 'armor_warrior_1'}});
+- buyGear(user, { params: { key: 'armor_warrior_1' } }, analytics);
++ buyGear(user, { params: { key: 'armor_warrior_1' } });
expect(user.items.gear.owned).to.eql({
weapon_warrior_0: true,
@@ -2110,14 +2171,14 @@ index a732afa4e0..d91b70e921 100644
it('deducts gold from user', () => {
diff --git a/test/common/ops/buy/buyMysterySet.js b/test/common/ops/buy/buyMysterySet.js
-index dca60d7489..9ef720f70c 100644
+index 6db89cf998..8d844f403b 100644
--- a/test/common/ops/buy/buyMysterySet.js
+++ b/test/common/ops/buy/buyMysterySet.js
@@ -14,7 +14,6 @@ import errorMessage from '../../../../website/common/script/libs/errorMessage';
describe('shared.ops.buyMysterySet', () => {
let user;
-- let analytics = {track () {}};
+- const analytics = { track () {} };
beforeEach(() => {
user = generateUser({
@@ -2137,8 +2198,8 @@ index dca60d7489..9ef720f70c 100644
context('successful purchases', () => {
it('buys Steampunk Accessories Set', () => {
user.purchased.plan.consecutive.trinkets = 1;
-- buyMysterySet(user, {params: {key: '301404'}}, analytics);
-+ buyMysterySet(user, {params: {key: '301404'}});
+- buyMysterySet(user, { params: { key: '301404' } }, analytics);
++ buyMysterySet(user, { params: { key: '301404' } });
expect(user.purchased.plan.consecutive.trinkets).to.eql(0);
expect(user.items.gear.owned).to.have.property('weapon_warrior_0', true);
@@ -2151,14 +2212,14 @@ index dca60d7489..9ef720f70c 100644
});
});
diff --git a/test/common/ops/buy/buyQuestGems.js b/test/common/ops/buy/buyQuestGems.js
-index 8e98e1b94d..050f74f152 100644
+index d1c25b0832..a551fa2692 100644
--- a/test/common/ops/buy/buyQuestGems.js
+++ b/test/common/ops/buy/buyQuestGems.js
-@@ -11,10 +11,9 @@ import {BuyQuestWithGemOperation} from '../../../../website/common/script/ops/bu
+@@ -11,10 +11,9 @@ import { BuyQuestWithGemOperation } from '../../../../website/common/script/ops/
describe('shared.ops.buyQuestGems', () => {
let user;
- let goldPoints = 40;
-- let analytics = {track () {}};
+ const goldPoints = 40;
+- const analytics = { track () {} };
- function buyQuest (_user, _req, _analytics) {
- const buyOp = new BuyQuestWithGemOperation(_user, _req, _analytics);
@@ -2181,14 +2242,14 @@ index 8e98e1b94d..050f74f152 100644
});
diff --git a/test/common/ops/buy/buyQuestGold.js b/test/common/ops/buy/buyQuestGold.js
-index dec213aa54..a992b496e5 100644
+index f2be81495d..094d71191a 100644
--- a/test/common/ops/buy/buyQuestGold.js
+++ b/test/common/ops/buy/buyQuestGold.js
@@ -12,21 +12,15 @@ import errorMessage from '../../../../website/common/script/libs/errorMessage';
describe('shared.ops.buyQuest', () => {
let user;
-- let analytics = {track () {}};
+- const analytics = { track () {} };
- function buyQuest (_user, _req, _analytics) {
- const buyOp = new BuyQuestWithGoldOperation(_user, _req, _analytics);
@@ -2225,7 +2286,7 @@ index dec213aa54..a992b496e5 100644
@@ -49,10 +42,9 @@ describe('shared.ops.buyQuest', () => {
user.items.quests[key] = -1;
buyQuest(user, {
- params: {key},
+ params: { key },
- }, analytics);
+ });
expect(user.items.quests[key]).to.equal(1);
@@ -2260,14 +2321,14 @@ index dec213aa54..a992b496e5 100644
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(i18n.t('invalidQuantity'));
diff --git a/test/common/ops/buy/buySpell.js b/test/common/ops/buy/buySpell.js
-index 02d0bda6a4..6db2b7b509 100644
+index 83b8008756..d7ef342f32 100644
--- a/test/common/ops/buy/buySpell.js
+++ b/test/common/ops/buy/buySpell.js
@@ -13,20 +13,14 @@ import errorMessage from '../../../../website/common/script/libs/errorMessage';
describe('shared.ops.buySpecialSpell', () => {
let user;
-- let analytics = {track () {}};
+- const analytics = { track () {} };
- function buySpecialSpell (_user, _req, _analytics) {
- const buyOp = new BuySpellOperation(_user, _req, _analytics);
@@ -2285,7 +2346,7 @@ index 02d0bda6a4..6db2b7b509 100644
- analytics.track.restore();
});
- it('throws an error if params.key is missing', (done) => {
+ it('throws an error if params.key is missing', done => {
@@ -76,7 +70,7 @@ describe('shared.ops.buySpecialSpell', () => {
params: {
key: 'thankyou',
@@ -2303,18 +2364,22 @@ index 02d0bda6a4..6db2b7b509 100644
});
});
diff --git a/test/common/ops/buy/hourglassPurchase.js b/test/common/ops/buy/hourglassPurchase.js
-index 6f9bf50808..d1c660aeb1 100644
+index a04ad429a3..3468271dd8 100644
--- a/test/common/ops/buy/hourglassPurchase.js
+++ b/test/common/ops/buy/hourglassPurchase.js
-@@ -13,7 +13,6 @@ import {BuyHourglassMountOperation} from '../../../../website/common/script/ops/
+@@ -13,21 +13,15 @@ import { BuyHourglassMountOperation } from '../../../../website/common/script/op
describe('common.ops.hourglassPurchase', () => {
let user;
-- let analytics = {track () {}};
+- const analytics = { track () {} };
- function buyMount (_user, _req, _analytics) {
- const buyOp = new BuyHourglassMountOperation(_user, _req, _analytics);
-@@ -23,11 +22,6 @@ describe('common.ops.hourglassPurchase', () => {
+- function buyMount (_user, _req, _analytics) {
+- const buyOp = new BuyHourglassMountOperation(_user, _req, _analytics);
++ function buyMount (_user, _req) {
++ const buyOp = new BuyHourglassMountOperation(_user, _req);
+
+ return buyOp.purchase();
+ }
beforeEach(() => {
user = generateUser();
@@ -2330,28 +2395,28 @@ index 6f9bf50808..d1c660aeb1 100644
it('buys a pet', () => {
user.purchased.plan.consecutive.trinkets = 2;
-- let [, message] = hourglassPurchase(user, {params: {type: 'pets', key: 'MantisShrimp-Base'}}, analytics);
-+ let [, message] = hourglassPurchase(user, {params: {type: 'pets', key: 'MantisShrimp-Base'}});
+- const [, message] = hourglassPurchase(user, { params: { type: 'pets', key: 'MantisShrimp-Base' } }, analytics);
++ const [, message] = hourglassPurchase(user, { params: { type: 'pets', key: 'MantisShrimp-Base' } });
expect(message).to.eql(i18n.t('hourglassPurchase'));
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
- expect(user.items.pets).to.eql({'MantisShrimp-Base': 5});
+ expect(user.items.pets).to.eql({ 'MantisShrimp-Base': 5 });
- expect(analytics.track).to.be.calledOnce;
});
it('buys a mount', () => {
diff --git a/test/common/ops/buy/purchase.js b/test/common/ops/buy/purchase.js
-index 5266f46c7b..8de2431340 100644
+index c97a8761eb..78e4f14e87 100644
--- a/test/common/ops/buy/purchase.js
+++ b/test/common/ops/buy/purchase.js
@@ -16,19 +16,16 @@ describe('shared.ops.purchase', () => {
const SEASONAL_FOOD = 'Meat';
let user;
- let goldPoints = 40;
-- let analytics = {track () {}};
+ const goldPoints = 40;
+- const analytics = { track () {} };
before(() => {
- user = generateUser({'stats.class': 'rogue'});
+ user = generateUser({ 'stats.class': 'rogue' });
});
beforeEach(() => {
@@ -2365,11 +2430,11 @@ index 5266f46c7b..8de2431340 100644
});
@@ -114,7 +111,7 @@ describe('shared.ops.purchase', () => {
- let key = 'Wolf';
+ const key = 'Wolf';
try {
-- purchase(user, {params: {type, key}, quantity: 'jamboree'}, analytics);
-+ purchase(user, {params: {type, key}, quantity: 'jamboree'});
+- purchase(user, { params: { type, key }, quantity: 'jamboree' }, analytics);
++ purchase(user, { params: { type, key }, quantity: 'jamboree' });
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(i18n.t('invalidQuantity'));
@@ -2377,8 +2442,8 @@ index 5266f46c7b..8de2431340 100644
user.balance = 10;
try {
-- purchase(user, {params: {type, key}, quantity: -2}, analytics);
-+ purchase(user, {params: {type, key}, quantity: -2});
+- purchase(user, { params: { type, key }, quantity: -2 }, analytics);
++ purchase(user, { params: { type, key }, quantity: -2 });
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(i18n.t('invalidQuantity'));
@@ -2386,17 +2451,17 @@ index 5266f46c7b..8de2431340 100644
user.balance = 10;
try {
-- purchase(user, {params: {type, key}, quantity: 2.9}, analytics);
-+ purchase(user, {params: {type, key}, quantity: 2.9});
+- purchase(user, { params: { type, key }, quantity: 2.9 }, analytics);
++ purchase(user, { params: { type, key }, quantity: 2.9 });
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(i18n.t('invalidQuantity'));
@@ -170,11 +167,10 @@ describe('shared.ops.purchase', () => {
- let type = 'eggs';
- let key = 'Wolf';
+ const type = 'eggs';
+ const key = 'Wolf';
-- purchase(user, {params: {type, key}}, analytics);
-+ purchase(user, {params: {type, key}});
+- purchase(user, { params: { type, key } }, analytics);
++ purchase(user, { params: { type, key } });
expect(user.items[type][key]).to.equal(1);
expect(pinnedGearUtils.removeItemByPath.notCalled).to.equal(true);
@@ -2404,96 +2469,68 @@ index 5266f46c7b..8de2431340 100644
});
it('purchases hatchingPotions', () => {
-diff --git a/webpack/config/index.js b/webpack/config/index.js
-index ca098d0a95..4f9bee934f 100644
---- a/webpack/config/index.js
-+++ b/webpack/config/index.js
-@@ -50,18 +50,6 @@ module.exports = {
- target: DEV_BASE_URL,
- changeOrigin: true,
- },
-- '/stripe': {
-- target: DEV_BASE_URL,
-- changeOrigin: true,
-- },
-- '/amazon': {
-- target: DEV_BASE_URL,
-- changeOrigin: true,
-- },
-- '/paypal': {
-- target: DEV_BASE_URL,
-- changeOrigin: true,
-- },
- '/logout-server': {
- target: DEV_BASE_URL,
- changeOrigin: true,
-diff --git a/webpack/config/prod.env.js b/webpack/config/prod.env.js
-index 7b89084678..1609e92969 100644
---- a/webpack/config/prod.env.js
-+++ b/webpack/config/prod.env.js
-@@ -12,23 +12,10 @@ setupNconf(configFile);
-
- // To avoid stringifying more data then we need,
- // items from `env` used on the client will have to be specified in this array
--// @TODO: Do we need? const CLIENT_VARS = ['language', 'isStaticPage', 'availableLanguages', 'translations',
--// 'FACEBOOK_KEY', 'GOOGLE_CLIENT_ID', 'NODE_ENV', 'BASE_URL', 'GA_ID',
--// 'AMAZON_PAYMENTS', 'STRIPE_PUB_KEY', 'AMPLITUDE_KEY',
--// 'worldDmg', 'mods', 'IS_MOBILE'];
--
--const AMAZON_SELLER_ID = nconf.get('AMAZON_PAYMENTS_SELLER_ID');
--const AMAZON_CLIENT_ID = nconf.get('AMAZON_PAYMENTS_CLIENT_ID');
--const AMAZON_MODE = nconf.get('AMAZON_PAYMENTS_MODE');
-
- let env = {
- NODE_ENV: '"production"',
- // clientVars: CLIENT_VARS,
-- AMAZON_PAYMENTS: {
-- SELLER_ID: `"${AMAZON_SELLER_ID}"`,
-- CLIENT_ID: `"${AMAZON_CLIENT_ID}"`,
-- MODE: `"${AMAZON_MODE}"`,
-- },
- EMAILS: {
- COMMUNITY_MANAGER_EMAIL: `"${nconf.get('EMAILS_COMMUNITY_MANAGER_EMAIL')}"`,
- TECH_ASSISTANCE_EMAIL: `"${nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL')}"`,
-@@ -36,7 +23,7 @@ let env = {
- },
- };
+diff --git a/website/client/public/index.html b/website/client/public/index.html
+index 8e65f80c3b..e3630bc600 100644
+--- a/website/client/public/index.html
++++ b/website/client/public/index.html
+@@ -7,18 +7,7 @@
+ <title>Habitica - Gamify Your Life</title>
+ <meta name="description" content="Habitica is a free habit and productivity app that treats your real life like a game. Habitica can help you achieve your goals to become healthy and happy.">
+ <meta name="keywords" content="Habits,Goals,Todo,Gamification,Health,Fitness,School,Work">
+- <meta name="smartbanner:title" content="Habitica">
+- <meta name="smartbanner:author" content="HabitRPG, Inc.">
+- <meta name="smartbanner:price" content="FREE">
+- <meta name="smartbanner:price-suffix-apple" content=" - On the App Store">
+- <meta name="smartbanner:price-suffix-google" content=" - In Google Play">
+- <meta name="smartbanner:icon-apple" content="/static/presskit/Logo/iOS.png">
+- <meta name="smartbanner:icon-google" content="/static/presskit/Logo/Android.png">
+- <meta name="smartbanner:button" content="VIEW">
+- <meta name="smartbanner:button-url-apple" content="https://itunes.apple.com/us/app/habitica-gamified-taskmanager/id994882113">
+- <meta name="smartbanner:button-url-google" content="https://play.google.com/store/apps/details?id=com.habitrpg.android.habitica">
+- <meta name="smartbanner:enabled-platforms" content="android,ios">
+- <link href="https://fonts.googleapis.com/css?family=Roboto+Condensed:400,400i,700,700i|Roboto:400,400i,700,700i" rel="stylesheet">
++ <link href="/static/fonts/index-fonts.css" rel="stylesheet">
+ <link rel="shortcut icon" sizes="48x48" href="/static/icons/favicon.ico">
+ <link rel="shortcut icon" sizes="192x192" href="/static/icons/favicon_192x192.png">
+ <link rel="mask-icon" href="/static/icons/favicon.ico">
+@@ -34,7 +23,6 @@
+ <div id="app"></div>
+ <!-- built files will be auto injected -->
--'NODE_ENV BASE_URL GA_ID STRIPE_PUB_KEY FACEBOOK_KEY GOOGLE_CLIENT_ID AMPLITUDE_KEY LOGGLY_CLIENT_TOKEN'
-+'NODE_ENV BASE_URL'
- .split(' ')
- .forEach(key => {
- env[key] = `"${nconf.get(key)}"`;
-diff --git a/website/client/app.vue b/website/client/app.vue
-index 7a2e7c7397..f48245c494 100644
---- a/website/client/app.vue
-+++ b/website/client/app.vue
-@@ -10,8 +10,6 @@ div
- p {{currentTip}}
- #app(:class='{"casting-spell": castingSpell}')
- banned-account-modal
-- amazon-payments-modal(v-if='!isStaticPage')
-- payments-success-modal
- sub-cancel-modal-confirm(v-if='isUserLoaded')
- sub-canceled-modal(v-if='isUserLoaded')
- snackbars
-@@ -182,15 +180,9 @@ import AppFooter from './components/appFooter';
+- <script type="text/javascript" src="//cloudfront.loggly.com/js/loggly.tracker-latest.min.js" async></script>
+ <!-- Translations -->
+ <script type='text/javascript' src='/api/v4/i18n/browser-script'></script>
+ </body>
+diff --git a/website/client/src/app.vue b/website/client/src/app.vue
+index 3b2cfc8817..890558f15a 100644
+--- a/website/client/src/app.vue
++++ b/website/client/src/app.vue
+@@ -31,8 +31,6 @@
+ :class="{'casting-spell': castingSpell}"
+ >
+ <banned-account-modal />
+- <amazon-payments-modal v-if="!isStaticPage" />
+- <payments-success-modal />
+ <sub-cancel-modal-confirm v-if="isUserLoaded" />
+ <sub-canceled-modal v-if="isUserLoaded" />
+ <snackbars />
+@@ -228,15 +226,9 @@ import AppFooter from './components/appFooter';
import notificationsDisplay from './components/notifications';
import snackbars from './components/snackbars/notifications';
- import { mapState } from 'client/libs/store';
--import * as Analytics from 'client/libs/analytics';
+ import { mapState } from '@/libs/store';
+-import * as Analytics from '@/libs/analytics';
import BuyModal from './components/shops/buyModal.vue';
- import SelectMembersModal from 'client/components/selectMembersModal.vue';
- import notifications from 'client/mixins/notifications';
--import { setup as setupPayments } from 'client/libs/payments';
--import amazonPaymentsModal from 'client/components/payments/amazonModal';
--import paymentsSuccessModal from 'client/components/payments/successModal';
--import subCancelModalConfirm from 'client/components/payments/cancelModalConfirm';
--import subCanceledModal from 'client/components/payments/canceledModal';
-
- import spellsMixin from 'client/mixins/spells';
- import { CONSTANTS, getLocalSetting, removeLocalSetting } from 'client/libs/userlocalManager';
-@@ -211,11 +203,7 @@ export default {
+ import SelectMembersModal from '@/components/selectMembersModal.vue';
+ import notifications from '@/mixins/notifications';
+-import { setup as setupPayments } from '@/libs/payments';
+-import amazonPaymentsModal from '@/components/payments/amazonModal';
+-import paymentsSuccessModal from '@/components/payments/successModal';
+-import subCancelModalConfirm from '@/components/payments/cancelModalConfirm';
+-import subCanceledModal from '@/components/payments/canceledModal';
+
+ import spellsMixin from '@/mixins/spells';
+ import { CONSTANTS, getLocalSetting, removeLocalSetting } from '@/libs/userlocalManager';
+@@ -256,11 +248,7 @@ export default {
snackbars,
BuyModal,
SelectMembersModal,
@@ -2503,10 +2540,10 @@ index 7a2e7c7397..f48245c494 100644
- subCancelModalConfirm,
- subCanceledModal,
},
+ mixins: [notifications, spellsMixin],
data () {
- return {
-@@ -410,10 +398,6 @@ export default {
- this.$store.watch(state => state.title, (title) => {
+@@ -458,10 +446,6 @@ export default {
+ this.$store.watch(state => state.title, title => {
document.title = title;
});
- this.$nextTick(() => {
@@ -2516,7 +2553,7 @@ index 7a2e7c7397..f48245c494 100644
if (this.isUserLoggedIn && !this.isStaticPage) {
// Load the user and the user tasks
-@@ -422,8 +406,6 @@ export default {
+@@ -470,8 +454,6 @@ export default {
this.$store.dispatch('tasks:fetchUserTasks'),
]).then(() => {
this.$store.state.isUserLoaded = true;
@@ -2525,7 +2562,7 @@ index 7a2e7c7397..f48245c494 100644
this.hideLoadingScreen();
-@@ -439,12 +421,9 @@ export default {
+@@ -487,12 +469,9 @@ export default {
appState = JSON.parse(appState);
if (appState.paymentCompleted) {
removeLocalSetting(CONSTANTS.savedAppStateValues.SAVED_APP_STATE);
@@ -2536,18 +2573,18 @@ index 7a2e7c7397..f48245c494 100644
- // Load external scripts after the app has been rendered
- setupPayments();
});
- }).catch((err) => {
+ }).catch(err => {
console.error('Impossible to fetch user. Clean up localStorage and refresh.', err); // eslint-disable-line no-console
-@@ -493,8 +472,6 @@ export default {
+@@ -541,8 +520,6 @@ export default {
if (data.fromRoot) return;
- const modalStack = this.$store.state.modalStack;
+ const { modalStack } = this.$store.state;
- this.trackGemPurchase(modalId, data);
-
// Add new modal to the stack
const prev = modalStack[modalStack.length - 1];
const prevId = prev ? prev.modalId : undefined;
-@@ -558,18 +535,6 @@ export default {
+@@ -610,18 +587,6 @@ export default {
return true;
},
@@ -2566,15 +2603,15 @@ index 7a2e7c7397..f48245c494 100644
itemSelected (item) {
this.selectedItemToBuy = item;
},
-@@ -659,4 +624,3 @@ export default {
- <style src="assets/css/sprites/spritesmith-main-25.css"></style>
- <style src="assets/css/sprites/spritesmith-main-26.css"></style>
- <style src="assets/css/sprites.css"></style>
+@@ -709,4 +674,3 @@ export default {
+ <style src="@/assets/css/sprites/spritesmith-main-25.css"></style>
+ <style src="@/assets/css/sprites/spritesmith-main-26.css"></style>
+ <style src="@/assets/css/sprites.css"></style>
-<style src="smartbanner.js/dist/smartbanner.min.css"></style>
-diff --git a/website/client/assets/scss/index.scss b/website/client/assets/scss/index.scss
+diff --git a/website/client/src/assets/scss/index.scss b/website/client/src/assets/scss/index.scss
index 3919ff6efd..185eb917c3 100644
---- a/website/client/assets/scss/index.scss
-+++ b/website/client/assets/scss/index.scss
+--- a/website/client/src/assets/scss/index.scss
++++ b/website/client/src/assets/scss/index.scss
@@ -36,5 +36,4 @@
@import './animals';
@import './iconalert';
@@ -2583,28 +2620,48 @@ index 3919ff6efd..185eb917c3 100644
-@import './datepicker.scss';
\ No newline at end of file
+@import './datepicker.scss';
-diff --git a/website/client/components/achievements/achievementFooter.vue b/website/client/components/achievements/achievementFooter.vue
-index dd899a34b6..9b5328c7cb 100644
---- a/website/client/components/achievements/achievementFooter.vue
-+++ b/website/client/components/achievements/achievementFooter.vue
-@@ -1,16 +1,5 @@
- <template lang="pug">
- .modal-footer(style='margin-top:0', ng-init='loadWidgets()')
-- .container-fluid.share-buttons
-- .row
-- .col-12.text-center
-- a.twitter-share-button.share-button(:href='twitterLink', target='_blank')
-- .social-icon.twitter.svg-icon(v-html='icons.twitter')
-- | {{ $t('tweet') }}
-- a.fb-share-button.share-button(:href='facebookLink', target='_blank')
-- .social-icon.facebook.svg-icon(v-html='icons.facebook')
-- | {{ $t('share') }}
-- // @TODO: Still want this? .col-4
-- a.tumblr-share-button(:data-href='socialLevelLink', data-notes='none')
+diff --git a/website/client/src/components/achievements/achievementFooter.vue b/website/client/src/components/achievements/achievementFooter.vue
+index bf4a3a2580..f48f3b675b 100644
+--- a/website/client/src/components/achievements/achievementFooter.vue
++++ b/website/client/src/components/achievements/achievementFooter.vue
+@@ -4,36 +4,6 @@
+ style="margin-top:0"
+ ng-init="loadWidgets()"
+ >
+- <div class="container-fluid share-buttons">
+- <div class="row">
+- <div class="col-12 text-center">
+- <a
+- class="twitter-share-button share-button"
+- :href="twitterLink"
+- target="_blank"
+- >
+- <div
+- class="social-icon twitter svg-icon"
+- v-html="icons.twitter"
+- ></div>
+- {{ $t('tweet') }}
+- </a>
+- <a
+- class="fb-share-button share-button"
+- :href="facebookLink"
+- target="_blank"
+- >
+- <div
+- class="social-icon facebook svg-icon"
+- v-html="icons.facebook"
+- ></div>
+- {{ $t('share') }}
+- </a>
+- <!-- @TODO: Still want this?
+- .col-4a.tumblr-share-button(:data-href='socialLevelLink', data-notes='none')-->
+- </div>
+- </div>
+- </div>
+ </div>
</template>
- <style scoped>
-@@ -27,53 +16,4 @@
+@@ -51,54 +21,4 @@
text-align: center;
color: #fff;
}
@@ -2637,13 +2694,14 @@ index dd899a34b6..9b5328c7cb 100644
-
-<script>
-// @TODO:
--let BASE_URL = 'https://habitica.com';
--import twitter from 'assets/svg/twitter.svg';
--import facebook from 'assets/svg/facebook.svg';
+-import twitter from '@/assets/svg/twitter.svg';
+-import facebook from '@/assets/svg/facebook.svg';
+-
+-const BASE_URL = 'https://habitica.com';
-
-export default {
- data () {
-- let tweet = this.$t('achievementShare');
+- const tweet = this.$t('achievementShare');
-
- return {
- icons: Object.freeze({
@@ -2658,30 +2716,48 @@ index dd899a34b6..9b5328c7cb 100644
- },
-};
-</script>
-diff --git a/website/client/components/achievements/levelUp.vue b/website/client/components/achievements/levelUp.vue
-index 0f815deecf..cd47be7a04 100644
---- a/website/client/components/achievements/levelUp.vue
-+++ b/website/client/components/achievements/levelUp.vue
-@@ -12,18 +12,6 @@
- // @TODO: Keep this? .checkbox
- input(type='checkbox', v-model='user.preferences.suppressModals.levelUp', @change='changeLevelupSuppress()')
- label(style='display:inline-block') {{ $t('dontShowAgain') }}
--
-- .container-fluid.share-buttons
-- .row
-- .col-12.text-center
-- a.twitter-share-button.share-button(:href='twitterLink', target='_blank')
-- .social-icon.twitter.svg-icon(v-html='icons.twitter')
-- | {{ $t('tweet') }}
-- a.fb-share-button.share-button(:href='facebookLink', target='_blank')
-- .social-icon.facebook.svg-icon(v-html='icons.facebook')
-- | {{ $t('share') }}
-- // @TODO: Still want this? .col-4
-- a.tumblr-share-button(:data-href='socialLevelLink', data-notes='none')
+diff --git a/website/client/src/components/achievements/levelUp.vue b/website/client/src/components/achievements/levelUp.vue
+index aacaac9205..8193bf3605 100644
+--- a/website/client/src/components/achievements/levelUp.vue
++++ b/website/client/src/components/achievements/levelUp.vue
+@@ -27,36 +27,6 @@
+ label(style='display:inline-block') {{ $t('dontShowAgain') }}
+ -->
+ </div>
+- <div class="container-fluid share-buttons">
+- <div class="row">
+- <div class="col-12 text-center">
+- <a
+- class="twitter-share-button share-button"
+- :href="twitterLink"
+- target="_blank"
+- >
+- <div
+- class="social-icon twitter svg-icon"
+- v-html="icons.twitter"
+- ></div>
+- {{ $t('tweet') }}
+- </a>
+- <a
+- class="fb-share-button share-button"
+- :href="facebookLink"
+- target="_blank"
+- >
+- <div
+- class="social-icon facebook svg-icon"
+- v-html="icons.facebook"
+- ></div>
+- {{ $t('share') }}
+- </a>
+- </div>
+- <!-- @TODO: Still want this? .col-4a.tumblr
+- -share-button(:data-href='socialLevelLink', data-notes='none')-->
+- </div>
+- </div>
+ </b-modal>
</template>
- <style lang="scss">
-@@ -79,31 +67,6 @@
+@@ -113,31 +83,6 @@ label(style='display:inline-block') {{ $t('dontShowAgain') }}
text-align: center;
color: #fff;
}
@@ -2713,22 +2789,22 @@ index 0f815deecf..cd47be7a04 100644
}
</style>
-@@ -118,10 +81,6 @@ import Avatar from '../avatar';
- import { mapState } from 'client/libs/store';
- import {maxHealth} from '../../../common/script/index';
- import styleHelper from 'client/mixins/styleHelper';
--import twitter from 'assets/svg/twitter.svg';
--import facebook from 'assets/svg/facebook.svg';
+@@ -152,10 +97,6 @@ import Avatar from '../avatar';
+ import { mapState } from '@/libs/store';
+ import { MAX_HEALTH as maxHealth } from '@/../../common/script/constants';
+ import styleHelper from '@/mixins/styleHelper';
+-import twitter from '@/assets/svg/twitter.svg';
+-import facebook from '@/assets/svg/facebook.svg';
-
--let BASE_URL = 'https://habitica.com';
+-const BASE_URL = 'https://habitica.com';
export default {
- mixins: [styleHelper],
-@@ -129,18 +88,9 @@ export default {
- Avatar,
+ components: {
+@@ -163,18 +104,9 @@ export default {
},
+ mixins: [styleHelper],
data () {
-- let tweet = this.$t('levelUpShare');
+- const tweet = this.$t('levelUpShare');
return {
- icons: Object.freeze({
- twitter,
@@ -2742,82 +2818,146 @@ index 0f815deecf..cd47be7a04 100644
- facebookLink: `https://www.facebook.com/sharer/sharer.php?text=${tweet}&u=${BASE_URL}/social/level-up`,
};
},
- mounted () {
-diff --git a/website/client/components/achievements/wonChallenge.vue b/website/client/components/achievements/wonChallenge.vue
-index de65914ea7..ab38d55467 100644
---- a/website/client/components/achievements/wonChallenge.vue
-+++ b/website/client/components/achievements/wonChallenge.vue
-@@ -13,13 +13,6 @@
- p {{ $t('congratulations') }}
- br
- button.btn.btn-primary(@click='close()') {{ $t('hurray') }}
-- .modal-footer
-- .col-3
-- a.twitter-share-button(href='https://twitter.com/intent/tweet?text=#{tweet}&via=habitica&url=#{env.BASE_URL}/social/won-challenge&count=none') {{ $t('tweet') }}
-- .col-4(style='margin-left:.8em')
-- .fb-share-button(data-href='#{env.BASE_URL}/social/won-challenge', data-layout='button')
-- .col-4(style='margin-left:.8em')
-- a.tumblr-share-button(data-href='#{env.BASE_URL}/social/won-challenge', data-notes='none')
+ computed: {
+diff --git a/website/client/src/components/achievements/wonChallenge.vue b/website/client/src/components/achievements/wonChallenge.vue
+index 06c382e688..ac80752526 100644
+--- a/website/client/src/components/achievements/wonChallenge.vue
++++ b/website/client/src/components/achievements/wonChallenge.vue
+@@ -32,34 +32,6 @@
+ {{ $t('hurray') }}
+ </button>
+ </div>
+- <div class="modal-footer">
+- <div class="col-3">
+- <a
+- class="twitter-share-button"
+- href="https://twitter.com/intent/tweet?text=#{tweet}&via=habitica&url=#{env.BASE_URL}/social/won-challenge&count=none"
+- >{{ $t('tweet') }}</a>
+- </div>
+- <div
+- class="col-4"
+- style="margin-left:.8em"
+- >
+- <div
+- class="fb-share-button"
+- data-href="#{env.BASE_URL}/social/won-challenge"
+- data-layout="button"
+- ></div>
+- </div>
+- <div
+- class="col-4"
+- style="margin-left:.8em"
+- >
+- <a
+- class="tumblr-share-button"
+- data-href="#{env.BASE_URL}/social/won-challenge"
+- data-notes="none"
+- ></a>
+- </div>
+- </div>
+ </b-modal>
</template>
- <style scoped>
-@@ -51,12 +44,6 @@ export default {
- computed: {
- ...mapState({user: 'user.data'}),
+@@ -89,12 +61,6 @@ export default {
+ directives: {
+ markdown: markdownDirective,
},
- data () {
-- let tweet = this.$t('wonChallengeShare');
+- const tweet = this.$t('wonChallengeShare');
- return {
- tweet,
- };
- },
- methods: {
- close () {
- this.$root.$emit('bv::hide::modal', 'won-challenge');
-diff --git a/website/client/components/appFooter.vue b/website/client/components/appFooter.vue
-index 97bcf9b3da..8478089836 100644
---- a/website/client/components/appFooter.vue
-+++ b/website/client/components/appFooter.vue
-@@ -4,11 +4,6 @@
- //modify-inventory(v-if="isUserLoaded")
- footer.col-12.expanded
- .row
-- .col-12.col-md-2
-- h3
-- a(href='https://itunes.apple.com/us/app/habitica/id994882113?ls=1&mt=8', target='_blank') {{ $t('mobileIOS') }}
-- h3
-- a(href='https://play.google.com/store/apps/details?id=com.habitrpg.android.habitica', target='_blank') {{ $t('mobileAndroid') }}
- .col-12.col-md-2
- h3 {{ $t('footerCompany') }}
- ul
-@@ -41,10 +36,6 @@
- a(href='https://trello.com/c/odmhIqyW/440-read-first-table-of-contents', target='_blank') {{ $t('requestFeature') }}
- li(v-html='$t("communityExtensions")')
- li(v-html='$t("communityForum")')
-- li
-- a(href='https://www.facebook.com/Habitica', target='_blank') {{ $t('communityFacebook') }}
-- li
-- a(href='https://www.instagram.com/habitica', target='_blank') {{ $t('communityInstagram') }}
- .col-12.col-md-6
- .row
- .col-6
-@@ -56,15 +47,6 @@
- a(:href="getDataDisplayToolUrl", target='_blank') {{ $t('dataDisplayTool') }}
- li
- a(href='http://habitica.fandom.com/wiki/Guidance_for_Blacksmiths', target='_blank') {{ $t('guidanceForBlacksmiths') }}
-- .col-6.social
-- h3 {{ $t('footerSocial') }}
-- .icons
-- a.social-circle(href='https://twitter.com/habitica', target='_blank')
-- .social-icon.svg-icon(v-html='icons.twitter')
-- a.social-circle(href='https://www.instagram.com/habitica/', target='_blank')
-- .social-icon.svg-icon.instagram(v-html='icons.instagram')
-- a.social-circle(href='https://www.facebook.com/Habitica', target='_blank')
-- .social-icon.facebook.svg-icon(v-html='icons.facebook')
- .row
- .col-12.col-md-8 {{ $t('donateText3') }}
- .col-12.col-md-4
-@@ -138,51 +120,12 @@
+ computed: {
+ ...mapState({ user: 'user.data' }),
+ },
+diff --git a/website/client/src/components/appFooter.vue b/website/client/src/components/appFooter.vue
+index d6b8ac6435..3a4d0b63cf 100644
+--- a/website/client/src/components/appFooter.vue
++++ b/website/client/src/components/appFooter.vue
+@@ -4,20 +4,6 @@
+ <!--modify-inventory(v-if="isUserLoaded")-->
+ <footer class="col-12 expanded">
+ <div class="row">
+- <div class="col-12 col-md-2">
+- <h3>
+- <a
+- href="https://itunes.apple.com/us/app/habitica/id994882113?ls=1&mt=8"
+- target="_blank"
+- >{{ $t('mobileIOS') }}</a>
+- </h3>
+- <h3>
+- <a
+- href="https://play.google.com/store/apps/details?id=com.habitrpg.android.habitica"
+- target="_blank"
+- >{{ $t('mobileAndroid') }}</a>
+- </h3>
+- </div>
+ <div class="col-12 col-md-2">
+ <h3>{{ $t('footerCompany') }}</h3>
+ <ul>
+@@ -95,18 +81,6 @@
+ </li>
+ <li v-html="$t('communityExtensions')"></li>
+ <li v-html="$t('communityForum')"></li>
+- <li>
+- <a
+- href="https://www.facebook.com/Habitica"
+- target="_blank"
+- >{{ $t('communityFacebook') }}</a>
+- </li>
+- <li>
+- <a
+- href="https://www.instagram.com/habitica"
+- target="_blank"
+- >{{ $t('communityInstagram') }}</a>
+- </li>
+ </ul>
+ </div>
+ <div class="col-12 col-md-6">
+@@ -134,41 +108,6 @@
+ </li>
+ </ul>
+ </div>
+- <div class="col-6 social">
+- <h3>{{ $t('footerSocial') }}</h3>
+- <div class="icons">
+- <a
+- class="social-circle"
+- href="https://twitter.com/habitica"
+- target="_blank"
+- >
+- <div
+- class="social-icon svg-icon"
+- v-html="icons.twitter"
+- ></div>
+- </a>
+- <a
+- class="social-circle"
+- href="https://www.instagram.com/habitica/"
+- target="_blank"
+- >
+- <div
+- class="social-icon svg-icon instagram"
+- v-html="icons.instagram"
+- ></div>
+- </a>
+- <a
+- class="social-circle"
+- href="https://www.facebook.com/Habitica"
+- target="_blank"
+- >
+- <div
+- class="social-icon facebook svg-icon"
+- v-html="icons.facebook"
+- ></div>
+- </a>
+- </div>
+- </div>
+ </div>
+ <div class="row">
+ <div class="col-12 col-md-8">
+@@ -351,51 +290,12 @@
margin-bottom: .5em;
}
@@ -2869,7 +3009,7 @@ index 97bcf9b3da..8478089836 100644
.logo {
width: 24px;
height: 24px;
-@@ -234,11 +177,6 @@
+@@ -447,11 +347,6 @@
margin-top: .1em;
}
@@ -2881,28 +3021,26 @@ index 97bcf9b3da..8478089836 100644
footer {
&.expanded {
padding-left: 6em;
-@@ -263,31 +201,22 @@
+@@ -476,29 +371,17 @@
import axios from 'axios';
import moment from 'moment';
- import { mapState } from 'client/libs/store';
--import * as Analytics from 'client/libs/analytics';
+ import { mapState } from '@/libs/store';
+-import * as Analytics from '@/libs/analytics';
- import gryphon from 'assets/svg/gryphon.svg';
--import twitter from 'assets/svg/twitter.svg';
--import facebook from 'assets/svg/facebook.svg';
--import instagram from 'assets/svg/instagram.svg';
- import heart from 'assets/svg/heart.svg';
+ import gryphon from '@/assets/svg/gryphon.svg';
+-import twitter from '@/assets/svg/twitter.svg';
+-import facebook from '@/assets/svg/facebook.svg';
+-import instagram from '@/assets/svg/instagram.svg';
+ import heart from '@/assets/svg/heart.svg';
- import modifyInventory from './modifyInventory';
-import buyGemsModal from './payments/buyGemsModal';
-
+-
const IS_PRODUCTION = process.env.NODE_ENV === 'production'; // eslint-disable-line no-process-env
export default {
- components: {
- modifyInventory,
+- components: {
- buyGemsModal,
- },
+- },
data () {
return {
icons: Object.freeze({
@@ -2913,7 +3051,7 @@ index 97bcf9b3da..8478089836 100644
heart,
}),
debugMenuShown: false,
-@@ -388,12 +317,6 @@ export default {
+@@ -600,12 +483,6 @@ export default {
this.$root.$emit('bv::show::modal', 'modify-inventory');
},
donate () {
@@ -2923,30 +3061,59 @@ index 97bcf9b3da..8478089836 100644
- eventAction: 'click',
- eventLabel: 'Gems > Donate',
- });
- this.$root.$emit('bv::show::modal', 'buy-gems', {alreadyTracked: true});
+ this.$root.$emit('bv::show::modal', 'buy-gems', { alreadyTracked: true });
},
},
-diff --git a/website/client/components/auth/registerLoginReset.vue b/website/client/components/auth/registerLoginReset.vue
-index 7aa7f795c8..390ff25c3a 100644
---- a/website/client/components/auth/registerLoginReset.vue
-+++ b/website/client/components/auth/registerLoginReset.vue
-@@ -13,15 +13,6 @@
- .svg-icon.gryphon
- div
- .svg-icon.habitica-logo(v-html="icons.habiticaIcon")
-- .form-group.row.text-center
-- .col-12.col-md-6
-- .btn.btn-secondary.social-button(@click='socialAuth("facebook")')
-- .svg-icon.social-icon(v-html="icons.facebookIcon")
-- .text {{registering ? $t('signUpWithSocial', {social: 'Facebook'}) : $t('loginWithSocial', {social: 'Facebook'})}}
-- .col-12.col-md-6
-- .btn.btn-secondary.social-button(@click='socialAuth("google")')
-- .svg-icon.social-icon(v-html="icons.googleIcon")
-- .text {{registering ? $t('signUpWithSocial', {social: 'Google'}) : $t('loginWithSocial', {social: 'Google'})}}
- .form-group(v-if='registering')
- label(for='usernameInput', v-once) {{$t('username')}}
- input#usernameInput.form-control(type='text', :placeholder='$t("usernamePlaceholder")', v-model='username', :class='{"input-valid": usernameValid, "input-invalid": usernameInvalid}')
-@@ -209,26 +200,6 @@
+diff --git a/website/client/src/components/auth/registerLoginReset.vue b/website/client/src/components/auth/registerLoginReset.vue
+index e76d1a902d..c89a8b0631 100644
+--- a/website/client/src/components/auth/registerLoginReset.vue
++++ b/website/client/src/components/auth/registerLoginReset.vue
+@@ -20,44 +20,6 @@
+ ></div>
+ </div>
+ </div>
+- <div class="form-group row text-center">
+- <div class="col-12 col-md-6">
+- <div
+- class="btn btn-secondary social-button"
+- @click="socialAuth('facebook')"
+- >
+- <div
+- class="svg-icon social-icon"
+- v-html="icons.facebookIcon"
+- ></div>
+- <div
+- class="text"
+- >
+- {{ registering
+- ? $t('signUpWithSocial', {social: 'Facebook'})
+- : $t('loginWithSocial', {social: 'Facebook'}) }}
+- </div>
+- </div>
+- </div>
+- <div class="col-12 col-md-6">
+- <div
+- class="btn btn-secondary social-button"
+- @click="socialAuth('google')"
+- >
+- <div
+- class="svg-icon social-icon"
+- v-html="icons.googleIcon"
+- ></div>
+- <div
+- class="text"
+- >
+- {{ registering
+- ? $t('signUpWithSocial', {social: 'Google'})
+- : $t('loginWithSocial', {social: 'Google'}) }}
+- </div>
+- </div>
+- </div>
+- </div>
+ <div
+ v-if="registering"
+ class="form-group"
+@@ -434,26 +396,6 @@
font-size: 14px;
color: $white;
}
@@ -2973,7 +3140,7 @@ index 7aa7f795c8..390ff25c3a 100644
}
#top-background {
-@@ -293,14 +264,11 @@
+@@ -518,14 +460,11 @@
<script>
import axios from 'axios';
@@ -2981,14 +3148,14 @@ index 7aa7f795c8..390ff25c3a 100644
import debounce from 'lodash/debounce';
import isEmail from 'validator/lib/isEmail';
- import gryphon from 'assets/svg/gryphon.svg';
- import habiticaIcon from 'assets/svg/habitica-logo.svg';
--import facebookSquareIcon from 'assets/svg/facebook-square.svg';
--import googleIcon from 'assets/svg/google.svg';
+ import gryphon from '@/assets/svg/gryphon.svg';
+ import habiticaIcon from '@/assets/svg/habitica-logo.svg';
+-import facebookSquareIcon from '@/assets/svg/facebook-square.svg';
+-import googleIcon from '@/assets/svg/google.svg';
export default {
data () {
-@@ -320,8 +288,6 @@ export default {
+@@ -545,8 +484,6 @@ export default {
data.icons = Object.freeze({
gryphon,
habiticaIcon,
@@ -2997,8 +3164,8 @@ index 7aa7f795c8..390ff25c3a 100644
});
return data;
-@@ -364,13 +330,6 @@ export default {
- return !this.passwordConfirmValid;
+@@ -618,13 +555,6 @@ export default {
+ this.validateUsername(this.username);
},
},
- mounted () {
@@ -3008,11 +3175,11 @@ index 7aa7f795c8..390ff25c3a 100644
- google: process.env.GOOGLE_CLIENT_ID, // eslint-disable-line
- });
- },
- watch: {
- $route: {
- handler () {
-@@ -481,37 +440,6 @@ export default {
- // ALSO it's the only way to make sure language data is reloaded and correct for the logged in user
+ methods: {
+ // eslint-disable-next-line func-names
+ validateUsername: debounce(function (username) {
+@@ -709,38 +639,6 @@ export default {
+ // is reloaded and correct for the logged in user
window.location.href = redirectTo;
},
- // @TODO: Abstract hello in to action or lib
@@ -3022,7 +3189,7 @@ index 7aa7f795c8..390ff25c3a 100644
- } catch (e) {} // eslint-disable-line
-
- const redirectUrl = `${window.location.protocol}//${window.location.host}`;
-- let auth = await hello(network).login({
+- const auth = await hello(network).login({
- scope: 'email',
- // explicitly pass the redirect url or it might redirect to /home
- redirect_uri: redirectUrl, // eslint-disable-line camelcase
@@ -3043,63 +3210,65 @@ index 7aa7f795c8..390ff25c3a 100644
- // @TODO do not reload entire page
- // problem is that app.vue created hook should be called again
- // after user is logged in / just signed up
-- // ALSO it's the only way to make sure language data is reloaded and correct for the logged in user
+- // ALSO it's the only way to make sure language data
+- // is reloaded and correct for the logged in user
- window.location.href = redirectTo;
- },
handleSubmit () {
if (this.registering) {
this.register();
-diff --git a/website/client/components/challenges/challengeModal.vue b/website/client/components/challenges/challengeModal.vue
-index 103d9e4ca8..fdf5e83da0 100644
---- a/website/client/components/challenges/challengeModal.vue
-+++ b/website/client/components/challenges/challengeModal.vue
-@@ -54,8 +54,6 @@
- .row.footer-wrap
- .col-12.text-center.submit-button-wrapper
- .alert.alert-warning(v-if='insufficientGemsForTavernChallenge') You do not have enough gems to create a Tavern challenge
-- // @TODO if buy gems button is added, add analytics tracking to it
-- // see https://github.com/HabitRPG/habitica/blob/develop/website/views/options/social/challenges.jade#L134
- button.btn.btn-primary(v-if='creating && !cloning', @click='createChallenge()', :disabled='loading') {{$t('createChallengeAddTasks')}}
- button.btn.btn-primary(v-once, v-if='cloning', @click='createChallenge()', :disabled='loading') {{$t('createChallengeCloneTasks')}}
- button.btn.btn-primary(v-once, v-if='!creating && !cloning', @click='updateChallenge()') {{$t('updateChallenge')}}
-diff --git a/website/client/components/groups/createPartyModal.vue b/website/client/components/groups/createPartyModal.vue
-index 6e0ea2956a..21a5a75ef4 100644
---- a/website/client/components/groups/createPartyModal.vue
-+++ b/website/client/components/groups/createPartyModal.vue
-@@ -141,7 +141,6 @@ b-modal#create-party-modal(size='lg', hide-footer=true)
+diff --git a/website/client/src/components/challenges/challengeModal.vue b/website/client/src/components/challenges/challengeModal.vue
+index 7e1fe7b0fe..7977e1ab3c 100644
+--- a/website/client/src/components/challenges/challengeModal.vue
++++ b/website/client/src/components/challenges/challengeModal.vue
+@@ -158,8 +158,6 @@
+ >
+ You do not have enough gems to create a Tavern challenge
+ </div>
+- <!-- @TODO if buy gems button is added, add analytics tracking to it-->
+- <!-- see https://github.com/HabitRPG/habitica/blob/develop/website/views/options/social/challenges.jade#L134-->
+ <button
+ v-if="creating && !cloning"
+ class="btn btn-primary"
+diff --git a/website/client/src/components/groups/createPartyModal.vue b/website/client/src/components/groups/createPartyModal.vue
+index 8b00d4e06c..78f6bbc279 100644
+--- a/website/client/src/components/groups/createPartyModal.vue
++++ b/website/client/src/components/groups/createPartyModal.vue
+@@ -190,7 +190,6 @@
<script>
- import { mapState } from 'client/libs/store';
-- import * as Analytics from 'client/libs/analytics';
- import notifications from 'client/mixins/notifications';
-
- import copyIcon from 'assets/svg/copy.svg';
-@@ -167,11 +166,6 @@ b-modal#create-party-modal(size='lg', hide-footer=true)
- this.$store.state.party.data = party;
- this.user.party._id = party._id;
-
-- Analytics.updateUser({
-- partyID: party._id,
-- partySize: 1,
-- });
+ import { mapState } from '@/libs/store';
+-import * as Analytics from '@/libs/analytics';
+ import notifications from '@/mixins/notifications';
+
+ import copyIcon from '@/assets/svg/copy.svg';
+@@ -216,12 +215,6 @@ export default {
+ const party = await this.$store.dispatch('guilds:create', { group });
+ this.$store.state.party.data = party;
+ this.user.party._id = party._id;
-
- this.$root.$emit('bv::hide::modal', 'create-party-modal');
- this.$router.push('/party');
- },
-diff --git a/website/client/components/groups/group.vue b/website/client/components/groups/group.vue
-index 9416b5f3cd..2695b6fac5 100644
---- a/website/client/components/groups/group.vue
-+++ b/website/client/components/groups/group.vue
-@@ -262,7 +262,6 @@ import extend from 'lodash/extend';
- import groupUtilities from 'client/mixins/groupsUtilities';
- import styleHelper from 'client/mixins/styleHelper';
- import { mapState } from 'client/libs/store';
--import * as Analytics from 'client/libs/analytics';
- import membersModal from './membersModal';
+- Analytics.updateUser({
+- partyID: party._id,
+- partySize: 1,
+- });
+-
+ this.$root.$emit('bv::hide::modal', 'create-party-modal');
+ this.$router.push('/party');
+ },
+diff --git a/website/client/src/components/groups/group.vue b/website/client/src/components/groups/group.vue
+index b6d092827b..a437e99878 100644
+--- a/website/client/src/components/groups/group.vue
++++ b/website/client/src/components/groups/group.vue
+@@ -387,7 +387,6 @@ import extend from 'lodash/extend';
+ import groupUtilities from '@/mixins/groupsUtilities';
+ import styleHelper from '@/mixins/styleHelper';
+ import { mapState } from '@/libs/store';
+-import * as Analytics from '@/libs/analytics';
import startQuestModal from './startQuestModal';
import questDetailsModal from './questDetailsModal';
-@@ -484,13 +483,6 @@ export default {
- await this.$store.dispatch('guilds:join', {groupId: this.group._id, type: 'guild'});
+ import participantListModal from './participantListModal';
+@@ -590,13 +589,6 @@ export default {
+ await this.$store.dispatch('guilds:join', { groupId: this.group._id, type: 'guild' });
},
clickLeave () {
- Analytics.track({
@@ -3110,64 +3279,92 @@ index 9416b5f3cd..2695b6fac5 100644
- });
-
// @TODO: Get challenges and ask to keep or remove
- if (!confirm('Are you sure you want to leave?')) return;
- let keep = true;
-@@ -507,7 +499,6 @@ export default {
+ if (!window.confirm('Are you sure you want to leave?')) return;
+ const keep = true;
+@@ -613,7 +605,6 @@ export default {
if (this.isParty) {
data.type = 'party';
-- Analytics.updateUser({partySize: null, partyID: null});
+- Analytics.updateUser({ partySize: null, partyID: null });
this.$store.state.partyMembers = [];
}
-diff --git a/website/client/components/groups/groupPlan.vue b/website/client/components/groups/groupPlan.vue
-index 8d30345589..2561b2946b 100644
---- a/website/client/components/groups/groupPlan.vue
-+++ b/website/client/components/groups/groupPlan.vue
-@@ -46,13 +46,6 @@ div
- .number 3
- .name Each Individual Group Member
-
-- .box.payment-providers
-- h3 Choose your payment method
-- .payments-column
-- button.purchase.btn.btn-primary.payment-button.payment-item(@click='pay(PAYMENTS.STRIPE)')
-- .svg-icon.credit-card-icon(v-html="icons.creditCardIcon")
-- | {{ $t('card') }}
-- amazon-button.payment-item(:amazon-data="pay(PAYMENTS.AMAZON)")
- .container.col-6.offset-3.create-option(v-if='!upgradingGroup._id')
- .row
- h1.col-12.text-center.purple-header Create your Group today!
-@@ -95,14 +88,6 @@ div
- button.btn.btn-secondary.form-control(@click='createGroup()', :value="$t('createGroupPlan')")
- .form-group
- button.btn.btn-primary.btn-lg.btn-block(@click="createGroup()", :disabled="!newGroupIsReady") {{ $t('createGroupPlan') }}
-- .col-12(v-if='activePage === PAGES.PAY')
-- .text-center
-- h3 Choose your payment method
-- .payments-column.mx-auto
-- button.purchase.btn.btn-primary.payment-button.payment-item(@click='pay(PAYMENTS.STRIPE)')
-- .svg-icon.credit-card-icon(v-html="icons.creditCardIcon")
-- | {{ $t('card') }}
-- amazon-button.payment-item(:amazon-data="pay(PAYMENTS.AMAZON)")
+diff --git a/website/client/src/components/groups/groupPlan.vue b/website/client/src/components/groups/groupPlan.vue
+index 5729913e55..a4b1f41a86 100644
+--- a/website/client/src/components/groups/groupPlan.vue
++++ b/website/client/src/components/groups/groupPlan.vue
+@@ -91,25 +91,6 @@
+ </div>
+ </div>
+ </div>
+- <div class="box payment-providers">
+- <h3>Choose your payment method</h3>
+- <div class="payments-column">
+- <button
+- class="purchase btn btn-primary payment-button payment-item"
+- @click="pay(PAYMENTS.STRIPE)"
+- >
+- <div
+- class="svg-icon credit-card-icon"
+- v-html="icons.creditCardIcon"
+- ></div>
+- {{ $t('card') }}
+- </button>
+- <amazon-button
+- class="payment-item"
+- :amazon-data="pay(PAYMENTS.AMAZON)"
+- />
+- </div>
+- </div>
+ </div>
+ </div>
+ </div>
+@@ -248,30 +229,6 @@
+ </button>
+ </div>
+ </div>
+- <div
+- v-if="activePage === PAGES.PAY"
+- class="col-12"
+- >
+- <div class="text-center">
+- <h3>Choose your payment method</h3>
+- <div class="payments-column mx-auto">
+- <button
+- class="purchase btn btn-primary payment-button payment-item"
+- @click="pay(PAYMENTS.STRIPE)"
+- >
+- <div
+- class="svg-icon credit-card-icon"
+- v-html="icons.creditCardIcon"
+- ></div>
+- {{ $t('card') }}
+- </button>
+- <amazon-button
+- class="payment-item"
+- :amazon-data="pay(PAYMENTS.AMAZON)"
+- />
+- </div>
+- </div>
+- </div>
+ </b-modal>
+ </div>
</template>
-
- <style lang="scss" scoped>
-@@ -290,22 +275,13 @@ div
+@@ -461,22 +418,13 @@
</style>
<script>
-import paymentsMixin from '../../mixins/payments';
- import { mapState } from 'client/libs/store';
- import positiveIcon from 'assets/svg/positive.svg';
--import creditCardIcon from 'assets/svg/credit-card-icon.svg';
--import amazonButton from 'client/components/payments/amazonButton';
+ import { mapState } from '@/libs/store';
+ import positiveIcon from '@/assets/svg/positive.svg';
+-import creditCardIcon from '@/assets/svg/credit-card-icon.svg';
+-import amazonButton from '@/components/payments/amazonButton';
export default {
-- mixins: [paymentsMixin],
- components: {
- amazonButton,
- },
+- mixins: [paymentsMixin],
data () {
return {
- amazonPayments: {},
@@ -3176,7 +3373,7 @@ index 8d30345589..2561b2946b 100644
positiveIcon,
}),
PAGES: {
-@@ -313,10 +289,6 @@ export default {
+@@ -484,10 +432,6 @@ export default {
UPGRADE_GROUP: 'upgrade-group',
PAY: 'pay',
},
@@ -3187,35 +3384,38 @@ index 8d30345589..2561b2946b 100644
paymentMethod: '',
newGroup: {
type: 'guild',
-@@ -368,14 +340,6 @@ export default {
- } else {
+@@ -540,17 +484,6 @@ export default {
paymentData.groupToCreate = this.newGroup;
}
--
+
- this.paymentMethod = paymentMethod;
-- if (this.paymentMethod === this.PAYMENTS.STRIPE) {
-- this.showStripe(paymentData);
-- } else if (this.paymentMethod === this.PAYMENTS.AMAZON) {
+-
+- if (this.paymentMethod === this.PAYMENTS.AMAZON) {
- paymentData.type = 'subscription';
- return paymentData;
- }
+-
+- if (this.paymentMethod === this.PAYMENTS.STRIPE) {
+- this.showStripe(paymentData);
+- }
+-
+ return null;
},
},
- };
-diff --git a/website/client/components/groups/questDetailsModal.vue b/website/client/components/groups/questDetailsModal.vue
-index e025221025..4173eeda74 100644
---- a/website/client/components/groups/questDetailsModal.vue
-+++ b/website/client/components/groups/questDetailsModal.vue
-@@ -140,8 +140,6 @@ import quests from 'common/script/content/quests';
- import copyIcon from 'assets/svg/copy.svg';
- import greyBadgeIcon from 'assets/svg/grey-badge.svg';
- import qrCodeIcon from 'assets/svg/qrCode.svg';
--import facebookIcon from 'assets/svg/facebook.svg';
--import twitterIcon from 'assets/svg/twitter.svg';
- import starIcon from 'assets/svg/star.svg';
- import goldIcon from 'assets/svg/gold.svg';
- import difficultyStarIcon from 'assets/svg/difficulty-star.svg';
-@@ -162,8 +160,6 @@ export default {
+diff --git a/website/client/src/components/groups/questDetailsModal.vue b/website/client/src/components/groups/questDetailsModal.vue
+index c095ea5e55..7b225660b1 100644
+--- a/website/client/src/components/groups/questDetailsModal.vue
++++ b/website/client/src/components/groups/questDetailsModal.vue
+@@ -201,8 +201,6 @@ import * as quests from '@/../../common/script/content/quests';
+ import copyIcon from '@/assets/svg/copy.svg';
+ import greyBadgeIcon from '@/assets/svg/grey-badge.svg';
+ import qrCodeIcon from '@/assets/svg/qrCode.svg';
+-import facebookIcon from '@/assets/svg/facebook.svg';
+-import twitterIcon from '@/assets/svg/twitter.svg';
+ import starIcon from '@/assets/svg/star.svg';
+ import goldIcon from '@/assets/svg/gold.svg';
+ import difficultyStarIcon from '@/assets/svg/difficulty-star.svg';
+@@ -223,8 +221,6 @@ export default {
copy: copyIcon,
greyBadge: greyBadgeIcon,
qrCode: qrCodeIcon,
@@ -3224,27 +3424,27 @@ index e025221025..4173eeda74 100644
starIcon,
goldIcon,
difficultyStarIcon,
-diff --git a/website/client/components/groups/startQuestModal.vue b/website/client/components/groups/startQuestModal.vue
-index 9d13f2d0b3..97d18ff8f6 100644
---- a/website/client/components/groups/startQuestModal.vue
-+++ b/website/client/components/groups/startQuestModal.vue
-@@ -106,15 +106,12 @@
+diff --git a/website/client/src/components/groups/startQuestModal.vue b/website/client/src/components/groups/startQuestModal.vue
+index 340cac2aa3..f40227c318 100644
+--- a/website/client/src/components/groups/startQuestModal.vue
++++ b/website/client/src/components/groups/startQuestModal.vue
+@@ -151,15 +151,12 @@
<script>
- import { mapState } from 'client/libs/store';
--import * as Analytics from 'client/libs/analytics';
-
- import quests from 'common/script/content/quests';
-
- import copyIcon from 'assets/svg/copy.svg';
- import greyBadgeIcon from 'assets/svg/grey-badge.svg';
- import qrCodeIcon from 'assets/svg/qrCode.svg';
--import facebookIcon from 'assets/svg/facebook.svg';
--import twitterIcon from 'assets/svg/twitter.svg';
- import starIcon from 'assets/svg/star.svg';
- import goldIcon from 'assets/svg/gold.svg';
- import difficultyStarIcon from 'assets/svg/difficulty-star.svg';
-@@ -137,8 +134,6 @@ export default {
+ import { mapState } from '@/libs/store';
+-import * as Analytics from '@/libs/analytics';
+
+ import * as quests from '@/../../common/script/content/quests';
+
+ import copyIcon from '@/assets/svg/copy.svg';
+ import greyBadgeIcon from '@/assets/svg/grey-badge.svg';
+ import qrCodeIcon from '@/assets/svg/qrCode.svg';
+-import facebookIcon from '@/assets/svg/facebook.svg';
+-import twitterIcon from '@/assets/svg/twitter.svg';
+ import starIcon from '@/assets/svg/star.svg';
+ import goldIcon from '@/assets/svg/gold.svg';
+ import difficultyStarIcon from '@/assets/svg/difficulty-star.svg';
+@@ -182,8 +179,6 @@ export default {
copy: copyIcon,
greyBadge: greyBadgeIcon,
qrCode: qrCodeIcon,
@@ -3253,7 +3453,7 @@ index 9d13f2d0b3..97d18ff8f6 100644
starIcon,
goldIcon,
difficultyStarIcon,
-@@ -174,11 +169,6 @@ export default {
+@@ -219,11 +214,6 @@ export default {
async questInit () {
this.loading = true;
@@ -3262,38 +3462,38 @@ index 9d13f2d0b3..97d18ff8f6 100644
- partySize: this.group.memberCount,
- });
-
- let groupId = this.group._id || this.user.party._id;
+ const groupId = this.group._id || this.user.party._id;
const key = this.selectedQuest;
-diff --git a/website/client/components/header/menu.vue b/website/client/components/header/menu.vue
-index a6c2e33a72..fcb6aba088 100644
---- a/website/client/components/header/menu.vue
-+++ b/website/client/components/header/menu.vue
-@@ -4,7 +4,6 @@ div
- creator-intro
- profileModal
- report-flag-modal
-- send-gems-modal
- b-navbar.topbar.navbar-inverse.static-top(toggleable="lg", type="dark", :class="navbarZIndexClass")
- b-navbar-brand.brand(aria-label="Habitica")
- .logo.svg-icon.d-none.d-xl-block(v-html="icons.logo")
-@@ -393,7 +392,6 @@ div
+diff --git a/website/client/src/components/header/menu.vue b/website/client/src/components/header/menu.vue
+index c2b55381c2..e8dbc3a177 100644
+--- a/website/client/src/components/header/menu.vue
++++ b/website/client/src/components/header/menu.vue
+@@ -4,7 +4,6 @@
+ <creator-intro />
+ <profileModal />
+ <report-flag-modal />
+- <send-gems-modal />
+ <b-navbar
+ class="topbar navbar-inverse static-top"
+ toggleable="lg"
+@@ -710,7 +709,6 @@
<script>
- import { mapState, mapGetters } from 'client/libs/store';
--import * as Analytics from 'client/libs/analytics';
- import { goToModForm } from 'client/libs/modform';
+ import { mapState, mapGetters } from '@/libs/store';
+-import * as Analytics from '@/libs/analytics';
+ import { goToModForm } from '@/libs/modform';
- import gemIcon from 'assets/svg/gem.svg';
-@@ -408,7 +406,6 @@ import InboxModal from '../userMenu/inbox.vue';
+ import gemIcon from '@/assets/svg/gem.svg';
+@@ -725,7 +723,6 @@ import InboxModal from '../userMenu/inbox.vue';
import notificationMenu from './notificationsDropdown';
import profileModal from '../userMenu/profileModal';
import reportFlagModal from '../chat/reportFlagModal';
--import sendGemsModal from 'client/components/payments/sendGemsModal';
- import sync from 'client/mixins/sync';
+-import sendGemsModal from '@/components/payments/sendGemsModal';
+ import sync from '@/mixins/sync';
import userDropdown from './userDropdown';
-@@ -420,7 +417,6 @@ export default {
+@@ -737,7 +734,6 @@ export default {
notificationMenu,
profileModal,
reportFlagModal,
@@ -3301,7 +3501,7 @@ index a6c2e33a72..fcb6aba088 100644
userDropdown,
},
mixins: [sync],
-@@ -480,14 +476,6 @@ export default {
+@@ -797,14 +793,6 @@ export default {
},
showBuyGemsModal (startingPage) {
this.$store.state.gemModalOptions.startingPage = startingPage;
@@ -3313,22 +3513,22 @@ index a6c2e33a72..fcb6aba088 100644
- eventLabel: 'Gems > Toolbar',
- });
-
- this.$root.$emit('bv::show::modal', 'buy-gems', {alreadyTracked: true});
+ this.$root.$emit('bv::show::modal', 'buy-gems', { alreadyTracked: true });
},
dropdownDesktop (hover) {
-diff --git a/website/client/components/header/userDropdown.vue b/website/client/components/header/userDropdown.vue
-index 6fe67f63f9..72019f8ddf 100644
---- a/website/client/components/header/userDropdown.vue
-+++ b/website/client/components/header/userDropdown.vue
-@@ -67,7 +67,6 @@ menu-dropdown.item-user(:right="true")
-
+diff --git a/website/client/src/components/header/userDropdown.vue b/website/client/src/components/header/userDropdown.vue
+index 1809b8c2ab..c1ab280fec 100644
+--- a/website/client/src/components/header/userDropdown.vue
++++ b/website/client/src/components/header/userDropdown.vue
+@@ -135,7 +135,6 @@
<script>
- import { mapState } from 'client/libs/store';
--import * as Analytics from 'client/libs/analytics';
- import userIcon from 'assets/svg/user.svg';
- import MenuDropdown from '../ui/customMenuDropdown';
import axios from 'axios';
-@@ -106,14 +105,6 @@ export default {
+ import { mapState } from '@/libs/store';
+-import * as Analytics from '@/libs/analytics';
+ import userIcon from '@/assets/svg/user.svg';
+ import MenuDropdown from '../ui/customMenuDropdown';
+ import markPMSRead from '@/../../common/script/ops/markPMSRead';
+@@ -173,14 +172,6 @@ export default {
},
showBuyGemsModal (startingPage) {
this.$store.state.gemModalOptions.startingPage = startingPage;
@@ -3340,92 +3540,126 @@ index 6fe67f63f9..72019f8ddf 100644
- eventLabel: 'Gems > User Dropdown',
- });
-
- this.$root.$emit('bv::show::modal', 'buy-gems', {alreadyTracked: true});
+ this.$root.$emit('bv::show::modal', 'buy-gems', { alreadyTracked: true });
},
logout () {
-diff --git a/website/client/components/settings/deleteModal.vue b/website/client/components/settings/deleteModal.vue
-index 34838b0504..a74c52e6ee 100644
---- a/website/client/components/settings/deleteModal.vue
-+++ b/website/client/components/settings/deleteModal.vue
-@@ -3,7 +3,6 @@
- .modal-body
- br
- strong(v-if='user.auth.local.email') {{ $t('deleteLocalAccountText') }}
-- strong(v-if='!user.auth.local.email') {{ $t('deleteSocialAccountText', {magicWord: 'DELETE'}) }}
- .row.mt-3
- .col-6
- input.form-control(type='password', v-model='password')
-diff --git a/website/client/components/settings/notifications.vue b/website/client/components/settings/notifications.vue
-index dfc6dfb964..bfb5996089 100644
---- a/website/client/components/settings/notifications.vue
-+++ b/website/client/components/settings/notifications.vue
-@@ -3,14 +3,6 @@
- .col-12
- h1 {{ $t('notifications') }}
- .col-12
-- .checkbox
-- label
-- input(type='checkbox', v-model='user.preferences.pushNotifications.unsubscribeFromAll',
-- @change='set("pushNotifications", "unsubscribeFromAll")')
-- span {{ $t('unsubscribeAllPush') }}
--
-- br
--
- .checkbox
- label
- input(type='checkbox', v-model='user.preferences.emailNotifications.unsubscribeFromAll',
-@@ -24,17 +16,12 @@
- td
- th
- span {{ $t('email') }}
-- th
-- span {{ $t('push') }}
- tr(v-for='notification in notificationsIds')
- td
- span {{ $t(notification) }}
- td
- input(type='checkbox', v-model='user.preferences.emailNotifications[notification]',
- @change='set("emailNotifications", notification)')
-- td(v-if="onlyEmailsIds.indexOf(notification) === -1")
-- input(type='checkbox', v-model='user.preferences.pushNotifications[notification]',
-- @change='set("pushNotifications", notification)')
- hr
- </template>
-
-diff --git a/website/client/components/settings/site.vue b/website/client/components/settings/site.vue
-index 4f6d75d1f8..0fefae00d2 100644
---- a/website/client/components/settings/site.vue
-+++ b/website/client/components/settings/site.vue
-@@ -111,12 +111,6 @@
- h2 {{ $t('registration') }}
- .panel-body
- div
-- ul.list-inline
-- li(v-for='network in SOCIAL_AUTH_NETWORKS')
-- button.btn.btn-primary.mb-2(v-if='!user.auth[network.key].id', @click='socialAuth(network.key, user)') {{ $t('registerWithSocial', {network: network.name}) }}
-- button.btn.btn-primary.mb-2(disabled='disabled', v-if='!hasBackupAuthOption(network.key) && user.auth[network.key].id') {{ $t('registeredWithSocial', {network: network.name}) }}
-- button.btn.btn-danger(@click='deleteSocialAuth(network)', v-if='hasBackupAuthOption(network.key) && user.auth[network.key].id') {{ $t('detachSocial', {network: network.name}) }}
-- hr
- div(v-if='!user.auth.local.email')
- p {{ $t('addLocalAuth') }}
- .form(name='localAuth', novalidate)
-@@ -206,7 +200,6 @@
+diff --git a/website/client/src/components/settings/deleteModal.vue b/website/client/src/components/settings/deleteModal.vue
+index 1d21281fdd..03d886776a 100644
+--- a/website/client/src/components/settings/deleteModal.vue
++++ b/website/client/src/components/settings/deleteModal.vue
+@@ -8,9 +8,6 @@
+ <div class="modal-body">
+ <br>
+ <strong v-if="user.auth.local.email">{{ $t('deleteLocalAccountText') }}</strong>
+- <strong
+- v-if="!user.auth.local.email"
+- >{{ $t('deleteSocialAccountText', {magicWord: 'DELETE'}) }}</strong>
+ <div class="row mt-3">
+ <div class="col-6">
+ <input
+diff --git a/website/client/src/components/settings/notifications.vue b/website/client/src/components/settings/notifications.vue
+index 29017b4899..25de83aa0c 100644
+--- a/website/client/src/components/settings/notifications.vue
++++ b/website/client/src/components/settings/notifications.vue
+@@ -4,17 +4,6 @@
+ <h1>{{ $t('notifications') }}</h1>
+ </div>
+ <div class="col-12">
+- <div class="checkbox">
+- <label>
+- <input
+- v-model="user.preferences.pushNotifications.unsubscribeFromAll"
+- type="checkbox"
+- @change="set('pushNotifications', 'unsubscribeFromAll')"
+- >
+- <span>{{ $t('unsubscribeAllPush') }}</span>
+- </label>
+- </div>
+- <br>
+ <div class="checkbox">
+ <label>
+ <input
+@@ -34,9 +23,6 @@
+ <th>
+ <span>{{ $t('email') }}</span>
+ </th>
+- <th>
+- <span>{{ $t('push') }}</span>
+- </th>
+ </tr>
+ <tr
+ v-for="notification in notificationsIds"
+@@ -51,13 +37,6 @@
+ type="checkbox"
+ @change="set('emailNotifications', notification)"
+ >
+- </td>
+- <td v-if="onlyEmailsIds.indexOf(notification) === -1">
+- <input
+- v-model="user.preferences.pushNotifications[notification]"
+- type="checkbox"
+- @change="set('pushNotifications', notification)"
+- >
+ <hr>
+ </td>
+ </tr>
+diff --git a/website/client/src/components/settings/site.vue b/website/client/src/components/settings/site.vue
+index b63f964f31..2c96a9272f 100644
+--- a/website/client/src/components/settings/site.vue
++++ b/website/client/src/components/settings/site.vue
+@@ -255,35 +255,6 @@
+ <h2>{{ $t('registration') }}</h2>
+ <div class="panel-body">
+ <div>
+- <ul class="list-inline">
+- <li
+- v-for="network in SOCIAL_AUTH_NETWORKS"
+- :key="network.key"
+- >
+- <button
+- v-if="!user.auth[network.key].id"
+- class="btn btn-primary mb-2"
+- @click="socialAuth(network.key, user)"
+- >
+- {{ $t('registerWithSocial', {network: network.name}) }}
+- </button>
+- <button
+- v-if="!hasBackupAuthOption(network.key) && user.auth[network.key].id"
+- class="btn btn-primary mb-2"
+- disabled="disabled"
+- >
+- {{ $t('registeredWithSocial', {network: network.name}) }}
+- </button>
+- <button
+- v-if="hasBackupAuthOption(network.key) && user.auth[network.key].id"
+- class="btn btn-danger"
+- @click="deleteSocialAuth(network)"
+- >
+- {{ $t('detachSocial', {network: network.name}) }}
+- </button>
+- </li>
+- </ul>
+- <hr>
+ <div v-if="!user.auth.local.email">
+ <p>{{ $t('addLocalAuth') }}</p>
+ <div
+@@ -549,7 +520,6 @@
</style>
<script>
-import hello from 'hellojs';
import moment from 'moment';
import axios from 'axios';
- import { mapState } from 'client/libs/store';
-@@ -214,7 +207,6 @@ import debounce from 'lodash/debounce';
+ import debounce from 'lodash/debounce';
+@@ -557,7 +527,6 @@ import { mapState } from '@/libs/store';
import restoreModal from './restoreModal';
import resetModal from './resetModal';
import deleteModal from './deleteModal';
--import { SUPPORTED_SOCIAL_NETWORKS } from '../../../common/script/constants';
- import changeClass from '../../../common/script/ops/changeClass';
+-import { SUPPORTED_SOCIAL_NETWORKS } from '@/../../common/script/constants';
+ import changeClass from '@/../../common/script/ops/changeClass';
import notificationsMixin from '../../mixins/notifications';
import sounds from '../../libs/sounds';
-@@ -241,7 +233,6 @@ export default {
+@@ -584,7 +553,6 @@ export default {
}
return {
@@ -3433,15 +3667,15 @@ index 4f6d75d1f8..0fefae00d2 100644
party: {},
// Made available by the server as a script
availableFormats: ['MM/dd/yyyy', 'dd/MM/yyyy', 'yyyy/MM/dd'],
-@@ -262,7 +253,6 @@ export default {
- };
+@@ -675,7 +643,6 @@ export default {
+ },
},
mounted () {
- this.SOCIAL_AUTH_NETWORKS = SUPPORTED_SOCIAL_NETWORKS;
// @TODO: We may need to request the party here
this.party = this.$store.state.party;
this.newDayStart = this.user.preferences.dayStart;
-@@ -271,12 +261,6 @@ export default {
+@@ -684,12 +651,6 @@ export default {
this.emailUpdates.newEmail = this.user.auth.local.email || null;
this.localAuth.username = this.user.auth.local.username || null;
this.soundIndex = 0;
@@ -3454,7 +3688,7 @@ index 4f6d75d1f8..0fefae00d2 100644
const focusID = this.$route.query.focus;
if (focusID !== undefined && focusID !== null) {
-@@ -415,19 +399,6 @@ export default {
+@@ -758,21 +719,6 @@ export default {
showBailey () {
this.$root.$emit('bv::show::modal', 'new-stuff');
},
@@ -3463,27 +3697,29 @@ index 4f6d75d1f8..0fefae00d2 100644
- return true;
- }
-
-- return find(this.SOCIAL_AUTH_NETWORKS, (network) => {
+- return this.SOCIAL_AUTH_NETWORKS.find(network => {
- if (network.key !== networkKeyToCheck) {
-- if (this.user.auth.hasOwnProperty(network.key)) {
-- return this.user.auth[network.key].id;
+- if (this.user.auth[network.key]) {
+- return !!this.user.auth[network.key].id;
- }
- }
+-
+- return false;
- });
- },
calculateNextCron () {
- let nextCron = moment().hours(this.newDayStart).minutes(0).seconds(0).milliseconds(0);
-
-@@ -484,19 +455,6 @@ export default {
+ let nextCron = moment().hours(this.newDayStart).minutes(0).seconds(0)
+ .milliseconds(0);
+@@ -830,19 +776,6 @@ export default {
openDeleteModal () {
this.$root.$emit('bv::show::modal', 'delete');
},
- async deleteSocialAuth (network) {
- await axios.delete(`/api/v4/user/auth/social/${network.key}`);
-- this.text(this.$t('detachedSocial', {network: network.name}));
+- this.text(this.$t('detachedSocial', { network: network.name }));
- },
- async socialAuth (network) {
-- let auth = await hello(network).login({scope: 'email'});
+- const auth = await hello(network).login({ scope: 'email' });
-
- await this.$store.dispatch('auth:socialAuth', {
- auth,
@@ -3492,64 +3728,101 @@ index 4f6d75d1f8..0fefae00d2 100644
- window.location.href = '/';
- },
async changeClassForUser (confirmationNeeded) {
- if (confirmationNeeded && !confirm(this.$t('changeClassConfirmCost'))) return;
+ if (confirmationNeeded && !window.confirm(this.$t('changeClassConfirmCost'))) return;
try {
-diff --git a/website/client/components/settings/subscription.vue b/website/client/components/settings/subscription.vue
-index 80023627c8..eea2bc36ad 100644
---- a/website/client/components/settings/subscription.vue
-+++ b/website/client/components/settings/subscription.vue
-@@ -36,9 +36,6 @@
- h4 {{ $t('subscribed') }}
- p(v-if='hasPlan && !hasGroupPlan') {{ $t('purchasedPlanId', purchasedPlanIdInfo) }}
- p(v-if='hasGroupPlan') {{ $t('youHaveGroupPlan') }}
-- tr(v-if='user.purchased.plan.extraMonths'): td
-- span.glyphicon.glyphicon-credit-card
-- | &nbsp; {{ $t('purchasedPlanExtraMonths', purchasedPlanExtraMonthsDetails) }}
- tr(v-if='hasConsecutiveSubscription'): td
- span.glyphicon.glyphicon-forward
- | &nbsp; {{ $t('consecutiveSubscription') }}
-@@ -67,21 +64,9 @@
- button.btn.btn-primary(type='button', @click='applyCoupon(subscription.coupon)') {{ $t("apply") }}
-
- div(v-if='hasSubscription')
-- .btn.btn-primary(v-if='canEditCardDetails', @click='showStripeEdit()') {{ $t('subUpdateCard') }}
- .btn.btn-sm.btn-danger(v-if='canCancelSubscription && !loading', @click='cancelSubscriptionConfirm()') {{ $t('cancelSub') }}
- small(v-if='!canCancelSubscription && !hasCanceledSubscription', v-html='getCancelSubInfo()')
-
-- .subscribe-pay(v-if='!hasSubscription || hasCanceledSubscription')
-- h3 {{ $t('subscribeUsing') }}
-- .payments-column
-- button.purchase.btn.btn-primary.payment-button.payment-item(@click='showStripe({subscription:subscription.key, coupon:subscription.coupon})', :disabled='!subscription.key')
-- .svg-icon.credit-card-icon(v-html="icons.creditCardIcon")
-- | {{ $t('card') }}
-- button.btn.payment-item.paypal-checkout.payment-button(@click="openPaypal(paypalPurchaseLink, 'subscription')", :disabled='!subscription.key')
-- | &nbsp;
-- img(src='~assets/images/paypal-checkout.png', :alt="$t('paypal')")
-- | &nbsp;
-- amazon-button.payment-item(:amazon-data="{type: 'subscription', subscription: this.subscription.key, coupon: this.subscription.coupon}")
- .row
- .col-6
- h2(v-once) {{ $t('giftSubscription') }}
-@@ -111,17 +96,10 @@ import { mapState } from 'client/libs/store';
-
- import subscriptionBlocks from '../../../common/script/content/subscriptionBlocks';
- import planGemLimits from '../../../common/script/libs/planGemLimits';
+diff --git a/website/client/src/components/settings/subscription.vue b/website/client/src/components/settings/subscription.vue
+index 0938bff3b8..7e85bcbc46 100644
+--- a/website/client/src/components/settings/subscription.vue
++++ b/website/client/src/components/settings/subscription.vue
+@@ -92,12 +92,6 @@
+ </p>
+ </td>
+ </tr>
+- <tr v-if="user.purchased.plan.extraMonths">
+- <td>
+- <span class="glyphicon glyphicon-credit-card"></span>
+- &nbsp; {{ $t('purchasedPlanExtraMonths', purchasedPlanExtraMonthsDetails) }}
+- </td>
+- </tr>
+ <tr v-if="hasConsecutiveSubscription">
+ <td>
+ <span class="glyphicon glyphicon-forward"></span>
+@@ -161,13 +155,6 @@
+ </div>
+ </div>
+ <div v-if="hasSubscription">
+- <div
+- v-if="canEditCardDetails"
+- class="btn btn-primary"
+- @click="showStripeEdit()"
+- >
+- {{ $t('subUpdateCard') }}
+- </div>
+ <div
+ v-if="canCancelSubscription && !loading"
+ class="btn btn-sm btn-danger"
+@@ -180,41 +167,6 @@
+ v-html="getCancelSubInfo()"
+ ></small>
+ </div>
+- <div
+- v-if="!hasSubscription || hasCanceledSubscription"
+- class="subscribe-pay"
+- >
+- <h3>{{ $t('subscribeUsing') }}</h3>
+- <div class="payments-column">
+- <button
+- class="purchase btn btn-primary payment-button payment-item"
+- :disabled="!subscription.key"
+- @click="showStripe({subscription:subscription.key, coupon:subscription.coupon})"
+- >
+- <div
+- class="svg-icon credit-card-icon"
+- v-html="icons.creditCardIcon"
+- ></div>
+- {{ $t('card') }}
+- </button>
+- <button
+- class="btn payment-item paypal-checkout payment-button"
+- :disabled="!subscription.key"
+- @click="openPaypal(paypalPurchaseLink, 'subscription')"
+- >
+- &nbsp;
+- <img
+- src="~@/assets/images/paypal-checkout.png"
+- :alt="$t('paypal')"
+- >&nbsp;
+- </button>
+- <amazon-button
+- class="payment-item"
+- :amazon-data="{
+- type: 'subscription', subscription: subscription.key, coupon: subscription.coupon}"
+- />
+- </div>
+- </div>
+ </div>
+ </div>
+ <div class="row">
+@@ -260,17 +212,10 @@ import { mapState } from '@/libs/store';
+
+ import subscriptionBlocks from '@/../../common/script/content/subscriptionBlocks';
+ import planGemLimits from '@/../../common/script/libs/planGemLimits';
-import paymentsMixin from '../../mixins/payments';
import notificationsMixin from '../../mixins/notifications';
--import amazonButton from 'client/components/payments/amazonButton';
--import creditCardIcon from 'assets/svg/credit-card-icon.svg';
+-import amazonButton from '@/components/payments/amazonButton';
+-import creditCardIcon from '@/assets/svg/credit-card-icon.svg';
-
export default {
-- mixins: [paymentsMixin, notificationsMixin],
- components: {
- amazonButton,
- },
+- mixins: [paymentsMixin, notificationsMixin],
+ mixins: [notificationsMixin],
data () {
return {
loading: false,
-@@ -132,19 +110,9 @@ export default {
+@@ -281,19 +226,9 @@ export default {
subscription: {
key: 'basic_earned',
},
@@ -3569,28 +3842,30 @@ index 80023627c8..eea2bc36ad 100644
};
},
computed: {
-@@ -179,10 +147,7 @@ export default {
+@@ -325,10 +260,7 @@ export default {
return subscriptionBlocks;
},
canEditCardDetails () {
- return Boolean(
-- !this.hasCanceledSubscription &&
-- this.user.purchased.plan.paymentMethod === this.paymentMethods.STRIPE
+- !this.hasCanceledSubscription
+- && this.user.purchased.plan.paymentMethod === this.paymentMethods.STRIPE,
- );
+ return Boolean(!this.hasCanceledSubscription);
},
hasSubscription () {
return Boolean(this.user.purchased.plan.customerId);
-@@ -236,8 +201,6 @@ export default {
+@@ -382,22 +314,12 @@ export default {
+ };
},
canCancelSubscription () {
- return (
-- this.user.purchased.plan.paymentMethod !== this.paymentMethods.GOOGLE &&
-- this.user.purchased.plan.paymentMethod !== this.paymentMethods.APPLE &&
- !this.hasCanceledSubscription &&
- !this.hasGroupPlan
- );
-@@ -245,12 +208,7 @@ export default {
+- return (
+- this.user.purchased.plan.paymentMethod !== this.paymentMethods.GOOGLE
+- && this.user.purchased.plan.paymentMethod !== this.paymentMethods.APPLE
+- && !this.hasCanceledSubscription
+- && !this.hasGroupPlan
+- );
++ return !this.hasCanceledSubscription && !this.hasGroupPlan;
+ },
},
methods: {
async applyCoupon (coupon) {
@@ -3604,71 +3879,90 @@ index 80023627c8..eea2bc36ad 100644
},
getCancelSubInfo () {
let payMethod = this.user.purchased.plan.paymentMethod || '';
-diff --git a/website/client/components/shops/buyModal.vue b/website/client/components/shops/buyModal.vue
-index a54b33deab..2a230e04b3 100644
---- a/website/client/components/shops/buyModal.vue
-+++ b/website/client/components/shops/buyModal.vue
-@@ -274,7 +274,6 @@
- </style>
-
- <script>
-- import * as Analytics from 'client/libs/analytics';
- import spellsMixin from 'client/mixins/spells';
- import planGemLimits from 'common/script/libs/planGemLimits';
- import numberInvalid from 'client/mixins/numberInvalid';
-@@ -444,14 +443,6 @@
- }
- },
- purchaseGems () {
-- if (this.item.key === 'rebirth_orb') {
-- Analytics.track({
-- hitType: 'event',
-- eventCategory: 'button',
-- eventAction: 'click',
-- eventLabel: 'Gems > Rebirth',
-- });
-- }
- this.$root.$emit('bv::show::modal', 'buy-gems');
- },
- togglePinned () {
-diff --git a/website/client/components/static/app.vue b/website/client/components/static/app.vue
-index cfcf1fa02a..4dd4105b54 100644
---- a/website/client/components/static/app.vue
-+++ b/website/client/components/static/app.vue
-@@ -1,11 +1,3 @@
- <template lang="pug">
- .container-fluid.text-center
-- .row
-- .col-md-6.offset-3
-- h1 {{ $t('checkOutMobileApps') }}
-- .promo_habitica(style='border-radius:25px;margin:auto;margin-bottom:30px')
--
-- a(href='https://play.google.com/store/apps/details?id=com.habitrpg.android.habitica&utm_source=global_co&utm_medium=prtnr&utm_content=Mar2515&utm_campaign=PartBadge&pcampaignid=MKT-AC-global-none-all-co-pr-py-PartBadges-Oct1515-1&utm_source=global_co&utm_medium=prtnr&utm_content=Mar2515&utm_campaign=PartBadge&pcampaignid=MKT-AC-global-none-all-co-pr-py-PartBadges-Oct1515-1')
-- img(alt='Get it on Google Play', src='https://play.google.com/intl/en_us/badges/images/apps/en-play-badge.png', style='width:139px;height:45px;image-rendering:auto;vertical-align:top')
-- a(href='https://geo.itunes.apple.com/us/app/habitica/id994882113?mt=8', style='display:inline-block;overflow:hidden;background:url(http://linkmaker.itunes.apple.com/images/badges/en-us/badge_appstore-lrg.svg#svgView) no-repeat;background-size:100%;width:152px;height:45px;margin-left:20px;image-rendering:auto')
+diff --git a/website/client/src/components/shops/buyModal.vue b/website/client/src/components/shops/buyModal.vue
+index f5ec03c197..ee84a93ed0 100644
+--- a/website/client/src/components/shops/buyModal.vue
++++ b/website/client/src/components/shops/buyModal.vue
+@@ -364,7 +364,6 @@
+ import keys from 'lodash/keys';
+ import reduce from 'lodash/reduce';
+ import moment from 'moment';
+-import * as Analytics from '@/libs/analytics';
+ import spellsMixin from '@/mixins/spells';
+ import planGemLimits from '@/../../common/script/libs/planGemLimits';
+ import numberInvalid from '@/mixins/numberInvalid';
+@@ -555,14 +554,6 @@ export default {
+ }
+ },
+ purchaseGems () {
+- if (this.item.key === 'rebirth_orb') {
+- Analytics.track({
+- hitType: 'event',
+- eventCategory: 'button',
+- eventAction: 'click',
+- eventLabel: 'Gems > Rebirth',
+- });
+- }
+ this.$root.$emit('bv::show::modal', 'buy-gems');
+ },
+ togglePinned () {
+diff --git a/website/client/src/components/static/app.vue b/website/client/src/components/static/app.vue
+index 5997b32717..d4d10292c5 100644
+--- a/website/client/src/components/static/app.vue
++++ b/website/client/src/components/static/app.vue
+@@ -1,26 +1,4 @@
+ <template>
+ <div class="container-fluid text-center">
+- <div class="row">
+- <div class="col-md-6 offset-3">
+- <h1>{{ $t('checkOutMobileApps') }}</h1>
+- <div
+- class="promo_habitica"
+- style="border-radius:25px;margin:auto;margin-bottom:30px"
+- ></div>
+- <a
+- href="https://play.google.com/store/apps/details?id=com.habitrpg.android.habitica&utm_source=global_co&utm_medium=prtnr&utm_content=Mar2515&utm_campaign=PartBadge&pcampaignid=MKT-AC-global-none-all-co-pr-py-PartBadges-Oct1515-1&utm_source=global_co&utm_medium=prtnr&utm_content=Mar2515&utm_campaign=PartBadge&pcampaignid=MKT-AC-global-none-all-co-pr-py-PartBadges-Oct1515-1"
+- >
+- <img
+- alt="Get it on Google Play"
+- src="https://play.google.com/intl/en_us/badges/images/apps/en-play-badge.png"
+- style="width:139px;height:45px;image-rendering:auto;vertical-align:top"
+- >
+- </a>
+- <a
+- href="https://geo.itunes.apple.com/us/app/habitica/id994882113?mt=8"
+- style="display:inline-block;overflow:hidden;background:url(http://linkmaker.itunes.apple.com/images/badges/en-us/badge_appstore-lrg.svg#svgView) no-repeat;background-size:100%;width:152px;height:45px;margin-left:20px;image-rendering:auto"
+- ></a>
+- </div>
+- </div>
+ </div>
</template>
-diff --git a/website/client/components/static/header.vue b/website/client/components/static/header.vue
-index 9d17a17fb0..4f148b29c5 100644
---- a/website/client/components/static/header.vue
-+++ b/website/client/components/static/header.vue
-@@ -21,8 +21,6 @@
- ul.navbar-nav.mr-auto(v-else)
- router-link.nav-item(tag='li', to='/register')
- a.nav-link(v-once) {{ $t('getStarted') }}
-- li.nav-item
-- a.nav-link(@click='scrollToMobileApp') {{ $t('mobileApps') }}
- li.nav-item.dropdown
- a.nav-link.dropdown-toggle(v-once) {{ $t('learnMore') }}
- .dropdown-menu
-@@ -158,7 +156,6 @@
+diff --git a/website/client/src/components/static/header.vue b/website/client/src/components/static/header.vue
+index 696a8a2460..2010b8c96d 100644
+--- a/website/client/src/components/static/header.vue
++++ b/website/client/src/components/static/header.vue
+@@ -91,12 +91,6 @@
+ class="nav-link"
+ >{{ $t('getStarted') }}</a>
+ </router-link>
+- <li class="nav-item">
+- <a
+- class="nav-link"
+- @click="scrollToMobileApp"
+- >{{ $t('mobileApps') }}</a>
+- </li>
+ <li class="nav-item dropdown">
+ <a
+ v-once
+@@ -262,7 +256,6 @@
<script>
- import logo from 'assets/svg/logo.svg';
- import purpleLogo from 'assets/svg/purple-logo.svg';
--import * as Analytics from 'client/libs/analytics';
+ import logo from '@/assets/svg/logo.svg';
+ import purpleLogo from '@/assets/svg/purple-logo.svg';
+-import * as Analytics from '@/libs/analytics';
export default {
data () {
-@@ -181,21 +178,8 @@ export default {
+@@ -285,21 +278,8 @@ export default {
return;
}
@@ -3690,56 +3984,90 @@ index 9d17a17fb0..4f148b29c5 100644
},
};
</script>
-diff --git a/website/client/components/static/home.vue b/website/client/components/static/home.vue
-index a6acf92a55..0180180773 100644
---- a/website/client/components/static/home.vue
-+++ b/website/client/components/static/home.vue
-@@ -13,15 +13,6 @@
- p.section-main {{$t('timeToGetThingsDone', {userCountInMillions})}}
- .col-12.col-md-6.col-lg-6
- h3.text-center {{$t('singUpForFree')}}
-- div.text-center
-- button.social-button(@click='socialAuth("facebook")')
-- .svg-icon.social-icon(v-html="icons.facebookIcon")
-- span {{$t('signUpWithSocial', {social: 'Facebook'})}}
-- button.social-button(@click='socialAuth("google")')
-- .svg-icon.social-icon(v-html="icons.googleIcon")
-- span {{$t('signUpWithSocial', {social: 'Google'})}}
-- .strike
-- span {{$t('or')}}
- .form(@keyup.enter="register()")
- p.form-text {{$t('usernameLimitations')}}
- input#usernameInput.form-control(type='text', :placeholder='$t("username")', v-model='username', :class='{"input-valid": usernameValid, "input-invalid": usernameInvalid}')
-@@ -81,19 +72,6 @@
- .container-fluid
- .pixel-horizontal-2.svg-icon(v-html='icons.pixelHorizontal2')
-
-- #level-up-anywhere.purple-3
-- .container
-- .row
-- .col-12.col-md-6.col-lg-6
-- .iphones
-- .col-12.col-md-6.col-lg-6.text-column
-- h2 {{ $t('levelUpAnywhere') }}
-- p {{ $t('levelUpAnywhereDesc') }}
-- a.app.svg-icon(v-html='icons.googlePlay', href='https://play.google.com/store/apps/details?id=com.habitrpg.android.habitica', target='_blank')
-- a.app.svg-icon(v-html='icons.iosAppStore', href='https://itunes.apple.com/us/app/habitica-gamified-task-manager/id994882113?mt=8', target='_blank')
-- .container-fluid
-- .pixel-horizontal-3.svg-icon(v-html='icons.pixelHorizontal3')
--
- #call-to-action.purple-4
- .container.featured
- .row.text-center
-@@ -126,7 +104,7 @@
+diff --git a/website/client/src/components/static/home.vue b/website/client/src/components/static/home.vue
+index ed3cb2d511..0d8dbe5650 100644
+--- a/website/client/src/components/static/home.vue
++++ b/website/client/src/components/static/home.vue
+@@ -28,28 +28,6 @@
+ <h3 class="text-center">
+ {{ $t('singUpForFree') }}
+ </h3>
+- <div class="text-center">
+- <button
+- class="social-button"
+- @click="socialAuth('facebook')"
+- >
+- <div
+- class="svg-icon social-icon"
+- v-html="icons.facebookIcon"
+- ></div>
+- <span>{{ $t('signUpWithSocial', {social: 'Facebook'}) }}</span>
+- </button>
+- <button
+- class="social-button"
+- @click="socialAuth('google')"
+- >
+- <div
+- class="svg-icon social-icon"
+- v-html="icons.googleIcon"
+- ></div>
+- <span>{{ $t('signUpWithSocial', {social: 'Google'}) }}</span>
+- </button>
+- </div>
+ <div class="strike">
+ <span>{{ $t('or') }}</span>
+ </div>
+@@ -231,40 +209,6 @@
+ ></div>
+ </div>
+ </div>
+- <div
+- id="level-up-anywhere"
+- class="purple-3"
+- >
+- <div class="container">
+- <div class="row">
+- <div class="col-12 col-md-6 col-lg-6">
+- <div class="iphones"></div>
+- </div>
+- <div class="col-12 col-md-6 col-lg-6 text-column">
+- <h2>{{ $t('levelUpAnywhere') }}</h2>
+- <p>{{ $t('levelUpAnywhereDesc') }}</p>
+- <a
+- class="app svg-icon"
+- href="https://play.google.com/store/apps/details?id=com.habitrpg.android.habitica"
+- target="_blank"
+- v-html="icons.googlePlay"
+- ></a>
+- <a
+- class="app svg-icon"
+- href="https://itunes.apple.com/us/app/habitica-gamified-task-manager/id994882113?mt=8"
+- target="_blank"
+- v-html="icons.iosAppStore"
+- ></a>
+- </div>
+- </div>
+- </div>
+- <div class="container-fluid">
+- <div
+- class="pixel-horizontal-3 svg-icon"
+- v-html="icons.pixelHorizontal3"
+- ></div>
+- </div>
+- </div>
+ <div
+ id="call-to-action"
+ class="purple-4"
+@@ -343,7 +287,7 @@
<style lang="scss" scoped>
- @import '~client/assets/scss/colors.scss';
+ @import '~@/assets/scss/colors.scss';
-@import url('https://fonts.googleapis.com/css?family=Varela+Round');
+@import url('/static/fonts/home-fonts.css');
#front {
.form-text a {
-@@ -220,37 +198,6 @@
+@@ -437,37 +381,6 @@
font-size: 24px;
}
@@ -3777,7 +4105,7 @@ index a6acf92a55..0180180773 100644
.strike {
display: block;
text-align: center;
-@@ -393,31 +340,6 @@
+@@ -610,31 +523,6 @@
}
}
@@ -3798,7 +4126,7 @@ index a6acf92a55..0180180773 100644
- max-width: 100%;
- background-repeat: no-repeat;
- background-size: 100%;
-- background-image: url('~assets/images/home/mobile-preview@3x.png');
+- background-image: url('~@/assets/images/home/mobile-preview@3x.png');
- }
-
- .text-column {
@@ -3809,107 +4137,107 @@ index a6acf92a55..0180180773 100644
#call-to-action {
.row {
margin-top: 1em;
-@@ -558,18 +480,11 @@
+@@ -775,18 +663,11 @@
</style>
<script>
-- import hello from 'hellojs';
- import debounce from 'lodash/debounce';
- import isEmail from 'validator/lib/isEmail';
-- import googlePlay from 'assets/images/home/google-play-badge.svg';
-- import iosAppStore from 'assets/images/home/ios-app-store.svg';
-- import iphones from 'assets/images/home/iphones.svg';
- import spacer from 'assets/images/home/spacer.svg';
- import pixelHorizontal from 'assets/images/home/pixel-horizontal.svg';
- import pixelHorizontal2 from 'assets/images/home/pixel-horizontal-2.svg';
-- import pixelHorizontal3 from 'assets/images/home/pixel-horizontal-3.svg';
-- import facebookSquareIcon from 'assets/svg/facebook-square.svg';
-- import googleIcon from 'assets/svg/google.svg';
- import cnet from 'assets/svg/cnet.svg';
- import fastCompany from 'assets/svg/fast-company.svg';
- import discover from 'assets/images/home/discover.svg';
-@@ -578,21 +493,14 @@
- import lifehacker from 'assets/images/home/lifehacker.svg';
- import makeuseof from 'assets/images/home/make-use-of.svg';
- import thenewyorktimes from 'assets/images/home/the-new-york-times.svg';
-- import * as Analytics from 'client/libs/analytics';
-
- export default {
- data () {
- return {
- icons: Object.freeze({
-- googlePlay,
-- iosAppStore,
-- iphones,
- spacer,
- pixelHorizontal,
- pixelHorizontal2,
-- pixelHorizontal3,
-- facebookIcon: facebookSquareIcon,
-- googleIcon,
- cnet,
- fastCompany,
- discover,
-@@ -610,20 +518,6 @@
- usernameIssues: [],
- };
+-import hello from 'hellojs';
+ import debounce from 'lodash/debounce';
+ import isEmail from 'validator/lib/isEmail';
+-import googlePlay from '@/assets/images/home/google-play-badge.svg';
+-import iosAppStore from '@/assets/images/home/ios-app-store.svg';
+-import iphones from '@/assets/images/home/iphones.svg';
+ import spacer from '@/assets/images/home/spacer.svg';
+ import pixelHorizontal from '@/assets/images/home/pixel-horizontal.svg';
+ import pixelHorizontal2 from '@/assets/images/home/pixel-horizontal-2.svg';
+-import pixelHorizontal3 from '@/assets/images/home/pixel-horizontal-3.svg';
+-import facebookSquareIcon from '@/assets/svg/facebook-square.svg';
+-import googleIcon from '@/assets/svg/google.svg';
+ import cnet from '@/assets/svg/cnet.svg';
+ import fastCompany from '@/assets/svg/fast-company.svg';
+ import discover from '@/assets/images/home/discover.svg';
+@@ -795,21 +676,14 @@ import kickstarter from '@/assets/images/home/kickstarter.svg';
+ import lifehacker from '@/assets/images/home/lifehacker.svg';
+ import makeuseof from '@/assets/images/home/make-use-of.svg';
+ import thenewyorktimes from '@/assets/images/home/the-new-york-times.svg';
+-import * as Analytics from '@/libs/analytics';
+
+ export default {
+ data () {
+ return {
+ icons: Object.freeze({
+- googlePlay,
+- iosAppStore,
+- iphones,
+ spacer,
+ pixelHorizontal,
+ pixelHorizontal2,
+- pixelHorizontal3,
+- facebookIcon: facebookSquareIcon,
+- googleIcon,
+ cnet,
+ fastCompany,
+ discover,
+@@ -858,20 +732,6 @@ export default {
+ this.validateUsername(this.username);
},
-- mounted () {
-- Analytics.track({
-- hitType: 'pageview',
-- eventCategory: 'page',
-- eventAction: 'landing page',
-- page: '/static/home',
-- });
+ },
+- mounted () {
+- Analytics.track({
+- hitType: 'pageview',
+- eventCategory: 'page',
+- eventAction: 'landing page',
+- page: '/static/home',
+- });
-
-- hello.init({
+- hello.init({
- facebook: process.env.FACEBOOK_KEY, // eslint-disable-line
-- // windows: WINDOWS_CLIENT_ID,
+- // windows: WINDOWS_CLIENT_ID,
- google: process.env.GOOGLE_CLIENT_ID, // eslint-disable-line
+- });
+- },
+ methods: {
+ // eslint-disable-next-line func-names
+ validateUsername: debounce(function (username) {
+@@ -918,33 +778,8 @@ export default {
+ window.location.href = redirectTo;
+ },
+ playButtonClick () {
+- Analytics.track({
+- hitType: 'event',
+- eventCategory: 'button',
+- eventAction: 'click',
+- eventLabel: 'Play',
- });
-- },
- computed: {
- emailValid () {
- if (this.email.length <= 3) return false;
-@@ -701,33 +595,8 @@
- window.location.href = redirectTo;
- },
- playButtonClick () {
-- Analytics.track({
-- hitType: 'event',
-- eventCategory: 'button',
-- eventAction: 'click',
-- eventLabel: 'Play',
-- });
- this.$router.push('/register');
- },
-- // @TODO: Abstract hello in to action or lib
-- async socialAuth (network) {
-- try {
-- await hello(network).logout();
+ this.$router.push('/register');
+ },
+- // @TODO: Abstract hello in to action or lib
+- async socialAuth (network) {
+- try {
+- await hello(network).logout();
- } catch (e) {} // eslint-disable-line
-
-- const redirectUrl = `${window.location.protocol}//${window.location.host}`;
-- const auth = await hello(network).login({
-- scope: 'email',
-- // explicitly pass the redirect url or it might redirect to /home
-- redirect_uri: redirectUrl, // eslint-disable-line camelcase
-- });
+- const redirectUrl = `${window.location.protocol}//${window.location.host}`;
+- const auth = await hello(network).login({
+- scope: 'email',
+- // explicitly pass the redirect url or it might redirect to /home
+- redirect_uri: redirectUrl, // eslint-disable-line camelcase
+- });
-
-- await this.$store.dispatch('auth:socialAuth', {
-- auth,
-- });
+- await this.$store.dispatch('auth:socialAuth', {
+- auth,
+- });
-
-- window.location.href = '/';
-- },
- },
- };
+- window.location.href = '/';
+- },
+ },
+ };
</script>
-diff --git a/website/client/components/static/staticWrapper.vue b/website/client/components/static/staticWrapper.vue
-index 94371181fe..eefe1fe6ea 100644
---- a/website/client/components/static/staticWrapper.vue
-+++ b/website/client/components/static/staticWrapper.vue
-@@ -90,7 +90,7 @@ div
+diff --git a/website/client/src/components/static/staticWrapper.vue b/website/client/src/components/static/staticWrapper.vue
+index 89cb9fb77c..517db5f983 100644
+--- a/website/client/src/components/static/staticWrapper.vue
++++ b/website/client/src/components/static/staticWrapper.vue
+@@ -105,7 +105,7 @@
color: #bda8ff;
}
@@ -3918,115 +4246,69 @@ index 94371181fe..eefe1fe6ea 100644
background: #36205d;
color: #bda8ff;
-diff --git a/website/client/components/tasks/task.vue b/website/client/components/tasks/task.vue
-index 0a1b15ddf9..46cb1da302 100644
---- a/website/client/components/tasks/task.vue
-+++ b/website/client/components/tasks/task.vue
-@@ -552,7 +552,6 @@ import moment from 'moment';
- import axios from 'axios';
- import scoreTask from 'common/script/ops/scoreTask';
- import Vue from 'vue';
--import * as Analytics from 'client/libs/analytics';
-
- import positiveIcon from 'assets/svg/positive.svg';
- import negativeIcon from 'assets/svg/negative.svg';
-@@ -783,8 +782,6 @@ export default {
+diff --git a/website/client/src/components/tasks/task.vue b/website/client/src/components/tasks/task.vue
+index 3d6232e584..2d01342a9e 100644
+--- a/website/client/src/components/tasks/task.vue
++++ b/website/client/src/components/tasks/task.vue
+@@ -791,7 +791,6 @@ import Vue from 'vue';
+ import uuid from 'uuid';
+ import { mapState, mapGetters, mapActions } from '@/libs/store';
+ import scoreTask from '@/../../common/script/ops/scoreTask';
+-import * as Analytics from '@/libs/analytics';
+
+ import positiveIcon from '@/assets/svg/positive.svg';
+ import negativeIcon from '@/assets/svg/negative.svg';
+@@ -1020,8 +1019,6 @@ export default {
break;
}
-
- Analytics.updateUser();
const response = await axios.post(`/api/v4/tasks/${task._id}/score/${direction}`);
- const tmp = response.data.data._tmp || {}; // used to notify drops, critical hits and other bonuses
- const crit = tmp.crit;
-diff --git a/website/client/components/userMenu/profile.vue b/website/client/components/userMenu/profile.vue
-index 02ecf467f6..dba76d8a65 100644
---- a/website/client/components/userMenu/profile.vue
-+++ b/website/client/components/userMenu/profile.vue
-@@ -79,14 +79,12 @@
- .progress
- .progress-bar(role='progressbar', :aria-valuenow='incentivesProgress', aria-valuemin='0', aria-valuemax='100', :style='{width: incentivesProgress + "%"}')
- span.sr-only {{ incentivesProgress }}% {{$t('complete')}}
-- // @TODO: Implement in V2 .social
-
- .row(v-if='editing')
- h1 {{$t('editProfile')}}
- .col-12
- .alert.alert-info.alert-sm(v-html='$t("communityGuidelinesWarning", managerEmail)')
-
-- // TODO use photo-upload instead: https://groups.google.com/forum/?fromgroups=#!topic/derbyjs/xMmADvxBOak
- .form-group
- label {{ $t('displayName') }}
- input.form-control(type='text', :placeholder="$t('fullName')", v-model='editingProfile.name')
-@@ -97,15 +95,6 @@
- label {{ $t('about') }}
- textarea.form-control(rows=5, :placeholder="$t('displayBlurbPlaceholder')", v-model='editingProfile.blurb')
- // include ../../shared/formatting-help
-- //- .form-group
-- //- label Facebook
-- //- input.form-control(type='text', placeholder="Paste your link here", v-model='editingProfile.facebook')
-- //- .form-group
-- //- label Instagram
-- //- input.form-control(type='text', placeholder="Paste your link here", v-model='editingProfile.instagram')
-- //- .form-group
-- //- label Twitter
-- //- input.form-control(type='text', placeholder="Paste your link here", v-model='editingProfile.twitter')
-
- .col-12.text-center
- button.btn.btn-primary(@click='save()') {{ $t("save") }}
-diff --git a/website/client/index.html b/website/client/index.html
-index 32ecee0b0e..096b62dc2c 100644
---- a/website/client/index.html
-+++ b/website/client/index.html
-@@ -6,18 +6,7 @@
- <title>Habitica - Gamify Your Life</title>
- <meta name="description" content="Habitica is a free habit and productivity app that treats your real life like a game. Habitica can help you achieve your goals to become healthy and happy.">
- <meta name="keywords" content="Habits,Goals,Todo,Gamification,Health,Fitness,School,Work">
-- <meta name="smartbanner:title" content="Habitica">
-- <meta name="smartbanner:author" content="HabitRPG, Inc.">
-- <meta name="smartbanner:price" content="FREE">
-- <meta name="smartbanner:price-suffix-apple" content=" - On the App Store">
-- <meta name="smartbanner:price-suffix-google" content=" - In Google Play">
-- <meta name="smartbanner:icon-apple" content="/static/presskit/Logo/iOS.png">
-- <meta name="smartbanner:icon-google" content="/static/presskit/Logo/Android.png">
-- <meta name="smartbanner:button" content="VIEW">
-- <meta name="smartbanner:button-url-apple" content="https://itunes.apple.com/us/app/habitica-gamified-taskmanager/id994882113">
-- <meta name="smartbanner:button-url-google" content="https://play.google.com/store/apps/details?id=com.habitrpg.android.habitica">
-- <meta name="smartbanner:enabled-platforms" content="android,ios">
-- <link href="https://fonts.googleapis.com/css?family=Roboto+Condensed:400,400i,700,700i|Roboto:400,400i,700,700i" rel="stylesheet">
-+ <link href="/static/fonts/index-fonts.css" rel="stylesheet">
- <link rel="shortcut icon" sizes="48x48" href="/static/icons/favicon.ico">
- <link rel="shortcut icon" sizes="192x192" href="/static/icons/favicon_192x192.png">
- <link rel="mask-icon" href="/static/icons/favicon.ico">
-@@ -33,7 +22,6 @@
- <div id="app"></div>
- <!-- built files will be auto injected -->
-
-- <script type="text/javascript" src="//cloudfront.loggly.com/js/loggly.tracker-latest.min.js" async></script>
- <!-- Translations -->
- <script type='text/javascript' src='/api/v4/i18n/browser-script'></script>
- </body>
-diff --git a/website/client/main.js b/website/client/main.js
-index f6b0701dd8..da68df567e 100644
---- a/website/client/main.js
-+++ b/website/client/main.js
-@@ -1,15 +1,10 @@
+ // used to notify drops, critical hits and other bonuses
+ const tmp = response.data.data._tmp || {};
+diff --git a/website/client/src/components/userMenu/profile.vue b/website/client/src/components/userMenu/profile.vue
+index 1e0b413c4c..97bf877a28 100644
+--- a/website/client/src/components/userMenu/profile.vue
++++ b/website/client/src/components/userMenu/profile.vue
+@@ -232,7 +232,6 @@
+ </div>
+ </div>
+ </div>
+- <!-- @TODO: Implement in V2 .social-->
+ </div>
+ </div>
+ <div
+@@ -245,7 +244,6 @@
+ class="alert alert-info alert-sm"
+ v-html="$t('communityGuidelinesWarning', managerEmail)"
+ ></div>
+- <!-- TODO use photo-upload instead: https://groups.google.com/forum/?fromgroups=#!topic/derbyjs/xMmADvxBOak-->
+ <div class="form-group">
+ <label>{{ $t('displayName') }}</label>
+ <input
+diff --git a/website/client/src/main.js b/website/client/src/main.js
+index f3587c5c12..421072ce35 100644
+--- a/website/client/src/main.js
++++ b/website/client/src/main.js
+@@ -1,16 +1,11 @@
import Vue from 'vue';
+ import BootstrapVue from 'bootstrap-vue';
import AppComponent from './app';
-import {
- setup as setupAnalytics,
--} from 'client/libs/analytics';
--import { setUpLogging } from 'client/libs/logging';
+-} from '@/libs/analytics';
+-import { setUpLogging } from '@/libs/logging';
import router from './router/index';
import getStore from './store';
import StoreModule from './libs/store';
import './filters/registerGlobals';
import i18n from './libs/i18n';
--import 'smartbanner.js/dist/smartbanner.js';
+-import 'smartbanner.js/dist/smartbanner';
- import BootstrapVue from 'bootstrap-vue';
+ const IS_PRODUCTION = process.env.NODE_ENV === 'production'; // eslint-disable-line no-process-env
-@@ -30,8 +25,6 @@ Vue.use(i18n, {i18nData: window && window['habitica-i18n']});
+@@ -29,8 +24,6 @@ Vue.use(i18n, { i18nData: window && window['habitica-i18n'] });
Vue.use(StoreModule);
Vue.use(BootstrapVue);
@@ -4035,32 +4317,32 @@ index f6b0701dd8..da68df567e 100644
const store = getStore();
export default new Vue({
-diff --git a/website/client/mixins/guide.js b/website/client/mixins/guide.js
-index 4dd3d9be88..d213fb5454 100644
---- a/website/client/mixins/guide.js
-+++ b/website/client/mixins/guide.js
+diff --git a/website/client/src/mixins/guide.js b/website/client/src/mixins/guide.js
+index d116a6d9ca..36e95d9e54 100644
+--- a/website/client/src/mixins/guide.js
++++ b/website/client/src/mixins/guide.js
@@ -1,6 +1,5 @@
import times from 'lodash/times';
import introjs from 'intro.js';
--import * as Analytics from 'client/libs/analytics';
+-import * as Analytics from '@/libs/analytics';
let showingTour = false;
-@@ -140,12 +139,6 @@ export default {
- case 'equipment': return this.goto('equipment', 0);
- }
+@@ -143,12 +142,6 @@ export default {
+
+ return null;
},
- hoyo (user) {
- // @TODO: What is was the timeout for?
- // @TODO move to analytics
- window.amplitude.setUserId(user._id);
-- window.ga('set', {userId: user._id});
+- window.ga('set', { userId: user._id });
- },
goto (chapter, page, force) {
- if (chapter === 'intro' && this.user.flags.welcomed !== true) {
+ if (chapter === 'intro' && this.user.flags.welcomed !== true) {
// @TODO: Add dispatch User.set({'flags.welcomed': true});
-@@ -162,15 +155,6 @@ export default {
- opts.steps = opts.steps.concat(this.chapters[chapter][p]);
+@@ -165,15 +158,6 @@ export default {
+ opts.steps = opts.steps.concat(this.chapters[chapter][p]);
});
- Analytics.track({
@@ -4075,7 +4357,7 @@ index 4dd3d9be88..d213fb5454 100644
// @TODO: Do we always need to initialize here?
const intro = introjs();
intro.setOptions({
-@@ -196,15 +180,6 @@ export default {
+@@ -200,15 +184,6 @@ export default {
// Mark tour complete
ups[`flags.tour.${chapter}`] = -2; // @TODO: Move magic numbers to enum
@@ -4091,20 +4373,20 @@ index 4dd3d9be88..d213fb5454 100644
this.$store.dispatch('user:set', ups);
},
},
-diff --git a/website/client/router/index.js b/website/client/router/index.js
-index 167232732b..05663006bc 100644
---- a/website/client/router/index.js
-+++ b/website/client/router/index.js
+diff --git a/website/client/src/router/index.js b/website/client/src/router/index.js
+index b44689dd15..196e97b282 100644
+--- a/website/client/src/router/index.js
++++ b/website/client/src/router/index.js
@@ -1,8 +1,6 @@
import Vue from 'vue';
import VueRouter from 'vue-router';
- import getStore from 'client/store';
--import * as Analytics from 'client/libs/analytics';
+ import getStore from '@/store';
+-import * as Analytics from '@/libs/analytics';
-import handleRedirect from './handleRedirect';
- import ParentPage from 'client/components/parentPage';
+ import ParentPage from '@/components/parentPage';
-@@ -286,9 +284,6 @@ const router = new VueRouter({
+@@ -327,9 +325,6 @@ const router = new VueRouter({
{ name: 'contributors', path: 'contributors', component: HeroesPage },
],
},
@@ -4114,8 +4396,8 @@ index 167232732b..05663006bc 100644
{ path: '*', redirect: { name: 'notFound' } },
],
});
-@@ -299,8 +294,6 @@ router.beforeEach(function routerGuard (to, from, next) {
- const isUserLoggedIn = store.state.isUserLoggedIn;
+@@ -340,8 +335,6 @@ router.beforeEach((to, from, next) => {
+ const { isUserLoggedIn } = store.state;
const routeRequiresLogin = to.meta.requiresLogin !== false;
- if (to.name === 'redirect') return handleRedirect(to, from, next);
@@ -4123,7 +4405,7 @@ index 167232732b..05663006bc 100644
if (!isUserLoggedIn && routeRequiresLogin) {
// Redirect to the login page unless the user is trying to reach the
// root of the website, in which case show the home page.
-@@ -356,13 +349,6 @@ router.beforeEach(function routerGuard (to, from, next) {
+@@ -397,13 +390,6 @@ router.beforeEach((to, from, next) => {
});
}
@@ -4137,32 +4419,24 @@ index 167232732b..05663006bc 100644
if ((to.name === 'userProfile' || to.name === 'userProfilePage') && from.name !== null) {
let startingPage = 'profile';
if (to.params.startingPage !== undefined) {
-@@ -387,7 +373,6 @@ router.beforeEach(function routerGuard (to, from, next) {
- if (from.name === 'userProfile' || from.name === 'userProfilePage' || from.name === 'stats' || from.name === 'achievements' || from.name === 'profile') {
- router.app.$root.$emit('bv::hide::modal', 'profile');
- }
--
- next();
- });
-
-diff --git a/website/client/store/actions/auth.js b/website/client/store/actions/auth.js
-index 58af5e3be9..c84241a39e 100644
---- a/website/client/store/actions/auth.js
-+++ b/website/client/store/actions/auth.js
+diff --git a/website/client/src/store/actions/auth.js b/website/client/src/store/actions/auth.js
+index af909201b8..9bb001cf9e 100644
+--- a/website/client/src/store/actions/auth.js
++++ b/website/client/src/store/actions/auth.js
@@ -63,25 +63,6 @@ export async function verifyDisplayName (store, params) {
return result.data.data;
}
-export async function socialAuth (store, params) {
-- let url = '/api/v4/user/auth/social';
-- let result = await axios.post(url, {
+- const url = '/api/v4/user/auth/social';
+- const result = await axios.post(url, {
- network: params.auth.network,
- authResponse: params.auth.authResponse,
- });
-
-- let user = result.data.data;
+- const user = result.data.data;
-
-- let userLocalData = JSON.stringify({
+- const userLocalData = JSON.stringify({
- auth: {
- apiId: user.id,
- apiToken: user.apiToken,
@@ -4175,16 +4449,16 @@ index 58af5e3be9..c84241a39e 100644
export function logout () {
localStorage.clear();
window.location.href = '/logout-server';
-diff --git a/website/client/store/actions/chat.js b/website/client/store/actions/chat.js
-index 584db3bf75..98806066f3 100644
---- a/website/client/store/actions/chat.js
-+++ b/website/client/store/actions/chat.js
+diff --git a/website/client/src/store/actions/chat.js b/website/client/src/store/actions/chat.js
+index 75ef624306..36e37f11da 100644
+--- a/website/client/src/store/actions/chat.js
++++ b/website/client/src/store/actions/chat.js
@@ -1,5 +1,4 @@
import axios from 'axios';
--import * as Analytics from 'client/libs/analytics';
+-import * as Analytics from '@/libs/analytics';
export async function getChat (store, payload) {
- let response = await axios.get(`/api/v4/groups/${payload.groupId}/chat`);
+ const response = await axios.get(`/api/v4/groups/${payload.groupId}/chat`);
@@ -16,13 +15,6 @@ export async function postChat (store, payload) {
url += `?previousMsg=${payload.previousMsg}`;
}
@@ -4196,42 +4470,42 @@ index 584db3bf75..98806066f3 100644
- });
- }
-
- let response = await axios.post(url, {
+ const response = await axios.post(url, {
message: payload.message,
});
-diff --git a/website/client/store/actions/guilds.js b/website/client/store/actions/guilds.js
-index ea4e680440..b4eda8714b 100644
---- a/website/client/store/actions/guilds.js
-+++ b/website/client/store/actions/guilds.js
+diff --git a/website/client/src/store/actions/guilds.js b/website/client/src/store/actions/guilds.js
+index 02609970fe..2372fc9124 100644
+--- a/website/client/src/store/actions/guilds.js
++++ b/website/client/src/store/actions/guilds.js
@@ -1,7 +1,6 @@
import axios from 'axios';
import omit from 'lodash/omit';
import findIndex from 'lodash/findIndex';
--import * as Analytics from 'client/libs/analytics';
+-import * as Analytics from '@/libs/analytics';
export async function getPublicGuilds (store, payload) {
- let params = {
+ const params = {
@@ -74,8 +73,6 @@ export async function join (store, payload) {
if (invitationI !== -1) invitations.parties.splice(invitationI, 1);
user.party._id = groupId;
-
-- Analytics.updateUser({partyID: groupId});
+- Analytics.updateUser({ partyID: groupId });
}
return response.data.data;
-diff --git a/website/client/store/actions/quests.js b/website/client/store/actions/quests.js
-index cff15fa53a..ef7fd0dd5b 100644
---- a/website/client/store/actions/quests.js
-+++ b/website/client/store/actions/quests.js
+diff --git a/website/client/src/store/actions/quests.js b/website/client/src/store/actions/quests.js
+index af340d5aa5..49508530b0 100644
+--- a/website/client/src/store/actions/quests.js
++++ b/website/client/src/store/actions/quests.js
@@ -1,26 +1,9 @@
import axios from 'axios';
--import * as Analytics from 'client/libs/analytics';
+-import * as Analytics from '@/libs/analytics';
// export async function initQuest (store) {
// }
- export async function sendAction (store, payload) {
+ export async function sendAction (store, payload) { // eslint-disable-line import/prefer-default-export, max-len
- // @TODO: Maybe move this to server
- let partyData = {};
- if (store.state.party && store.state.party.data) {
@@ -4248,14 +4522,14 @@ index cff15fa53a..ef7fd0dd5b 100644
-
- Analytics.updateUser(partyData);
-
- let response = await axios.post(`/api/v4/groups/${payload.groupId}/${payload.action}`);
+ const response = await axios.post(`/api/v4/groups/${payload.groupId}/${payload.action}`);
// @TODO: Update user?
-diff --git a/website/client/store/index.js b/website/client/store/index.js
-index b47fce6de7..4f33daf2a2 100644
---- a/website/client/store/index.js
-+++ b/website/client/store/index.js
-@@ -51,7 +51,6 @@ export default function () {
+diff --git a/website/client/src/store/index.js b/website/client/src/store/index.js
+index 42fe46c9a8..9de1fa52e1 100644
+--- a/website/client/src/store/index.js
++++ b/website/client/src/store/index.js
+@@ -54,7 +54,6 @@ export default function () {
title: 'Habitica',
isUserLoggedIn,
isUserLoaded: false, // Means the user and the user's tasks are ready
@@ -4263,38 +4537,70 @@ index b47fce6de7..4f33daf2a2 100644
user: asyncResourceFactory(),
credentials: isUserLoggedIn ? {
API_ID: AUTH_SETTINGS.auth.apiId,
-diff --git a/website/common/errors/apiErrorMessages.js b/website/common/errors/apiErrorMessages.js
-index f10747b12c..90804492fc 100644
---- a/website/common/errors/apiErrorMessages.js
-+++ b/website/common/errors/apiErrorMessages.js
-@@ -23,6 +23,5 @@ module.exports = {
-
- missingPaymentId: 'Missing "req.query.paymentId"',
- missingCustomerId: 'Missing "req.query.customerId"',
-- missingPaypalBlock: 'Missing "req.session.paypalBlock"',
- missingSubKey: 'Missing "req.query.sub"',
- };
+diff --git a/website/client/vue.config.js b/website/client/vue.config.js
+index cdf5a9f345..b1a7f55529 100644
+--- a/website/client/vue.config.js
++++ b/website/client/vue.config.js
+@@ -14,19 +14,10 @@ setupNconf(configFile, nconf);
+ const DEV_BASE_URL = nconf.get('BASE_URL');
+
+ const envVars = [
+- 'AMAZON_PAYMENTS_SELLER_ID',
+- 'AMAZON_PAYMENTS_CLIENT_ID',
+- 'AMAZON_PAYMENTS_MODE',
+ 'EMAILS_COMMUNITY_MANAGER_EMAIL',
+ 'EMAILS_TECH_ASSISTANCE_EMAIL',
+ 'EMAILS_PRESS_ENQUIRY_EMAIL',
+ 'BASE_URL',
+- 'GA_ID',
+- 'STRIPE_PUB_KEY',
+- 'FACEBOOK_KEY',
+- 'GOOGLE_CLIENT_ID',
+- 'AMPLITUDE_KEY',
+- 'LOGGLY_CLIENT_TOKEN',
+ // TODO necessary? if yes how not to mess up with vue cli? 'NODE_ENV'
+ ];
+
+@@ -126,18 +117,6 @@ module.exports = {
+ target: DEV_BASE_URL,
+ changeOrigin: true,
+ },
+- '^/stripe': {
+- target: DEV_BASE_URL,
+- changeOrigin: true,
+- },
+- '^/amazon': {
+- target: DEV_BASE_URL,
+- changeOrigin: true,
+- },
+- '^/paypal': {
+- target: DEV_BASE_URL,
+- changeOrigin: true,
+- },
+ '^/logout-server': {
+ target: DEV_BASE_URL,
+ changeOrigin: true,
diff --git a/website/common/script/constants.js b/website/common/script/constants.js
-index 8985bea89e..098e34095f 100644
+index 9d4f4137c2..7f36ee4942 100644
--- a/website/common/script/constants.js
+++ b/website/common/script/constants.js
-@@ -15,11 +15,6 @@ export const CHAT_FLAG_FROM_MOD = 5; // a flag from a moderator counts as this m
- export const CHAT_FLAG_FROM_SHADOW_MUTE = 10; // a shadow-muted user's post starts with this many flags
+@@ -16,11 +16,6 @@ export const CHAT_FLAG_FROM_MOD = 5; // a flag from a moderator counts as this m
+ export const CHAT_FLAG_FROM_SHADOW_MUTE = 10;
// @TODO use those constants to replace hard-coded numbers
-export const SUPPORTED_SOCIAL_NETWORKS = [
-- {key: 'facebook', name: 'Facebook'},
-- {key: 'google', name: 'Google'},
+- { key: 'facebook', name: 'Facebook' },
+- { key: 'google', name: 'Google' },
-];
-
export const GUILDS_PER_PAGE = 30; // number of guilds to return per page when using pagination
export const PARTY_LIMIT_MEMBERS = 30;
diff --git a/website/common/script/content/spells.js b/website/common/script/content/spells.js
-index 58d69d3755..e641f15466 100644
+index 02196d4f78..487424e7f7 100644
--- a/website/common/script/content/spells.js
+++ b/website/common/script/content/spells.js
-@@ -44,13 +44,13 @@ spells.wizard = {
+@@ -53,13 +53,13 @@ spells.wizard = {
lvl: 11,
target: 'task',
notes: t('spellWizardFireballNotes'),
@@ -4310,14 +4616,14 @@ index 58d69d3755..e641f15466 100644
},
},
mpheal: { // Ethereal Surge
-@@ -168,12 +168,12 @@ spells.rogue = {
+@@ -177,12 +177,12 @@ spells.rogue = {
lvl: 12,
target: 'task',
notes: t('spellRogueBackStabNotes'),
- cast (user, target, req) {
+ cast (user, target) {
- let _crit = crit.crit(user, 'str', 0.3);
- let bonus = calculateBonus(target.value, statsComputed(user).str, _crit);
+ const _crit = crit.crit(user, 'str', 0.3);
+ const bonus = calculateBonus(target.value, statsComputed(user).str, _crit);
user.stats.exp += diminishingReturns(bonus, 75, 50);
user.stats.gp += diminishingReturns(bonus, 18, 75);
- updateStats(user, user.stats, req);
@@ -4326,10 +4632,10 @@ index 58d69d3755..e641f15466 100644
},
toolsOfTrade: { // Tools of the Trade
diff --git a/website/common/script/content/subscriptionBlocks.js b/website/common/script/content/subscriptionBlocks.js
-index f3131cb5a5..719a693820 100644
+index 760588772e..3a889dd72e 100644
--- a/website/common/script/content/subscriptionBlocks.js
+++ b/website/common/script/content/subscriptionBlocks.js
-@@ -20,14 +20,6 @@ let subscriptionBlocks = {
+@@ -20,14 +20,6 @@ const subscriptionBlocks = {
months: 6,
price: 30,
},
@@ -4344,7 +4650,7 @@ index f3131cb5a5..719a693820 100644
basic_12mo: {
target: 'user',
canSubscribe: true,
-@@ -39,7 +31,7 @@ let subscriptionBlocks = {
+@@ -39,7 +31,7 @@ const subscriptionBlocks = {
canSubscribe: true,
months: 1,
price: 9,
@@ -4353,20 +4659,31 @@ index f3131cb5a5..719a693820 100644
},
group_plan_auto: {
target: 'user',
+diff --git a/website/common/script/errors/apiErrorMessages.js b/website/common/script/errors/apiErrorMessages.js
+index 1a99ec1d2e..40eec5ae38 100644
+--- a/website/common/script/errors/apiErrorMessages.js
++++ b/website/common/script/errors/apiErrorMessages.js
+@@ -23,6 +23,5 @@ export default {
+
+ missingPaymentId: 'Missing "req.query.paymentId"',
+ missingCustomerId: 'Missing "req.query.customerId"',
+- missingPaypalBlock: 'Missing "req.session.paypalBlock"',
+ missingSubKey: 'Missing "req.query.sub"',
+ };
diff --git a/website/common/script/fns/randomDrop.js b/website/common/script/fns/randomDrop.js
-index 6061b3f83f..7c643d0ef0 100644
+index a3f8101424..35b03647e1 100644
--- a/website/common/script/fns/randomDrop.js
+++ b/website/common/script/fns/randomDrop.js
-@@ -25,7 +25,7 @@ function trueRandom () {
+@@ -24,7 +24,7 @@ function trueRandom () {
return Math.random();
}
--module.exports = function randomDrop (user, options, req = {}, analytics) {
-+module.exports = function randomDrop (user, options, req = {}) {
+-export default function randomDrop (user, options, req = {}, analytics) {
++export default function randomDrop (user, options, req = {}) {
let acceptableDrops;
let drop;
let dropMultiplier;
-@@ -119,16 +119,6 @@ module.exports = function randomDrop (user, options, req = {}, analytics) {
+@@ -125,16 +125,6 @@ export default function randomDrop (user, options, req = {}, analytics) {
}, req.language);
}
@@ -4382,22 +4699,22 @@ index 6061b3f83f..7c643d0ef0 100644
-
user._tmp.drop = drop;
user.items.lastDrop.date = Number(new Date());
- user.items.lastDrop.count++;
+ user.items.lastDrop.count += 1;
diff --git a/website/common/script/fns/updateStats.js b/website/common/script/fns/updateStats.js
-index 669fb46fd2..11278bd04d 100644
+index 49ca605959..4f9e000c5c 100644
--- a/website/common/script/fns/updateStats.js
+++ b/website/common/script/fns/updateStats.js
@@ -6,7 +6,7 @@ import {
import { toNextLevel } from '../statHelpers';
import autoAllocate from './autoAllocate';
--module.exports = function updateStats (user, stats, req = {}, analytics) {
-+module.exports = function updateStats (user, stats) {
+-export default function updateStats (user, stats, req = {}, analytics) {
++export default function updateStats (user, stats) {
let allocatedStatPoints;
let totalStatPoints;
let experienceToNextLevel;
-@@ -92,15 +92,6 @@ module.exports = function updateStats (user, stats, req = {}, analytics) {
- user.items.quests[k]++;
+@@ -92,15 +92,6 @@ export default function updateStats (user, stats, req = {}, analytics) {
+ user.items.quests[k] += 1;
if (user.markModified) user.markModified('items.quests');
- if (analytics) {
@@ -4413,10 +4730,10 @@ index 669fb46fd2..11278bd04d 100644
type: 'Quest',
key: k,
diff --git a/website/common/script/index.js b/website/common/script/index.js
-index b636c94bc2..5775880362 100644
+index 3e12ebd7fe..a38bd65c00 100644
--- a/website/common/script/index.js
+++ b/website/common/script/index.js
-@@ -26,7 +26,6 @@ import {
+@@ -22,7 +22,6 @@ import {
MAX_SUMMARY_SIZE_FOR_GUILDS,
MAX_SUMMARY_SIZE_FOR_CHALLENGES,
MIN_SHORTNAME_SIZE_FOR_CHALLENGES,
@@ -4424,7 +4741,7 @@ index b636c94bc2..5775880362 100644
GUILDS_PER_PAGE,
PARTY_LIMIT_MEMBERS,
CHAT_FLAG_LIMIT_FOR_HIDING,
-@@ -40,7 +39,6 @@ api.constants = {
+@@ -123,7 +122,6 @@ api.constants = {
MAX_SUMMARY_SIZE_FOR_GUILDS,
MAX_SUMMARY_SIZE_FOR_CHALLENGES,
MIN_SHORTNAME_SIZE_FOR_CHALLENGES,
@@ -4433,17 +4750,10 @@ index b636c94bc2..5775880362 100644
PARTY_LIMIT_MEMBERS,
CHAT_FLAG_LIMIT_FOR_HIDING,
diff --git a/website/common/script/ops/buy/abstractBuyOperation.js b/website/common/script/ops/buy/abstractBuyOperation.js
-index 3f87f08694..79533d4c20 100644
+index aaaf89ee38..307ff15166 100644
--- a/website/common/script/ops/buy/abstractBuyOperation.js
+++ b/website/common/script/ops/buy/abstractBuyOperation.js
-@@ -4,19 +4,16 @@ import {
- NotImplementedError,
- BadRequest,
- } from '../../libs/errors';
--import _merge from 'lodash/merge';
- import _get from 'lodash/get';
-
- export class AbstractBuyOperation {
+@@ -12,12 +12,10 @@ export class AbstractBuyOperation {
/**
* @param {User} user - the User-Object
* @param {Request} req - the Request-Object
@@ -4455,22 +4765,22 @@ index 3f87f08694..79533d4c20 100644
this.req = req || {};
- this.analytics = analytics;
- let quantity = _get(req, 'quantity');
+ const quantity = _get(req, 'quantity');
-@@ -84,10 +81,6 @@ export class AbstractBuyOperation {
+@@ -84,10 +82,6 @@ export class AbstractBuyOperation {
throw new NotImplementedError('executeChanges');
}
-- analyticsData () {
+- analyticsData () { // eslint-disable-line class-methods-use-this
- throw new NotImplementedError('sendToAnalytics');
- }
-
purchase () {
if (!this.multiplePurchaseAllowed() && this.quantity > 1) {
throw new NotAuthorized(this.i18n('messageNotAbleToBuyInBulk'));
-@@ -97,37 +90,13 @@ export class AbstractBuyOperation {
+@@ -97,32 +91,8 @@ export class AbstractBuyOperation {
- let resultObj = this.executeChanges(this.user, this.item, this.req);
+ const resultObj = this.executeChanges(this.user, this.item, this.req);
- if (this.analytics) {
- this.sendToAnalytics(this.analyticsData());
@@ -4479,13 +4789,13 @@ index 3f87f08694..79533d4c20 100644
return resultObj;
}
-
-- analyticsLabel () {
+- analyticsLabel () { // eslint-disable-line class-methods-use-this
- return 'acquire item';
- }
-
- sendToAnalytics (additionalData = {}) {
- // spread-operator produces an "unexpected token" error
-- let analyticsData = _merge(additionalData, {
+- const analyticsData = _merge(additionalData, {
- // ...additionalData,
- uuid: this.user._id,
- category: 'behavior',
@@ -4501,14 +4811,7 @@ index 3f87f08694..79533d4c20 100644
}
export class AbstractGoldItemOperation extends AbstractBuyOperation {
-- constructor (user, req, analytics) {
-- super(user, req, analytics);
-+ constructor (user, req) {
-+ super(user, req);
- }
-
- canUserPurchase (user, item) {
-@@ -150,20 +119,11 @@ export class AbstractGoldItemOperation extends AbstractBuyOperation {
+@@ -146,15 +116,6 @@ export class AbstractGoldItemOperation extends AbstractBuyOperation {
user.stats.gp -= itemValue * this.quantity;
}
@@ -4524,14 +4827,7 @@ index 3f87f08694..79533d4c20 100644
}
export class AbstractGemItemOperation extends AbstractBuyOperation {
-- constructor (user, req, analytics) {
-- super(user, req, analytics);
-+ constructor (user, req) {
-+ super(user, req);
- }
-
- canUserPurchase (user, item) {
-@@ -184,20 +144,11 @@ export class AbstractGemItemOperation extends AbstractBuyOperation {
+@@ -176,15 +137,6 @@ export class AbstractGemItemOperation extends AbstractBuyOperation {
user.balance -= itemValue * this.quantity;
}
@@ -4547,16 +4843,9 @@ index 3f87f08694..79533d4c20 100644
}
export class AbstractHourglassItemOperation extends AbstractBuyOperation {
-- constructor (user, req, analytics) {
-- super(user, req, analytics);
-+ constructor (user, req) {
-+ super(user, req);
- }
-
- canUserPurchase (user, item) {
-@@ -211,11 +162,4 @@ export class AbstractHourglassItemOperation extends AbstractBuyOperation {
- subtractCurrency (user) {
- user.purchased.plan.consecutive.trinkets--;
+@@ -199,11 +151,4 @@ export class AbstractHourglassItemOperation extends AbstractBuyOperation {
+ subtractCurrency (user) { // eslint-disable-line class-methods-use-this
+ user.purchased.plan.consecutive.trinkets -= 1;
}
-
- analyticsData () {
@@ -4567,19 +4856,19 @@ index 3f87f08694..79533d4c20 100644
- }
}
diff --git a/website/common/script/ops/buy/buy.js b/website/common/script/ops/buy/buy.js
-index b0cc98c053..e3160b2561 100644
+index 7b9795986d..6f08b72b2e 100644
--- a/website/common/script/ops/buy/buy.js
+++ b/website/common/script/ops/buy/buy.js
-@@ -20,7 +20,7 @@ import {BuyHourglassMountOperation} from './buyMount';
-
+@@ -21,7 +21,7 @@ import { BuyHourglassMountOperation } from './buyMount';
// @TODO: when we are sure buy is the only function used, let's move the buy files to a folder
--module.exports = function buy (user, req = {}, analytics, options = {quantity: 1, hourglass: false}) {
-+module.exports = function buy (user, req = {}, options = {quantity: 1, hourglass: false}) {
- let key = get(req, 'params.key');
- const hourglass = options.hourglass;
- const quantity = options.quantity;
-@@ -36,31 +36,31 @@ module.exports = function buy (user, req = {}, analytics, options = {quantity: 1
+ export default function buy (
+- user, req = {}, analytics, options = { quantity: 1, hourglass: false },
++ user, req = {}, options = { quantity: 1, hourglass: false },
+ ) {
+ const key = get(req, 'params.key');
+ const { hourglass } = options;
+@@ -38,31 +38,31 @@ export default function buy (
switch (type) {
case 'armoire': {
@@ -4617,7 +4906,7 @@ index b0cc98c053..e3160b2561 100644
buyRes = buyOp.purchase();
}
-@@ -71,31 +71,31 @@ module.exports = function buy (user, req = {}, analytics, options = {quantity: 1
+@@ -73,31 +73,31 @@ export default function buy (
case 'food':
case 'gear':
case 'bundles':
@@ -4656,21 +4945,10 @@ index b0cc98c053..e3160b2561 100644
buyRes = buyOp.purchase();
break;
diff --git a/website/common/script/ops/buy/buyArmoire.js b/website/common/script/ops/buy/buyArmoire.js
-index cd4eb796af..2c38cbfc9c 100644
+index 97d5213aca..76bc67d2e4 100644
--- a/website/common/script/ops/buy/buyArmoire.js
+++ b/website/common/script/ops/buy/buyArmoire.js
-@@ -18,8 +18,8 @@ const YIELD_EQUIPMENT_THRESHOLD = 0.6;
- const YIELD_FOOD_THRESHOLD = 0.8;
-
- export class BuyArmoireOperation extends AbstractGoldItemOperation {
-- constructor (user, req, analytics) {
-- super(user, req, analytics);
-+ constructor (user, req) {
-+ super(user, req);
- }
-
- multiplePurchaseAllowed () {
-@@ -68,19 +68,6 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation {
+@@ -69,19 +69,6 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation { // eslint-d
];
}
@@ -4689,8 +4967,8 @@ index cd4eb796af..2c38cbfc9c 100644
-
_gearResult (user, eligibleEquipment) {
eligibleEquipment.sort();
- let drop = randomVal(eligibleEquipment);
-@@ -104,10 +91,6 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation {
+ const drop = randomVal(eligibleEquipment);
+@@ -105,10 +92,6 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation { // eslint-d
removeItemByPath(user, `gear.flat.${drop.key}`);
@@ -4698,10 +4976,10 @@ index cd4eb796af..2c38cbfc9c 100644
- this._trackDropAnalytics(user._id, drop.key);
- }
-
- let armoireResp = {
+ const armoireResp = {
type: 'gear',
dropKey: drop.key,
-@@ -129,10 +112,6 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation {
+@@ -130,10 +113,6 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation { // eslint-d
user.items.food[drop.key] += 1;
if (user.markModified) user.markModified('items.food');
@@ -4713,99 +4991,47 @@ index cd4eb796af..2c38cbfc9c 100644
message: this.i18n('armoireFood', {
image: `<span class="Pet_Food_${drop.key} pull-left"></span>`,
diff --git a/website/common/script/ops/buy/buyGem.js b/website/common/script/ops/buy/buyGem.js
-index b2ea03046e..81fa5be9da 100644
+index e2793fcb35..7a7255c021 100644
--- a/website/common/script/ops/buy/buyGem.js
+++ b/website/common/script/ops/buy/buyGem.js
-@@ -9,8 +9,8 @@ import get from 'lodash/get';
- import planGemLimits from '../../libs/planGemLimits';
-
- export class BuyGemOperation extends AbstractGoldItemOperation {
-- constructor (user, req, analytics) {
-- super(user, req, analytics);
-+ constructor (user, req) {
-+ super(user, req);
- }
-
- multiplePurchaseAllowed () {
-@@ -72,8 +72,4 @@ export class BuyGemOperation extends AbstractGoldItemOperation {
- this.i18n('plusGem', {count: this.quantity}),
+@@ -69,8 +69,4 @@ export class BuyGemOperation extends AbstractGoldItemOperation { // eslint-disab
+ this.i18n('plusGem', { count: this.quantity }),
];
}
-
-- analyticsLabel () {
+- analyticsLabel () { // eslint-disable-line class-methods-use-this
- return 'purchase gems';
- }
}
-diff --git a/website/common/script/ops/buy/buyHealthPotion.js b/website/common/script/ops/buy/buyHealthPotion.js
-index e3d6c1062a..5bd6cf4b5c 100644
---- a/website/common/script/ops/buy/buyHealthPotion.js
-+++ b/website/common/script/ops/buy/buyHealthPotion.js
-@@ -6,8 +6,8 @@ import {
- import { AbstractGoldItemOperation} from './abstractBuyOperation';
-
- export class BuyHealthPotionOperation extends AbstractGoldItemOperation {
-- constructor (user, req, analytics) {
-- super(user, req, analytics);
-+ constructor (user, req) {
-+ super(user, req);
- }
-
- multiplePurchaseAllowed () {
-diff --git a/website/common/script/ops/buy/buyMarketGear.js b/website/common/script/ops/buy/buyMarketGear.js
-index 5f8728bf53..7660de1c46 100644
---- a/website/common/script/ops/buy/buyMarketGear.js
-+++ b/website/common/script/ops/buy/buyMarketGear.js
-@@ -16,8 +16,8 @@ import { AbstractGoldItemOperation } from './abstractBuyOperation';
- import errorMessage from '../../libs/errorMessage';
-
- export class BuyMarketGearOperation extends AbstractGoldItemOperation {
-- constructor (user, req, analytics) {
-- super(user, req, analytics);
-+ constructor (user, req) {
-+ super(user, req);
- }
-
- multiplePurchaseAllowed () {
diff --git a/website/common/script/ops/buy/buyMount.js b/website/common/script/ops/buy/buyMount.js
-index ced5cddfc8..81cf05f16f 100644
+index 660b78b1dd..4cbe12b6c1 100644
--- a/website/common/script/ops/buy/buyMount.js
+++ b/website/common/script/ops/buy/buyMount.js
-@@ -10,8 +10,8 @@ import includes from 'lodash/includes';
- import keys from 'lodash/keys';
-
- export class BuyHourglassMountOperation extends AbstractHourglassItemOperation {
-- constructor (user, req, analytics) {
-- super(user, req, analytics);
-+ constructor (user, req) {
-+ super(user, req);
- }
-
- multiplePurchaseAllowed () {
-@@ -50,10 +50,4 @@ export class BuyHourglassMountOperation extends AbstractHourglassItemOperation {
+@@ -47,10 +47,4 @@ export class BuyHourglassMountOperation extends AbstractHourglassItemOperation {
message,
];
}
-
- analyticsData () {
-- let data = super.analyticsData();
+- const data = super.analyticsData();
- data.itemType = 'mounts';
- return data;
- }
}
diff --git a/website/common/script/ops/buy/buyMysterySet.js b/website/common/script/ops/buy/buyMysterySet.js
-index db9ca557f2..e8098e7b23 100644
+index 018322cba8..11514058e8 100644
--- a/website/common/script/ops/buy/buyMysterySet.js
+++ b/website/common/script/ops/buy/buyMysterySet.js
@@ -9,7 +9,7 @@ import {
} from '../../libs/errors';
import errorMessage from '../../libs/errorMessage';
--module.exports = function buyMysterySet (user, req = {}, analytics) {
-+module.exports = function buyMysterySet (user, req = {}) {
- let key = get(req, 'params.key');
+-export default function buyMysterySet (user, req = {}, analytics) {
++export default function buyMysterySet (user, req = {}) {
+ const key = get(req, 'params.key');
if (!key) throw new BadRequest(errorMessage('missingKeyParam'));
-@@ -26,16 +26,6 @@ module.exports = function buyMysterySet (user, req = {}, analytics) {
+@@ -26,16 +26,6 @@ export default function buyMysterySet (user, req = {}, analytics) {
each(mysterySet.items, item => {
user.items.gear.owned[item.key] = true;
@@ -4822,65 +5048,20 @@ index db9ca557f2..e8098e7b23 100644
});
if (user.markModified) user.markModified('items.gear.owned');
-diff --git a/website/common/script/ops/buy/buyQuestGem.js b/website/common/script/ops/buy/buyQuestGem.js
-index 63ba528ce3..c772e979ca 100644
---- a/website/common/script/ops/buy/buyQuestGem.js
-+++ b/website/common/script/ops/buy/buyQuestGem.js
-@@ -10,8 +10,8 @@ import errorMessage from '../../libs/errorMessage';
- import {AbstractGemItemOperation} from './abstractBuyOperation';
-
- export class BuyQuestWithGemOperation extends AbstractGemItemOperation {
-- constructor (user, req, analytics) {
-- super(user, req, analytics);
-+ constructor (user, req) {
-+ super(user, req);
- }
-
- multiplePurchaseAllowed () {
-diff --git a/website/common/script/ops/buy/buyQuestGold.js b/website/common/script/ops/buy/buyQuestGold.js
-index 09f04dcb59..68c47fcbfa 100644
---- a/website/common/script/ops/buy/buyQuestGold.js
-+++ b/website/common/script/ops/buy/buyQuestGold.js
-@@ -10,8 +10,8 @@ import {AbstractGoldItemOperation} from './abstractBuyOperation';
- import errorMessage from '../../libs/errorMessage';
-
- export class BuyQuestWithGoldOperation extends AbstractGoldItemOperation {
-- constructor (user, req, analytics) {
-- super(user, req, analytics);
-+ constructor (user, req) {
-+ super(user, req);
- }
-
- multiplePurchaseAllowed () {
-diff --git a/website/common/script/ops/buy/buySpell.js b/website/common/script/ops/buy/buySpell.js
-index 46e73a5d81..5397b50125 100644
---- a/website/common/script/ops/buy/buySpell.js
-+++ b/website/common/script/ops/buy/buySpell.js
-@@ -10,8 +10,8 @@ import {AbstractGoldItemOperation} from './abstractBuyOperation';
- import errorMessage from '../../libs/errorMessage';
-
- export class BuySpellOperation extends AbstractGoldItemOperation {
-- constructor (user, req, analytics) {
-- super(user, req, analytics);
-+ constructor (user, req) {
-+ super(user, req);
- }
-
- getItemKey () {
diff --git a/website/common/script/ops/buy/hourglassPurchase.js b/website/common/script/ops/buy/hourglassPurchase.js
-index 61ae2de568..8fb20a844d 100644
+index f721acbc43..68e7c2b52f 100644
--- a/website/common/script/ops/buy/hourglassPurchase.js
+++ b/website/common/script/ops/buy/hourglassPurchase.js
@@ -9,7 +9,7 @@ import {
} from '../../libs/errors';
import errorMessage from '../../libs/errorMessage';
--module.exports = function purchaseHourglass (user, req = {}, analytics, quantity = 1) {
-+module.exports = function purchaseHourglass (user, req = {}, quantity = 1) {
- let key = get(req, 'params.key');
+-export default function purchaseHourglass (user, req = {}, analytics, quantity = 1) {
++export default function purchaseHourglass (user, req = {}, quantity = 1) {
+ const key = get(req, 'params.key');
if (!key) throw new BadRequest(errorMessage('missingKeyParam'));
-@@ -57,17 +57,6 @@ module.exports = function purchaseHourglass (user, req = {}, analytics, quantity
+@@ -57,17 +57,6 @@ export default function purchaseHourglass (user, req = {}, analytics, quantity =
}
}
@@ -4899,19 +5080,19 @@ index 61ae2de568..8fb20a844d 100644
{ items: user.items, purchasedPlanConsecutive: user.purchased.plan.consecutive },
i18n.t('hourglassPurchase', req.language),
diff --git a/website/common/script/ops/buy/purchase.js b/website/common/script/ops/buy/purchase.js
-index 20975506f0..e0ae2111e8 100644
+index f4156f7683..5ec65bf9de 100644
--- a/website/common/script/ops/buy/purchase.js
+++ b/website/common/script/ops/buy/purchase.js
@@ -68,7 +68,7 @@ function purchaseItem (user, item, price, type, key) {
const acceptedTypes = ['eggs', 'hatchingPotions', 'food', 'gear', 'bundles'];
const singlePurchaseTypes = ['gear'];
--module.exports = function purchase (user, req = {}, analytics) {
-+module.exports = function purchase (user, req = {}) {
- let type = get(req.params, 'type');
- let key = get(req.params, 'key');
+-export default function purchase (user, req = {}, analytics) {
++export default function purchase (user, req = {}) {
+ const type = get(req.params, 'type');
+ const key = get(req.params, 'key');
-@@ -106,19 +106,6 @@ module.exports = function purchase (user, req = {}, analytics) {
+@@ -106,19 +106,6 @@ export default function purchase (user, req = {}, analytics) {
purchaseItem(user, item, price, type, key);
}
@@ -4932,22 +5113,23 @@ index 20975506f0..e0ae2111e8 100644
pick(user, splitWhitespace('items balance')),
];
diff --git a/website/common/script/ops/changeClass.js b/website/common/script/ops/changeClass.js
-index 49af6f481a..5704f92f81 100644
+index 460786c6bd..08f242beaf 100644
--- a/website/common/script/ops/changeClass.js
+++ b/website/common/script/ops/changeClass.js
-@@ -33,18 +33,17 @@ function resetClass (user, req = {}) {
+@@ -33,19 +33,18 @@ function resetClass (user, req = {}) {
return balanceRemoved;
}
--module.exports = function changeClass (user, req = {}, analytics) {
-+module.exports = function changeClass (user, req = {}) {
- let klass = get(req, 'query.class');
+-export default function changeClass (user, req = {}, analytics) {
++export default function changeClass (user, req = {}) {
+ const klass = get(req, 'query.class');
- let balanceRemoved = 0;
// user.flags.classSelected is set to false after the user paid the 3 gems
if (user.stats.lvl < 10) {
throw new NotAuthorized(i18n.t('lvl10ChangeClass', req.language));
} else if (!klass) {
- // if no class is specified, reset points and set user.flags.classSelected to false. User will have paid 3 gems and will be prompted to select class.
+ // if no class is specified, reset points and set user.flags.classSelected to false.
+ // User will have paid 3 gems and will be prompted to select class.
- balanceRemoved = resetClass(user, req);
+ resetClass(user, req);
} else if (klass === 'warrior' || klass === 'rogue' || klass === 'wizard' || klass === 'healer') {
@@ -4957,7 +5139,7 @@ index 49af6f481a..5704f92f81 100644
}
user.stats.class = klass;
-@@ -57,17 +56,6 @@ module.exports = function changeClass (user, req = {}, analytics) {
+@@ -58,17 +57,6 @@ export default function changeClass (user, req = {}, analytics) {
if (user.markModified) user.markModified('items.gear.owned');
removePinnedItemsByOwnedGear(user);
@@ -4976,19 +5158,19 @@ index 49af6f481a..5704f92f81 100644
// if invalid class is specified, throw an error.
throw new BadRequest(i18n.t('invalidClass', req.language));
diff --git a/website/common/script/ops/openMysteryItem.js b/website/common/script/ops/openMysteryItem.js
-index b2cf4ea561..b47a5813dd 100644
+index 0ab7926c40..7e42b13d81 100644
--- a/website/common/script/ops/openMysteryItem.js
+++ b/website/common/script/ops/openMysteryItem.js
-@@ -13,7 +13,7 @@ function markNotificationAsRead (user) {
+@@ -11,7 +11,7 @@ function markNotificationAsRead (user) {
if (index !== -1) user.notifications.splice(index, 1);
}
--module.exports = function openMysteryItem (user, req = {}, analytics) {
-+module.exports = function openMysteryItem (user, req = {}) {
- const mysteryItems = user.purchased.plan.mysteryItems;
+-export default function openMysteryItem (user, req = {}, analytics) {
++export default function openMysteryItem (user, req = {}) {
+ const { mysteryItems } = user.purchased.plan;
let item = mysteryItems.shift();
-@@ -32,17 +32,6 @@ module.exports = function openMysteryItem (user, req = {}, analytics) {
+@@ -30,17 +30,6 @@ export default function openMysteryItem (user, req = {}, analytics) {
user.markModified('items.gear.owned');
}
@@ -5007,22 +5189,22 @@ index b2cf4ea561..b47a5813dd 100644
item,
i18n.t('mysteryItemOpened', req.language),
diff --git a/website/common/script/ops/rebirth.js b/website/common/script/ops/rebirth.js
-index 02207c4ac4..0878130424 100644
+index 4d3c57ce23..84a1eefd95 100644
--- a/website/common/script/ops/rebirth.js
+++ b/website/common/script/ops/rebirth.js
@@ -11,30 +11,15 @@ import isFreeRebirth from '../libs/isFreeRebirth';
const USERSTATSLIST = ['per', 'int', 'con', 'str', 'points', 'gp', 'exp', 'mp'];
--module.exports = function rebirth (user, tasks = [], req = {}, analytics) {
-+module.exports = function rebirth (user, tasks = [], req = {}) {
+-export default function rebirth (user, tasks = [], req = {}, analytics) {
++export default function rebirth (user, tasks = [], req = {}) {
const notFree = !isFreeRebirth(user);
if (user.balance < 1.5 && notFree) {
throw new NotAuthorized(i18n.t('notEnoughGems', req.language));
}
-- let analyticsData = {
+- const analyticsData = {
- uuid: user._id,
- category: 'behavior',
- };
@@ -5041,12 +5223,12 @@ index 02207c4ac4..0878130424 100644
- analytics.track('Rebirth', analyticsData);
}
- let lvl = capByLevel(user.stats.lvl);
+ const lvl = capByLevel(user.stats.lvl);
diff --git a/website/common/script/ops/releaseBoth.js b/website/common/script/ops/releaseBoth.js
-index 75aa65abd7..9722d4e952 100644
+index 80a7c81241..b7f532b21d 100644
--- a/website/common/script/ops/releaseBoth.js
+++ b/website/common/script/ops/releaseBoth.js
-@@ -22,21 +22,6 @@ module.exports = function releaseBoth (user, req = {}) {
+@@ -23,21 +23,6 @@ export default function releaseBoth (user, req = {}) {
let giveBeastMasterAchievement = true;
let giveMountMasterAchievement = true;
@@ -5065,24 +5247,24 @@ index 75aa65abd7..9722d4e952 100644
- // user.balance -= 1.5;
- // }
-
- let mountInfo = content.mountInfo[user.items.currentMount];
+ const mountInfo = content.mountInfo[user.items.currentMount];
if (mountInfo && mountInfo.type === 'drop') {
diff --git a/website/common/script/ops/releaseMounts.js b/website/common/script/ops/releaseMounts.js
-index adb9d96dfd..8cd3e11625 100644
+index b41e50d861..b6a38a4fe4 100644
--- a/website/common/script/ops/releaseMounts.js
+++ b/website/common/script/ops/releaseMounts.js
@@ -5,7 +5,7 @@ import {
NotAuthorized,
} from '../libs/errors';
--module.exports = function releaseMounts (user, req = {}, analytics) {
-+module.exports = function releaseMounts (user, req = {}) {
+-export default function releaseMounts (user, req = {}, analytics) {
++export default function releaseMounts (user, req = {}) {
if (user.balance < 1) {
throw new NotAuthorized(i18n.t('notEnoughGems', req.language));
}
-@@ -39,16 +39,6 @@ module.exports = function releaseMounts (user, req = {}, analytics) {
- user.achievements.mountMasterCount++;
+@@ -40,16 +40,6 @@ export default function releaseMounts (user, req = {}, analytics) {
+ user.achievements.mountMasterCount += 1;
}
- if (analytics) {
@@ -5099,20 +5281,20 @@ index adb9d96dfd..8cd3e11625 100644
user.items.mounts,
i18n.t('mountsReleased'),
diff --git a/website/common/script/ops/releasePets.js b/website/common/script/ops/releasePets.js
-index 0764fddb62..955a91f4a0 100644
+index df7596a1a3..2ad527890b 100644
--- a/website/common/script/ops/releasePets.js
+++ b/website/common/script/ops/releasePets.js
@@ -5,7 +5,7 @@ import {
NotAuthorized,
} from '../libs/errors';
--module.exports = function releasePets (user, req = {}, analytics) {
-+module.exports = function releasePets (user, req = {}) {
+-export default function releasePets (user, req = {}, analytics) {
++export default function releasePets (user, req = {}) {
if (user.balance < 1) {
throw new NotAuthorized(i18n.t('notEnoughGems', req.language));
}
-@@ -39,16 +39,6 @@ module.exports = function releasePets (user, req = {}, analytics) {
- user.achievements.beastMasterCount++;
+@@ -40,16 +40,6 @@ export default function releasePets (user, req = {}, analytics) {
+ user.achievements.beastMasterCount += 1;
}
- if (analytics) {
@@ -5129,19 +5311,19 @@ index 0764fddb62..955a91f4a0 100644
user.items.pets,
i18n.t('petsReleased'),
diff --git a/website/common/script/ops/reroll.js b/website/common/script/ops/reroll.js
-index 9f8da0c839..ffe9e2c5c0 100644
+index faf89ba68a..c928ddb32b 100644
--- a/website/common/script/ops/reroll.js
+++ b/website/common/script/ops/reroll.js
@@ -4,7 +4,7 @@ import {
NotAuthorized,
} from '../libs/errors';
--module.exports = function reroll (user, tasks = [], req = {}, analytics) {
-+module.exports = function reroll (user, tasks = [], req = {}) {
+-export default function reroll (user, tasks = [], req = {}, analytics) {
++export default function reroll (user, tasks = [], req = {}) {
if (user.balance < 1) {
throw new NotAuthorized(i18n.t('notEnoughGems', req.language));
}
-@@ -20,16 +20,6 @@ module.exports = function reroll (user, tasks = [], req = {}, analytics) {
+@@ -20,16 +20,6 @@ export default function reroll (user, tasks = [], req = {}, analytics) {
}
});
@@ -5156,23 +5338,23 @@ index 9f8da0c839..ffe9e2c5c0 100644
- }
-
return [
- {user, tasks},
+ { user, tasks },
i18n.t('fortifyComplete'),
diff --git a/website/common/script/ops/revive.js b/website/common/script/ops/revive.js
-index 14ad3d1ddd..8714b0d356 100644
+index e8ce46010b..8e000c3952 100644
--- a/website/common/script/ops/revive.js
+++ b/website/common/script/ops/revive.js
@@ -12,7 +12,7 @@ import predictableRandom from '../fns/predictableRandom';
import { removePinnedGearByClass, addPinnedGearByClass, addPinnedGear } from './pinnedGearUtils';
import getItemInfo from '../libs/getItemInfo';
--module.exports = function revive (user, req = {}, analytics) {
-+module.exports = function revive (user, req = {}) {
+-export default function revive (user, req = {}, analytics) {
++export default function revive (user, req = {}) {
if (user.stats.hp > 0) {
throw new NotAuthorized(i18n.t('cannotRevive', req.language));
}
-@@ -105,16 +105,6 @@ module.exports = function revive (user, req = {}, analytics) {
- message = i18n.t('messageLostItem', { itemText: item.text(req.language)}, req.language);
+@@ -108,16 +108,6 @@ export default function revive (user, req = {}, analytics) {
+ message = i18n.t('messageLostItem', { itemText: item.text(req.language) }, req.language);
}
- if (analytics) {
@@ -5189,10 +5371,10 @@ index 14ad3d1ddd..8714b0d356 100644
user.items,
message,
diff --git a/website/common/script/ops/scoreTask.js b/website/common/script/ops/scoreTask.js
-index abe6ccf0fc..48baa4a2af 100644
+index bee17ba957..736656b3c2 100644
--- a/website/common/script/ops/scoreTask.js
+++ b/website/common/script/ops/scoreTask.js
-@@ -327,7 +327,6 @@ module.exports = function scoreTask (options = {}, req = {}) {
+@@ -341,7 +341,6 @@ export default function scoreTask (options = {}, req = {}) {
}
}
@@ -5200,14 +5382,14 @@ index abe6ccf0fc..48baa4a2af 100644
- updateStats(user, stats, req);
+ updateStats(user, stats);
return [delta];
- };
+ }
diff --git a/website/common/script/ops/sleep.js b/website/common/script/ops/sleep.js
-index e80f766b0a..48a283ce29 100644
+index 15e49c80a0..5ade69adc8 100644
--- a/website/common/script/ops/sleep.js
+++ b/website/common/script/ops/sleep.js
@@ -1,14 +1,4 @@
--module.exports = function sleep (user, req = {}, analytics) {
-+module.exports = function sleep (user) {
+-export default function sleep (user, req = {}, analytics) {
++export default function sleep (user, req = {}) {
user.preferences.sleep = !user.preferences.sleep;
-
- if (analytics) {
@@ -5220,21 +5402,21 @@ index e80f766b0a..48a283ce29 100644
- }
-
return [user.preferences.sleep];
- };
+ }
diff --git a/website/common/script/ops/unlock.js b/website/common/script/ops/unlock.js
-index 7adbac48de..bbdb7ea6fc 100644
+index 48720322b0..cec84773b4 100644
--- a/website/common/script/ops/unlock.js
+++ b/website/common/script/ops/unlock.js
@@ -15,7 +15,7 @@ import content from '../content/index';
// If item is already purchased -> equip it
// Otherwise unlock it
--module.exports = function unlock (user, req = {}, analytics) {
-+module.exports = function unlock (user, req = {}) {
- let path = get(req.query, 'path');
+-export default function unlock (user, req = {}, analytics) {
++export default function unlock (user, req = {}) {
+ const path = get(req.query, 'path');
if (!path) {
-@@ -117,18 +117,6 @@ module.exports = function unlock (user, req = {}, analytics) {
+@@ -118,18 +118,6 @@ export default function unlock (user, req = {}, analytics) {
}
user.balance -= cost;
@@ -5252,9 +5434,9 @@ index 7adbac48de..bbdb7ea6fc 100644
- }
}
- let response = [
+ const response = [
diff --git a/website/server/controllers/api-v3/auth.js b/website/server/controllers/api-v3/auth.js
-index 9d5d2a4977..3e3544aa34 100644
+index 8113eb1c25..86269e9c10 100644
--- a/website/server/controllers/api-v3/auth.js
+++ b/website/server/controllers/api-v3/auth.js
@@ -5,7 +5,6 @@ import {
@@ -5265,7 +5447,7 @@ index 9d5d2a4977..3e3544aa34 100644
import {
NotAuthorized,
BadRequest,
-@@ -16,8 +15,6 @@ import { validatePasswordResetCodeAndFindUser, convertToBcrypt} from '../../libs
+@@ -15,8 +14,6 @@ import { sendTxn as sendTxnEmail } from '../../libs/email';
import { encrypt } from '../../libs/encryption';
import {
loginRes,
@@ -5273,28 +5455,30 @@ index 9d5d2a4977..3e3544aa34 100644
- loginSocial,
registerLocal,
} from '../../libs/auth';
- import {verifyUsername} from '../../libs/user/validation';
-@@ -29,7 +26,7 @@ let api = {};
+ import { verifyUsername } from '../../libs/user/validation';
+@@ -28,8 +25,7 @@ const api = {};
/**
* @api {post} /api/v3/user/auth/local/register Register
-- * @apiDescription Register a new user with email, login name, and password or attach local auth to a social user
+- * @apiDescription Register a new user with email, login name, and password or
+- * attach local auth to a social user
+ * @apiDescription Register a new user with email, login name, and password
* @apiName UserRegisterLocal
* @apiGroup User
*
-@@ -38,7 +35,7 @@ let api = {};
+@@ -40,8 +36,7 @@ const api = {};
* @apiParam (Body) {String} password Password for the new user
* @apiParam (Body) {String} confirmPassword Password confirmation
*
-- * @apiSuccess {Object} data The user object, if local auth was just attached to a social user then only user.auth.local
+- * @apiSuccess {Object} data The user object, if local auth was just
+- * attached to a social user then only user.auth.local
+ * @apiSuccess {Object} data The user object
*/
api.registerLocal = {
method: 'POST',
-@@ -98,8 +95,7 @@ api.loginLocal = {
+@@ -103,8 +98,7 @@ api.loginLocal = {
// load the entire user because we may have to save it to convert the password to bcrypt
- let user = await User.findOne(login).exec();
+ const user = await User.findOne(login).exec();
- // if user is using social login, then user will not have a hashed_password stored
- if (!user || !user.auth.local.hashed_password) throw new NotAuthorized(res.t('invalidLoginCredentialsLong'));
@@ -5302,7 +5486,7 @@ index 9d5d2a4977..3e3544aa34 100644
let isValidPassword;
-@@ -117,30 +113,10 @@ api.loginLocal = {
+@@ -122,30 +116,10 @@ api.loginLocal = {
await user.save();
}
@@ -5314,7 +5498,7 @@ index 9d5d2a4977..3e3544aa34 100644
- headers: req.headers,
- });
-
- return loginRes(user, ...arguments);
+ return loginRes(user, req, res);
},
};
@@ -5326,20 +5510,21 @@ index 9d5d2a4977..3e3544aa34 100644
- })],
- url: '/user/auth/social',
- async handler (req, res) {
-- return await loginSocial(req, res);
+- await loginSocial(req, res);
- },
-};
-
/**
* @api {put} /api/v3/user/auth/update-username Update username
* @apiDescription Update the username of a local user
-@@ -403,33 +379,4 @@ api.resetPasswordSetNewOne = {
+@@ -408,33 +382,4 @@ api.resetPasswordSetNewOne = {
},
};
-/**
- * @api {delete} /api/v3/user/auth/social/:network Delete social authentication method
-- * @apiDescription Remove a social authentication method (only facebook supported) from a user profile. The user must have local authentication enabled
+- * @apiDescription Remove a social authentication method (only facebook supported)
+- * from a user profile. The user must have local authentication enabled
- * @apiName UserDeleteSocial
- * @apiGroup User
- *
@@ -5350,28 +5535,27 @@ index 9d5d2a4977..3e3544aa34 100644
- url: '/user/auth/social/:network',
- middlewares: [authWithHeaders()],
- async handler (req, res) {
-- let user = res.locals.user;
-- let network = req.params.network;
-- let isSupportedNetwork = common.constants.SUPPORTED_SOCIAL_NETWORKS.find(supportedNetwork => {
-- return supportedNetwork.key === network;
-- });
+- const { user } = res.locals;
+- const { network } = req.params;
+- const isSupportedNetwork = common.constants.SUPPORTED_SOCIAL_NETWORKS
+- .find(supportedNetwork => supportedNetwork.key === network);
- if (!isSupportedNetwork) throw new BadRequest(res.t('unsupportedNetwork'));
- if (!hasBackupAuth(user, network)) throw new NotAuthorized(res.t('cantDetachSocial'));
-- let unset = {
+- const unset = {
- [`auth.${network}`]: 1,
- };
-- await User.update({_id: user._id}, {$unset: unset}).exec();
+- await User.update({ _id: user._id }, { $unset: unset }).exec();
-
- res.respond(200, {});
- },
-};
-
- module.exports = api;
+ export default api;
diff --git a/website/server/controllers/api-v3/challenges.js b/website/server/controllers/api-v3/challenges.js
-index f0a60396a9..00b4ebd310 100644
+index 236bf198c4..207eeaa26f 100644
--- a/website/server/controllers/api-v3/challenges.js
+++ b/website/server/controllers/api-v3/challenges.js
-@@ -202,16 +202,6 @@ api.createChallenge = {
+@@ -212,16 +212,6 @@ api.createChallenge = {
};
response.group = getChallengeGroupResponse(group);
@@ -5388,9 +5572,9 @@ index f0a60396a9..00b4ebd310 100644
res.respond(201, response);
},
};
-@@ -261,16 +251,6 @@ api.joinChallenge = {
- let chalLeader = await User.findById(response.leader).select(nameFields).exec();
- response.leader = chalLeader ? chalLeader.toJSON({minimize: true}) : null;
+@@ -273,16 +263,6 @@ api.joinChallenge = {
+ const chalLeader = await User.findById(response.leader).select(nameFields).exec();
+ response.leader = chalLeader ? chalLeader.toJSON({ minimize: true }) : null;
- res.analytics.track('challenge join', {
- uuid: user._id,
@@ -5405,7 +5589,7 @@ index f0a60396a9..00b4ebd310 100644
res.respond(200, response);
},
};
-@@ -308,16 +288,6 @@ api.leaveChallenge = {
+@@ -322,16 +302,6 @@ api.leaveChallenge = {
// Unlink challenge's tasks from user's tasks and save the challenge
await challenge.unlinkTasks(user, keep);
@@ -5422,9 +5606,9 @@ index f0a60396a9..00b4ebd310 100644
res.respond(200, {});
},
};
-@@ -714,16 +684,6 @@ api.deleteChallenge = {
+@@ -747,16 +717,6 @@ api.deleteChallenge = {
// Close channel in background, some ops are run in the background without `await`ing
- await challenge.closeChal({broken: 'CHALLENGE_DELETED'});
+ await challenge.closeChal({ broken: 'CHALLENGE_DELETED' });
- res.analytics.track('challenge delete', {
- uuid: user._id,
@@ -5439,9 +5623,9 @@ index f0a60396a9..00b4ebd310 100644
res.respond(200, {});
},
};
-@@ -763,17 +723,6 @@ api.selectChallengeWinner = {
+@@ -796,17 +756,6 @@ api.selectChallengeWinner = {
// Close channel in background, some ops are run in the background without `await`ing
- await challenge.closeChal({broken: 'CHALLENGE_CLOSED', winner});
+ await challenge.closeChal({ broken: 'CHALLENGE_CLOSED', winner });
- res.analytics.track('challenge close', {
- uuid: user._id,
@@ -5458,27 +5642,18 @@ index f0a60396a9..00b4ebd310 100644
},
};
diff --git a/website/server/controllers/api-v3/chat.js b/website/server/controllers/api-v3/chat.js
-index e56337e76d..4534e45f39 100644
+index 1a4466e0cb..e3836558ec 100644
--- a/website/server/controllers/api-v3/chat.js
+++ b/website/server/controllers/api-v3/chat.js
-@@ -10,7 +10,6 @@ import {
+@@ -11,7 +11,6 @@ import {
} from '../../libs/errors';
import { removeFromArray } from '../../libs/collectionManipulators';
import { getUserInfo, getGroupUrl, sendTxn } from '../../libs/email';
--import slack from '../../libs/slack';
+-import * as slack from '../../libs/slack';
import { chatReporterFactory } from '../../libs/chatReporting/chatReporterFactory';
- import { getAuthorEmailFromMessage} from '../../libs/chat';
- import nconf from 'nconf';
-@@ -89,8 +88,6 @@ function getBannedWordsFromText (message) {
- return getMatchesByWordArray(message, bannedWords);
- }
-
--
--const mentionRegex = new RegExp('\\B@[-\\w]+', 'g');
- /**
- * @api {post} /api/v3/groups/:groupId/chat Post chat message to a group
- * @apiName PostChat
-@@ -150,14 +147,6 @@ api.postChat = {
+ import { getAuthorEmailFromMessage } from '../../libs/chat';
+ import bannedWords from '../../libs/bannedWords';
+@@ -151,14 +150,6 @@ api.postChat = {
sendTxn(FLAG_REPORT_EMAILS, 'slur-report-to-mods', report);
@@ -5493,7 +5668,7 @@ index e56337e76d..4534e45f39 100644
throw new BadRequest(res.t('bannedSlurUsed'));
}
-@@ -213,14 +202,6 @@ api.postChat = {
+@@ -217,14 +208,6 @@ api.postChat = {
];
sendTxn(FLAG_REPORT_EMAILS, 'shadow-muted-post-report-to-mods', report);
@@ -5507,12 +5682,12 @@ index e56337e76d..4534e45f39 100644
- });
}
- const newChatMessage = group.sendChat({message: req.body.message, user, flagCount, metaData: null, client, translate: res.t});
-@@ -233,27 +214,6 @@ api.postChat = {
+ const newChatMessage = group.sendChat({
+@@ -247,26 +230,6 @@ api.postChat = {
await Promise.all(toSave);
-- let analyticsObject = {
+- const analyticsObject = {
- uuid: user._id,
- hitType: 'event',
- category: 'behavior',
@@ -5521,7 +5696,6 @@ index e56337e76d..4534e45f39 100644
- headers: req.headers,
- };
-
-- const mentions = req.body.message.match(mentionRegex);
- if (mentions) {
- analyticsObject.mentionsCount = mentions.length;
- } else {
@@ -5534,41 +5708,42 @@ index e56337e76d..4534e45f39 100644
- res.analytics.track('group chat', analyticsObject);
-
if (chatUpdated) {
- res.respond(200, {chat: chatRes.chat});
+ res.respond(200, { chat: chatRes.chat });
} else {
diff --git a/website/server/controllers/api-v3/coupon.js b/website/server/controllers/api-v3/coupon.js
-index 7acc406a44..8a441b55e4 100644
+index eba36b7b23..758fa7ec1c 100644
--- a/website/server/controllers/api-v3/coupon.js
+++ b/website/server/controllers/api-v3/coupon.js
-@@ -58,7 +58,7 @@ api.getCoupons = {
+@@ -56,8 +56,8 @@ api.getCoupons = {
* @apiGroup Coupon
* @apiPermission sudo
*
-- * @apiParam (Path) {String=wondercon,google_6mo} event The event for which the coupon should be generated
-+ * @apiParam (Path) {String=wondercon} event The event for which the coupon should be generated
+- * @apiParam (Path) {String=wondercon,google_6mo} event The event for which the coupon
+- * should be generated
++ * @apiParam (Path) {String=wondercon} event The event for which the coupon
++ * should be generated
* @apiParam (Query) {Number} count The number of coupon codes to generate
*
* @apiSuccess {Array} data Generated coupons
diff --git a/website/server/controllers/api-v3/groups.js b/website/server/controllers/api-v3/groups.js
-index 41e1884ae5..262361ab39 100644
+index dbfaac3ba2..5ce1e243f5 100644
--- a/website/server/controllers/api-v3/groups.js
+++ b/website/server/controllers/api-v3/groups.js
-@@ -22,10 +22,6 @@ import {
+@@ -22,9 +22,6 @@ import {
inviteByUserName,
} from '../../libs/invites';
import common from '../../../common';
-import payments from '../../libs/payments/payments';
-import stripePayments from '../../libs/payments/stripe';
-import amzLib from '../../libs/payments/amazon';
--import shared from '../../../common';
import apiError from '../../libs/apiError';
+ import { model as UserNotification } from '../../models/userNotification';
- const MAX_EMAIL_INVITES_BY_USER = 200;
-@@ -147,22 +143,6 @@ api.createGroup = {
- profile: {name: user.profile.name},
+@@ -150,22 +147,6 @@ api.createGroup = {
+ profile: { name: user.profile.name },
};
-- let analyticsObject = {
+- const analyticsObject = {
- uuid: user._id,
- hitType: 'event',
- category: 'behavior',
@@ -5587,12 +5762,12 @@ index 41e1884ae5..262361ab39 100644
res.respond(201, response); // do not remove chat flags data as we've just created the group
},
};
-@@ -195,54 +175,6 @@ api.createGroupPlan = {
- let results = await Promise.all([user.save(), group.save()]);
- let savedGroup = results[1];
+@@ -198,56 +179,6 @@ api.createGroupPlan = {
+ const results = await Promise.all([user.save(), group.save()]);
+ const savedGroup = results[1];
- // Analytics
-- let analyticsObject = {
+- const analyticsObject = {
- uuid: user._id,
- hitType: 'event',
- category: 'behavior',
@@ -5604,13 +5779,13 @@ index 41e1884ae5..262361ab39 100644
- res.analytics.track('join group', analyticsObject);
-
- if (req.body.paymentType === 'Stripe') {
-- let token = req.body.id;
-- let gift = req.query.gift ? JSON.parse(req.query.gift) : undefined;
-- let sub = req.query.sub ? shared.content.subscriptionBlocks[req.query.sub] : false;
-- let groupId = savedGroup._id;
-- let email = req.body.email;
-- let headers = req.headers;
-- let coupon = req.query.coupon;
+- const token = req.body.id;
+- const gift = req.query.gift ? JSON.parse(req.query.gift) : undefined;
+- const sub = req.query.sub ? common.content.subscriptionBlocks[req.query.sub] : false;
+- const groupId = savedGroup._id;
+- const { email } = req.body;
+- const { headers } = req;
+- const { coupon } = req.query;
-
- await stripePayments.checkout({
- token,
@@ -5623,11 +5798,13 @@ index 41e1884ae5..262361ab39 100644
- coupon,
- });
- } else if (req.body.paymentType === 'Amazon') {
-- let billingAgreementId = req.body.billingAgreementId;
-- let sub = req.body.subscription ? shared.content.subscriptionBlocks[req.body.subscription] : false;
-- let coupon = req.body.coupon;
-- let groupId = savedGroup._id;
-- let headers = req.headers;
+- const { billingAgreementId } = req.body;
+- const sub = req.body.subscription
+- ? common.content.subscriptionBlocks[req.body.subscription]
+- : false;
+- const { coupon } = req.body;
+- const groupId = savedGroup._id;
+- const { headers } = req;
-
- await amzLib.subscribe({
- billingAgreementId,
@@ -5640,25 +5817,21 @@ index 41e1884ae5..262361ab39 100644
- }
-
// Instead of populate we make a find call manually because of https://github.com/Automattic/mongoose/issues/3833
- // await Q.ninvoke(savedGroup, 'populate', ['leader', nameFields]); // doc.populate doesn't return a promise
- let response = savedGroup.toJSON();
-@@ -618,10 +550,7 @@ api.joinGroup = {
-
+ // await Q.ninvoke(savedGroup, 'populate', ['leader', nameFields]);
+ // doc.populate doesn't return a promise
+@@ -682,7 +613,6 @@ api.joinGroup = {
promises = await Promise.all(promises);
-- if (group.hasNotCancelled()) {
+ if (group.hasNotCancelled()) {
- await payments.addSubToGroupUser(user, group);
-- await group.updateGroupPlan();
-- }
-+ if (group.hasNotCancelled()) await group.updateGroupPlan();
+ await group.updateGroupPlan();
+ }
- let response = await Group.toJSONCleanChat(promises[0], user);
- let leader = await User.findById(response.leader).select(nameFields).exec();
-@@ -629,22 +558,6 @@ api.joinGroup = {
- response.leader = leader.toJSON({minimize: true});
+@@ -692,22 +622,6 @@ api.joinGroup = {
+ response.leader = leader.toJSON({ minimize: true });
}
-- let analyticsObject = {
+- const analyticsObject = {
- uuid: user._id,
- hitType: 'event',
- category: 'behavior',
@@ -5677,11 +5850,11 @@ index 41e1884ae5..262361ab39 100644
res.respond(200, response);
},
};
-@@ -779,12 +692,7 @@ api.leaveGroup = {
+@@ -860,12 +774,7 @@ api.leaveGroup = {
if (guildIndex >= 0) user.guilds.splice(guildIndex, 1);
}
-- let isMemberOfGroupPlan = await user.isMemberOfGroupPlan();
+- const isMemberOfGroupPlan = await user.isMemberOfGroupPlan();
- if (!isMemberOfGroupPlan) {
- await payments.cancelGroupSubscriptionForUser(user, group);
- }
@@ -5691,21 +5864,21 @@ index 41e1884ae5..262361ab39 100644
res.respond(200, {});
},
};
-@@ -916,8 +824,7 @@ api.removeGroupMember = {
+@@ -1003,8 +912,7 @@ api.removeGroupMember = {
]);
- if (isInGroup && group.hasNotCancelled()) {
+ if (isInGroup && group.hasNotCancelled()) {
- await group.updateGroupPlan(true);
- await payments.cancelGroupSubscriptionForUser(member, group, true);
+ await group.updateGroupPlan();
}
res.respond(200, {});
-@@ -1060,16 +967,6 @@ api.inviteToGroup = {
+@@ -1163,16 +1071,6 @@ api.inviteToGroup = {
results.push(...usernameResults);
}
-- let analyticsObject = {
+- const analyticsObject = {
- uuid: user._id,
- hitType: 'event',
- category: 'behavior',
@@ -5719,7 +5892,7 @@ index 41e1884ae5..262361ab39 100644
},
};
diff --git a/website/server/controllers/api-v3/members.js b/website/server/controllers/api-v3/members.js
-index 3623477205..9c59c17a43 100644
+index 6d16734273..e02eee7277 100644
--- a/website/server/controllers/api-v3/members.js
+++ b/website/server/controllers/api-v3/members.js
@@ -18,7 +18,6 @@ import {
@@ -5727,42 +5900,42 @@ index 3623477205..9c59c17a43 100644
sendTxn as sendTxnEmail,
} from '../../libs/email';
-import { sendNotification as sendPushNotification } from '../../libs/pushNotifications';
- import { achievements } from '../../../../website/common/';
- import {sentMessage} from '../../libs/inbox';
-
-@@ -642,7 +641,7 @@ api.sendPrivateMessage = {
+ import common from '../../../common';
+ import { sentMessage } from '../../libs/inbox';
+ import { highlightMentions } from '../../libs/highlightMentions';
+@@ -686,7 +685,7 @@ api.sendPrivateMessage = {
const objections = sender.getObjectionsToInteraction('send-private-message', receiver);
if (objections.length > 0 && !sender.isAdmin()) throw new NotAuthorized(res.t(objections[0]));
- const messageSent = await sentMessage(sender, receiver, message, res.t);
+ const messageSent = await sentMessage(sender, receiver, message);
- res.respond(200, {message: messageSent});
+ res.respond(200, { message: messageSent });
},
-@@ -722,15 +721,6 @@ api.transferGems = {
- {name: 'X_GEMS_GIFTED', content: gemAmount},
+@@ -766,15 +765,6 @@ api.transferGems = {
+ { name: 'X_GEMS_GIFTED', content: gemAmount },
]);
}
- if (receiver.preferences.pushNotifications.giftedGems !== false) {
- sendPushNotification(receiver,
- {
- title: res.t('giftedGems', receiverLang),
-- message: res.t('giftedGemsInfo', {amount: gemAmount, name: byUsername}, receiverLang),
+- message: res.t('giftedGemsInfo', { amount: gemAmount, name: byUsername }, receiverLang),
- identifier: 'giftedGems',
-- payload: {replyTo: sender._id},
+- payload: { replyTo: sender._id },
- });
- }
res.respond(200, {});
},
diff --git a/website/server/controllers/api-v3/quests.js b/website/server/controllers/api-v3/quests.js
-index f43b5f7f6b..79fc1f036e 100644
+index 5b4c0322cb..9c163da1c4 100644
--- a/website/server/controllers/api-v3/quests.js
+++ b/website/server/controllers/api-v3/quests.js
@@ -1,6 +1,5 @@
import _ from 'lodash';
import { authWithHeaders } from '../../middlewares/auth';
--import analytics from '../../libs/analyticsService';
+-import * as analytics from '../../libs/analyticsService';
import {
model as Group,
basicFields as basicGroupFields,
@@ -5776,7 +5949,7 @@ index f43b5f7f6b..79fc1f036e 100644
const questScrolls = common.content.quests;
@@ -79,7 +77,7 @@ api.inviteToQuest = {
'party._id': group._id,
- _id: {$ne: user._id},
+ _id: { $ne: user._id },
})
- .select('auth.facebook auth.google auth.local preferences.emailNotifications preferences.pushNotifications preferences.language profile.name pushDevices')
+ .select('auth.local preferences.emailNotifications profile.name')
@@ -5785,8 +5958,8 @@ index f43b5f7f6b..79fc1f036e 100644
group.markModified('quest');
@@ -119,19 +117,6 @@ api.inviteToQuest = {
// send out invites
- let inviterVars = getUserInfo(user, ['name', 'email']);
- let membersToEmail = members.filter(member => {
+ const inviterVars = getUserInfo(user, ['name', 'email']);
+ const membersToEmail = members.filter(member => {
- // send push notifications while filtering members before sending emails
- if (member.preferences.pushNotifications.invitedQuest !== false) {
- sendPushNotification(
@@ -5796,7 +5969,7 @@ index f43b5f7f6b..79fc1f036e 100644
- message: res.t('questInvitationNotificationInfo', member.preferences.language),
- identifier: 'questInvitation',
- category: 'questInvitation',
-- }
+- },
- );
- }
-
@@ -5804,8 +5977,8 @@ index f43b5f7f6b..79fc1f036e 100644
});
sendTxnEmail(membersToEmail, `invite-${quest.boss ? 'boss' : 'collection'}-quest`, [
@@ -139,17 +124,6 @@ api.inviteToQuest = {
- {name: 'INVITER', content: inviterVars.name},
- {name: 'PARTY_URL', content: '/party'},
+ { name: 'INVITER', content: inviterVars.name },
+ { name: 'PARTY_URL', content: '/party' },
]);
-
- // track that the inviting user has accepted the quest
@@ -5822,7 +5995,7 @@ index f43b5f7f6b..79fc1f036e 100644
};
@@ -198,17 +172,6 @@ api.acceptQuest = {
- let savedGroup = await group.save();
+ const savedGroup = await group.save();
res.respond(200, savedGroup.quest);
-
@@ -5840,7 +6013,7 @@ index f43b5f7f6b..79fc1f036e 100644
};
@@ -258,16 +221,6 @@ api.rejectQuest = {
- let savedGroup = await group.save();
+ const savedGroup = await group.save();
res.respond(200, savedGroup.quest);
-
@@ -5856,7 +6029,7 @@ index f43b5f7f6b..79fc1f036e 100644
},
};
-@@ -317,16 +270,6 @@ api.forceStart = {
+@@ -319,16 +272,6 @@ api.forceStart = {
]);
res.respond(200, savedGroup.quest);
@@ -5874,21 +6047,13 @@ index f43b5f7f6b..79fc1f036e 100644
};
diff --git a/website/server/controllers/api-v3/tasks.js b/website/server/controllers/api-v3/tasks.js
-index 0eb220767f..c780161563 100644
+index f9f48ab5ad..6acee69699 100644
--- a/website/server/controllers/api-v3/tasks.js
+++ b/website/server/controllers/api-v3/tasks.js
-@@ -23,7 +23,6 @@ import {
- import common from '../../../common';
- import _ from 'lodash';
- import logger from '../../libs/logger';
--import moment from 'moment';
- import apiError from '../../libs/apiError';
-
- function canNotEditTasks (group, user, assignedUserId) {
-@@ -166,17 +165,6 @@ api.createUserTasks = {
+@@ -195,17 +195,6 @@ api.createUserTasks = {
res.respond(201, tasks.length === 1 ? tasks[0] : tasks);
- tasks.forEach((task) => {
+ tasks.forEach(task => {
- // Track when new users (first 7 days) create tasks
- if (moment().diff(user.auth.timestamps.created, 'days') < 7) {
- res.analytics.track('task create', {
@@ -5903,12 +6068,12 @@ index 0eb220767f..c780161563 100644
taskActivityWebhook.send(user, {
type: 'created',
task,
-@@ -252,16 +240,6 @@ api.createChallengeTasks = {
+@@ -316,16 +305,6 @@ api.createChallengeTasks = {
// If adding tasks to a challenge -> sync users
if (challenge) challenge.addTasks(tasks);
-
-- tasks.forEach((task) => {
+- tasks.forEach(task => {
- res.analytics.track('task create', {
- uuid: user._id,
- hitType: 'event',
@@ -5920,24 +6085,25 @@ index 0eb220767f..c780161563 100644
},
};
-@@ -587,7 +565,6 @@ api.scoreTask = {
+@@ -751,8 +730,6 @@ api.scoreTask = {
- let managers = await User.find({_id: managerIds}, 'notifications preferences').exec(); // Use this method so we can get access to notifications
+ const managers = await User.find({ _id: managerIds }, 'notifications preferences').exec(); // Use this method so we can get access to notifications
-- // @TODO: we can use the User.pushNotification function because we need to ensure notifications are translated
- let managerPromises = [];
- managers.forEach((manager) => {
+- // @TODO: we can use the User.pushNotification function because
+- // we need to ensure notifications are translated
+ const managerPromises = [];
+ managers.forEach(manager => {
manager.addNotification('GROUP_TASK_APPROVAL', {
-@@ -615,7 +592,7 @@ api.scoreTask = {
-
- let [delta] = common.ops.scoreTask({task, user, direction}, req);
- // Drop system (don't run on the client, as it would only be discarded since ops are sent to the API, not the results)
-- if (direction === 'up') common.fns.randomDrop(user, {task, delta}, req, res.analytics);
-+ if (direction === 'up') common.fns.randomDrop(user, {task, delta}, req);
+@@ -782,7 +759,7 @@ api.scoreTask = {
+ const [delta] = common.ops.scoreTask({ task, user, direction }, req);
+ // Drop system (don't run on the client,
+ // as it would only be discarded since ops are sent to the API, not the results)
+- if (direction === 'up') common.fns.randomDrop(user, { task, delta }, req, res.analytics);
++ if (direction === 'up') common.fns.randomDrop(user, { task, delta }, req);
// If a todo was completed or uncompleted move it in or out of the user.tasksOrder.todos list
// TODO move to common code?
-@@ -690,18 +667,6 @@ api.scoreTask = {
+@@ -864,18 +841,6 @@ api.scoreTask = {
logger.error(e);
}
}
@@ -5957,15 +6123,15 @@ index 0eb220767f..c780161563 100644
};
diff --git a/website/server/controllers/api-v3/tasks/groups.js b/website/server/controllers/api-v3/tasks/groups.js
-index 27fcc62db4..05164b41aa 100644
+index 1045860c42..f650a1cf0f 100644
--- a/website/server/controllers/api-v3/tasks/groups.js
+++ b/website/server/controllers/api-v3/tasks/groups.js
-@@ -60,16 +60,6 @@ api.createGroupTasks = {
- let tasks = await createTasks(req, res, {user, group});
+@@ -62,16 +62,6 @@ api.createGroupTasks = {
+ const tasks = await createTasks(req, res, { user, group });
res.respond(201, tasks.length === 1 ? tasks[0] : tasks);
-
-- tasks.forEach((task) => {
+- tasks.forEach(task => {
- res.analytics.track('task create', {
- uuid: user._id,
- hitType: 'event',
@@ -5978,18 +6144,18 @@ index 27fcc62db4..05164b41aa 100644
};
diff --git a/website/server/controllers/api-v3/user.js b/website/server/controllers/api-v3/user.js
-index c1b721650e..70cd50820c 100644
+index 1594e4fd7c..8f2a991b8e 100644
--- a/website/server/controllers/api-v3/user.js
+++ b/website/server/controllers/api-v3/user.js
-@@ -24,7 +24,6 @@ import nconf from 'nconf';
- import get from 'lodash/get';
+@@ -24,7 +24,6 @@ import * as inboxLib from '../../libs/inbox';
+ import * as userLib from '../../libs/user';
const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL');
-const DELETE_CONFIRMATION = 'DELETE';
/**
* @apiDefine UserNotFound
-@@ -56,7 +55,6 @@ let api = {};
+@@ -57,7 +56,6 @@ const api = {};
* Preferences (user selected prefs)
* Profile (name, photo url, blurb)
* Purchased (includes purchase history, gem purchased items, plans)
@@ -5997,16 +6163,16 @@ index c1b721650e..70cd50820c 100644
* Stats (standard RPG stats, class, buffs, xp, etc..)
* Tags
* TasksOrder (list of all ids for dailys, habits, rewards and todos)
-@@ -261,8 +259,6 @@ api.deleteUser = {
+@@ -274,8 +272,6 @@ api.deleteUser = {
if (user.auth.local.hashed_password && user.auth.local.email) {
- let isValidPassword = await passwordUtils.compare(user, password);
+ const isValidPassword = await passwordUtils.compare(user, password);
if (!isValidPassword) throw new NotAuthorized(res.t('wrongPassword'));
- } else if ((user.auth.facebook.id || user.auth.google.id) && password !== DELETE_CONFIRMATION) {
-- throw new NotAuthorized(res.t('incorrectDeletePhrase', {magicWord: 'DELETE'}));
+- throw new NotAuthorized(res.t('incorrectDeletePhrase', { magicWord: 'DELETE' }));
}
- let feedback = req.body.feedback;
-@@ -300,12 +296,6 @@ api.deleteUser = {
+ const { feedback } = req.body;
+@@ -311,12 +307,6 @@ api.deleteUser = {
]);
}
@@ -6019,7 +6185,7 @@ index c1b721650e..70cd50820c 100644
res.respond(200, {});
},
};
-@@ -347,8 +337,6 @@ api.getUserAnonymized = {
+@@ -358,8 +348,6 @@ api.getUserAnonymized = {
delete user.apiToken;
if (user.auth) {
delete user.auth.local;
@@ -6028,190 +6194,190 @@ index c1b721650e..70cd50820c 100644
}
delete user.newMessages;
delete user.profile;
-@@ -412,7 +400,7 @@ api.sleep = {
+@@ -423,7 +411,7 @@ api.sleep = {
url: '/user/sleep',
async handler (req, res) {
- let user = res.locals.user;
-- let sleepRes = common.ops.sleep(user, req, res.analytics);
-+ let sleepRes = common.ops.sleep(user);
+ const { user } = res.locals;
+- const sleepRes = common.ops.sleep(user, req, res.analytics);
++ const sleepRes = common.ops.sleep(user);
await user.save();
res.respond(200, ...sleepRes);
},
-@@ -472,7 +460,7 @@ api.buy = {
+@@ -482,7 +470,7 @@ api.buy = {
let quantity = 1;
if (req.body.quantity) quantity = req.body.quantity;
req.quantity = quantity;
-- buyRes = common.ops.buy(user, req, res.analytics);
-+ buyRes = common.ops.buy(user, req);
+- const buyRes = common.ops.buy(user, req, res.analytics);
++ const buyRes = common.ops.buy(user, req);
await user.save();
res.respond(200, ...buyRes);
-@@ -520,7 +508,7 @@ api.buyGear = {
+@@ -530,7 +518,7 @@ api.buyGear = {
url: '/user/buy-gear/:key',
async handler (req, res) {
- let user = res.locals.user;
-- let buyGearRes = common.ops.buy(user, req, res.analytics);
-+ let buyGearRes = common.ops.buy(user, req);
+ const { user } = res.locals;
+- const buyGearRes = common.ops.buy(user, req, res.analytics);
++ const buyGearRes = common.ops.buy(user, req);
await user.save();
res.respond(200, ...buyGearRes);
},
-@@ -562,7 +550,7 @@ api.buyArmoire = {
- let user = res.locals.user;
+@@ -572,7 +560,7 @@ api.buyArmoire = {
+ const { user } = res.locals;
req.type = 'armoire';
req.params.key = 'armoire';
-- let buyArmoireResponse = common.ops.buy(user, req, res.analytics);
-+ let buyArmoireResponse = common.ops.buy(user, req);
+- const buyArmoireResponse = common.ops.buy(user, req, res.analytics);
++ const buyArmoireResponse = common.ops.buy(user, req);
await user.save();
res.respond(200, ...buyArmoireResponse);
},
-@@ -602,7 +590,7 @@ api.buyHealthPotion = {
- let user = res.locals.user;
+@@ -612,7 +600,7 @@ api.buyHealthPotion = {
+ const { user } = res.locals;
req.type = 'potion';
req.params.key = 'potion';
-- let buyHealthPotionResponse = common.ops.buy(user, req, res.analytics);
-+ let buyHealthPotionResponse = common.ops.buy(user, req);
+- const buyHealthPotionResponse = common.ops.buy(user, req, res.analytics);
++ const buyHealthPotionResponse = common.ops.buy(user, req);
await user.save();
res.respond(200, ...buyHealthPotionResponse);
},
-@@ -643,7 +631,7 @@ api.buyMysterySet = {
+@@ -653,7 +641,7 @@ api.buyMysterySet = {
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.type = 'mystery';
-- let buyMysterySetRes = common.ops.buy(user, req, res.analytics);
-+ let buyMysterySetRes = common.ops.buy(user, req);
+- const buyMysterySetRes = common.ops.buy(user, req, res.analytics);
++ const buyMysterySetRes = common.ops.buy(user, req);
await user.save();
res.respond(200, ...buyMysterySetRes);
},
-@@ -686,7 +674,7 @@ api.buyQuest = {
+@@ -696,7 +684,7 @@ api.buyQuest = {
async handler (req, res) {
- let user = res.locals.user;
+ const { user } = res.locals;
req.type = 'quest';
-- let buyQuestRes = common.ops.buy(user, req, res.analytics);
-+ let buyQuestRes = common.ops.buy(user, req);
+- const buyQuestRes = common.ops.buy(user, req, res.analytics);
++ const buyQuestRes = common.ops.buy(user, req);
await user.save();
res.respond(200, ...buyQuestRes);
},
-@@ -900,7 +888,7 @@ api.changeClass = {
+@@ -922,7 +910,7 @@ api.changeClass = {
url: '/user/change-class',
async handler (req, res) {
- let user = res.locals.user;
-- let changeClassRes = common.ops.changeClass(user, req, res.analytics);
-+ let changeClassRes = common.ops.changeClass(user, req);
+ const { user } = res.locals;
+- const changeClassRes = common.ops.changeClass(user, req, res.analytics);
++ const changeClassRes = common.ops.changeClass(user, req);
await user.save();
res.respond(200, ...changeClassRes);
},
-@@ -969,7 +957,7 @@ api.purchase = {
+@@ -994,7 +982,7 @@ api.purchase = {
if (req.body.quantity) quantity = req.body.quantity;
req.quantity = quantity;
-- let purchaseRes = common.ops.buy(user, req, res.analytics);
-+ let purchaseRes = common.ops.buy(user, req);
+- const purchaseRes = common.ops.buy(user, req, res.analytics);
++ const purchaseRes = common.ops.buy(user, req);
await user.save();
res.respond(200, ...purchaseRes);
},
-@@ -1005,7 +993,7 @@ api.userPurchaseHourglass = {
- let user = res.locals.user;
- const quantity = req.body.quantity || 1;
- if (quantity < 1 || !Number.isInteger(quantity)) throw new BadRequest(res.t('invalidQuantity'), req.language);
-- let purchaseHourglassRes = common.ops.buy(user, req, res.analytics, {quantity, hourglass: true});
-+ let purchaseHourglassRes = common.ops.buy(user, req, {quantity, hourglass: true});
+@@ -1035,7 +1023,6 @@ api.userPurchaseHourglass = {
+ const purchaseHourglassRes = common.ops.buy(
+ user,
+ req,
+- res.analytics,
+ { quantity, hourglass: true },
+ );
await user.save();
- res.respond(200, ...purchaseHourglassRes);
- },
-@@ -1099,7 +1087,7 @@ api.userOpenMysteryItem = {
+@@ -1132,7 +1119,7 @@ api.userOpenMysteryItem = {
url: '/user/open-mystery-item',
async handler (req, res) {
- let user = res.locals.user;
-- let openMysteryItemRes = common.ops.openMysteryItem(user, req, res.analytics);
-+ let openMysteryItemRes = common.ops.openMysteryItem(user, req);
+ const { user } = res.locals;
+- const openMysteryItemRes = common.ops.openMysteryItem(user, req, res.analytics);
++ const openMysteryItemRes = common.ops.openMysteryItem(user, req);
await user.save();
res.respond(200, ...openMysteryItemRes);
},
-@@ -1131,7 +1119,7 @@ api.userReleasePets = {
+@@ -1164,7 +1151,7 @@ api.userReleasePets = {
url: '/user/release-pets',
async handler (req, res) {
- let user = res.locals.user;
-- let releasePetsRes = common.ops.releasePets(user, req, res.analytics);
-+ let releasePetsRes = common.ops.releasePets(user, req);
+ const { user } = res.locals;
+- const releasePetsRes = common.ops.releasePets(user, req, res.analytics);
++ const releasePetsRes = common.ops.releasePets(user, req);
await user.save();
res.respond(200, ...releasePetsRes);
},
-@@ -1180,7 +1168,7 @@ api.userReleaseBoth = {
+@@ -1213,7 +1200,7 @@ api.userReleaseBoth = {
url: '/user/release-both',
async handler (req, res) {
- let user = res.locals.user;
-- let releaseBothRes = common.ops.releaseBoth(user, req, res.analytics);
-+ let releaseBothRes = common.ops.releaseBoth(user, req);
+ const { user } = res.locals;
+- const releaseBothRes = common.ops.releaseBoth(user, req, res.analytics);
++ const releaseBothRes = common.ops.releaseBoth(user, req);
await user.save();
res.respond(200, ...releaseBothRes);
},
-@@ -1216,7 +1204,7 @@ api.userReleaseMounts = {
+@@ -1249,7 +1236,7 @@ api.userReleaseMounts = {
url: '/user/release-mounts',
async handler (req, res) {
- let user = res.locals.user;
-- let releaseMountsRes = common.ops.releaseMounts(user, req, res.analytics);
-+ let releaseMountsRes = common.ops.releaseMounts(user, req);
+ const { user } = res.locals;
+- const releaseMountsRes = common.ops.releaseMounts(user, req, res.analytics);
++ const releaseMountsRes = common.ops.releaseMounts(user, req);
await user.save();
res.respond(200, ...releaseMountsRes);
},
-@@ -1289,7 +1277,7 @@ api.userUnlock = {
+@@ -1325,7 +1312,7 @@ api.userUnlock = {
url: '/user/unlock',
async handler (req, res) {
- let user = res.locals.user;
-- let unlockRes = common.ops.unlock(user, req, res.analytics);
-+ let unlockRes = common.ops.unlock(user, req);
+ const { user } = res.locals;
+- const unlockRes = common.ops.unlock(user, req, res.analytics);
++ const unlockRes = common.ops.unlock(user, req);
await user.save();
res.respond(200, ...unlockRes);
},
-@@ -1315,7 +1303,7 @@ api.userRevive = {
+@@ -1351,7 +1338,7 @@ api.userRevive = {
url: '/user/revive',
async handler (req, res) {
- let user = res.locals.user;
-- let reviveRes = common.ops.revive(user, req, res.analytics);
-+ let reviveRes = common.ops.revive(user, req);
+ const { user } = res.locals;
+- const reviveRes = common.ops.revive(user, req, res.analytics);
++ const reviveRes = common.ops.revive(user, req);
await user.save();
res.respond(200, ...reviveRes);
},
diff --git a/website/server/controllers/api-v4/auth.js b/website/server/controllers/api-v4/auth.js
-index 05f8b6dd9b..55514c0275 100644
+index 7ff213183c..c134298aad 100644
--- a/website/server/controllers/api-v4/auth.js
+++ b/website/server/controllers/api-v4/auth.js
-@@ -56,7 +56,7 @@ api.verifyUsername = {
-
+@@ -57,7 +57,6 @@ api.verifyUsername = {
/**
* @api {post} /api/v4/user/auth/local/register Register
-- * @apiDescription Register a new user with email, login name, and password or attach local auth to a social user
-+ * @apiDescription Register a new user with email, login name, and password
+ * @apiDescription Register a new user with email, login name, and password
+- * or attach local auth to a social user
* @apiName UserRegisterLocal
* @apiGroup User
*
-@@ -65,7 +65,7 @@ api.verifyUsername = {
+@@ -68,8 +67,7 @@ api.verifyUsername = {
* @apiParam (Body) {String} password Password for the new user
* @apiParam (Body) {String} confirmPassword Password confirmation
*
-- * @apiSuccess {Object} data The user object, if local auth was just attached to a social user then only user.auth.local
+- * @apiSuccess {Object} data The user object, if local auth was just
+- * attached to a social user then only user.auth.local
+ * @apiSuccess {Object} data The user object
*/
api.registerLocal = {
method: 'POST',
diff --git a/website/server/controllers/api-v4/members.js b/website/server/controllers/api-v4/members.js
-index 57a1b39ddd..24cffe91dd 100644
+index bd31d6a0b4..4ea31044fc 100644
--- a/website/server/controllers/api-v4/members.js
+++ b/website/server/controllers/api-v4/members.js
-@@ -5,7 +5,7 @@ let api = {};
+@@ -5,8 +5,7 @@ const api = {};
/**
* @api {post} /api/v4/members/flag-private-message/:messageId Flag a private message
-- * @apiDescription An email and slack message are sent to the moderators about every flagged message.
+- * @apiDescription An email and slack message are sent
+- * to the moderators about every flagged message.
+ * @apiDescription An email is sent to the moderators about every flagged message.
* @apiName FlagPrivateMessage
* @apiGroup Member
*
diff --git a/website/server/controllers/api-v4/user.js b/website/server/controllers/api-v4/user.js
-index 2474c31dc0..75f6890796 100644
+index f7acd2d514..588a1930db 100644
--- a/website/server/controllers/api-v4/user.js
+++ b/website/server/controllers/api-v4/user.js
-@@ -33,7 +33,6 @@ const api = {};
+@@ -34,7 +34,6 @@ const api = {};
* Preferences (user selected prefs)
* Profile (name, photo url, blurb)
* Purchased (includes purchase history, gem purchased items, plans)
@@ -6220,17 +6386,23 @@ index 2474c31dc0..75f6890796 100644
* Tags
* TasksOrder (list of all ids for dailys, habits, rewards and todos)
diff --git a/website/server/controllers/top-level/dataexport.js b/website/server/controllers/top-level/dataexport.js
-index 39333edead..2b3388ae74 100644
+index 4aead64047..49419f4175 100644
--- a/website/server/controllers/top-level/dataexport.js
+++ b/website/server/controllers/top-level/dataexport.js
-@@ -9,17 +9,7 @@ import _ from 'lodash';
- import csvStringify from '../../libs/csvStringify';
+@@ -1,9 +1,6 @@
+ import _ from 'lodash';
import moment from 'moment';
import * as js2xml from 'js2xmlparser';
-import Pageres from 'pageres';
-import nconf from 'nconf';
-import got from 'got';
import md from 'habitica-markdown';
+ import csvStringify from '../../libs/csvStringify';
+ import {
+@@ -13,13 +10,6 @@ import * as Tasks from '../../models/task';
+ import * as inboxLib from '../../libs/inbox';
+ import { model as User } from '../../models/user';
+ import { authWithSession } from '../../middlewares/auth';
-import {
- S3,
-} from '../../libs/aws';
@@ -6239,9 +6411,9 @@ index 39333edead..2b3388ae74 100644
-
-const BASE_URL = nconf.get('BASE_URL');
- let api = {};
+ const api = {};
-@@ -224,75 +214,6 @@ api.exportUserAvatarHtml = {
+@@ -221,75 +211,6 @@ api.exportUserAvatarHtml = {
},
};
@@ -6260,13 +6432,13 @@ index 39333edead..2b3388ae74 100644
- async handler (req, res) {
- req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID();
-
-- let validationErrors = req.validationErrors();
+- const validationErrors = req.validationErrors();
- if (validationErrors) throw validationErrors;
-
-- let memberId = req.params.memberId;
+- const { memberId } = req.params;
-
-- let filename = `avatars/${memberId}.png`;
-- let s3url = `https://${S3_BUCKET}.s3.amazonaws.com/${filename}`;
+- const filename = `avatars/${memberId}.png`;
+- const s3url = `https://${S3_BUCKET}.s3.amazonaws.com/${filename}`;
-
- let response;
- try {
@@ -6290,17 +6462,17 @@ index 39333edead..2b3388ae74 100644
- })
- .run();
-
-- let s3upload = S3.upload({
+- const s3upload = S3.upload({
- Bucket: S3_BUCKET,
- Key: filename,
- ACL: 'public-read',
- StorageClass: 'REDUCED_REDUNDANCY',
- ContentType: 'image/png',
-- Expires: moment().add({minutes: 5}).toDate(),
+- Expires: moment().add({ minutes: 5 }).toDate(),
- Body: pageBuffer,
- });
-
-- let s3res = await new Promise((resolve, reject) => {
+- const s3res = await new Promise((resolve, reject) => {
- s3upload.send((err, s3uploadRes) => {
- if (err) {
- reject(err);
@@ -6310,7 +6482,7 @@ index 39333edead..2b3388ae74 100644
- });
- });
-
-- res.redirect(s3res.Location);
+- return res.redirect(s3res.Location);
- },
-};
-
@@ -6318,37 +6490,36 @@ index 39333edead..2b3388ae74 100644
* @api {get} /export/inbox.html Export user private messages as HTML document
* @apiName ExportUserPrivateMessages
diff --git a/website/server/index.js b/website/server/index.js
-index c1d6757dee..8259255218 100644
+index b0c1a8a823..b466797ee2 100644
--- a/website/server/index.js
+++ b/website/server/index.js
-@@ -12,9 +12,6 @@ const setupNconf = require('./libs/setupNconf');
+@@ -14,9 +14,6 @@ const setupNconf = require('./libs/setupNconf');
+ // Initialize configuration BEFORE anything
setupNconf();
- const nconf = require('nconf');
-// Initialize @google-cloud/trace-agent
-require('./libs/gcpTraceAgent');
-
- const cluster = require('cluster');
- const logger = require('./libs/logger');
+ const logger = require('./libs/logger').default;
+ const IS_PROD = nconf.get('IS_PROD');
diff --git a/website/server/libs/auth/index.js b/website/server/libs/auth/index.js
-index 609f546ad8..0ec22f525c 100644
+index af5e4522af..b6424cd766 100644
--- a/website/server/libs/auth/index.js
+++ b/website/server/libs/auth/index.js
-@@ -7,12 +7,10 @@ import * as passwordUtils from '../../libs/password';
+@@ -8,11 +8,9 @@ import * as passwordUtils from '../password';
import { model as User } from '../../models/user';
import { model as EmailUnsubscription } from '../../models/emailUnsubscription';
- import { sendTxn as sendTxnEmail } from '../../libs/email';
+ import { sendTxn as sendTxnEmail } from '../email';
-import common from '../../../common';
- import logger from '../../libs/logger';
- import { decrypt } from '../../libs/encryption';
+ import logger from '../logger';
+ import { decrypt } from '../encryption';
import { model as Group } from '../../models/group';
- import moment from 'moment';
--import { loginSocial } from './social.js';
+-import { loginSocial } from './social';
import { loginRes } from './utils';
import { verifyUsername } from '../user/validation';
-@@ -59,20 +57,8 @@ function hasLocalAuth (user) {
+@@ -64,19 +62,8 @@ function hasLocalAuth (user) {
return user.auth.local.email && user.auth.local.hashed_password;
}
@@ -6357,9 +6528,8 @@ index 609f546ad8..0ec22f525c 100644
- return true;
- }
-
-- let hasAlternateNetwork = common.constants.SUPPORTED_SOCIAL_NETWORKS.find((network) => {
-- return network.key !== networkToRemove && user.auth[network.key].id;
-- });
+- const hasAlternateNetwork = common.constants.SUPPORTED_SOCIAL_NETWORKS
+- .find(network => network.key !== networkToRemove && user.auth[network.key].id);
-
- return hasAlternateNetwork;
-}
@@ -6370,15 +6540,16 @@ index 609f546ad8..0ec22f525c 100644
req.checkBody({
username: {
-@@ -143,19 +129,8 @@ async function registerLocal (req, res, { isV3 = false }) {
+@@ -151,20 +138,8 @@ async function registerLocal (req, res, { isV3 = false }) {
},
};
- if (existingUser) {
-- let hasSocialAuth = common.constants.SUPPORTED_SOCIAL_NETWORKS.find(network => {
-- if (existingUser.auth.hasOwnProperty(network.key)) {
+- const hasSocialAuth = common.constants.SUPPORTED_SOCIAL_NETWORKS.find(network => {
+- if (existingUser.auth.hasOwnProperty(network.key)) { // eslint-disable-line no-prototype-builtins, max-len
- return existingUser.auth[network.key].id;
- }
+- return false;
- });
- if (!hasSocialAuth) throw new NotAuthorized(res.t('onlySocialAttachLocal'));
- existingUser.auth.local = newUser.auth.local;
@@ -6392,7 +6563,7 @@ index 609f546ad8..0ec22f525c 100644
// we check for partyInvite for backward compatibility
if (req.query.groupInvite || req.query.partyInvite) {
-@@ -191,24 +166,11 @@ async function registerLocal (req, res, { isV3 = false }) {
+@@ -200,24 +175,11 @@ async function registerLocal (req, res, { isV3 = false }) {
}
});
@@ -6410,7 +6581,7 @@ index 609f546ad8..0ec22f525c 100644
return null;
}
- module.exports = {
+ export {
loginRes,
- hasBackupAuth,
hasLocalAuth,
@@ -6418,7 +6589,7 @@ index 609f546ad8..0ec22f525c 100644
registerLocal,
};
diff --git a/website/server/libs/auth/utils.js b/website/server/libs/auth/utils.js
-index 588c596037..8e9265be22 100644
+index 99c9083a3f..f500b8fcbb 100644
--- a/website/server/libs/auth/utils.js
+++ b/website/server/libs/auth/utils.js
@@ -1,15 +1,8 @@
@@ -6430,80 +6601,83 @@ index 588c596037..8e9265be22 100644
const COMMUNITY_MANAGER_EMAIL = nconf.get('EMAILS_COMMUNITY_MANAGER_EMAIL');
-const translator = shortid('0123456789abcdefghijklmnopqrstuvwxyz');
-
--function generateUsername () {
-- let newName = `hb-${translator.new()}`;
+-export function generateUsername () {
+- const newName = `hb-${translator.new()}`;
- return newName.substring(0, 20);
-}
- function loginRes (user, req, res) {
- if (user.auth.blocked) throw new NotAuthorized(res.t('accountSuspended', {communityManagerEmail: COMMUNITY_MANAGER_EMAIL, userId: user._id}));
-@@ -25,6 +18,5 @@ function loginRes (user, req, res) {
- }
-
- module.exports = {
-- generateUsername,
- loginRes,
- };
+ export function loginRes (user, req, res) {
+ if (user.auth.blocked) {
diff --git a/website/server/libs/chat.js b/website/server/libs/chat.js
-index a19e9b260c..3554bc90ee 100644
+index fb41269f44..cd124b8ab1 100644
--- a/website/server/libs/chat.js
+++ b/website/server/libs/chat.js
@@ -1,6 +1,5 @@
- import { model as User } from '../models/user';
- import { getUserInfo } from './email';
--import {sendNotification as sendPushNotification} from './pushNotifications';
+ import { model as User } from '../models/user'; // eslint-disable-line import/no-cycle
+ import { getUserInfo } from './email'; // eslint-disable-line import/no-cycle
+-import { sendNotification as sendPushNotification } from './pushNotifications';
export async function getAuthorEmailFromMessage (message) {
- let authorId = message.uuid;
-@@ -17,26 +16,3 @@ export async function getAuthorEmailFromMessage (message) {
- return 'Author Account Deleted';
+ const authorId = message.uuid;
+@@ -16,37 +15,3 @@ export async function getAuthorEmailFromMessage (message) {
}
+ return 'Author Account Deleted';
}
-
--export async function sendChatPushNotifications (user, group, message, translate) {
-- let members = await User.find({
+-export async function sendChatPushNotifications (user, group, message, mentions, translate) {
+- const members = await User.find({
- 'party._id': group._id,
-- _id: {$ne: user._id},
+- _id: { $ne: user._id },
- })
-- .select('preferences.pushNotifications preferences.language profile.name pushDevices')
+- .select('preferences.pushNotifications preferences.language profile.name pushDevices auth.local.username')
- .exec();
+-
- members.forEach(member => {
- if (member.preferences.pushNotifications.partyActivity !== false) {
+- if (mentions && mentions.includes(`@${member.auth.local.username}`) && member.preferences.pushNotifications.mentionParty !== false) {
+- return;
+- }
- sendPushNotification(
- member,
- {
-- title: translate('groupActivityNotificationTitle', {user: message.user, group: group.name}, member.preferences.language),
+- title: translate('groupActivityNotificationTitle', { user: message.user, group: group.name }, member.preferences.language),
- message: message.text,
- identifier: 'groupActivity',
- category: 'groupActivity',
-- payload: {groupID: group._id, type: group.type, groupName: group.name, message: message.text, timestamp: message.timestamp, senderName: message.user},
-- }
+- payload: {
+- groupID: group._id,
+- type: group.type,
+- groupName: group.name,
+- message: message.text,
+- timestamp: message.timestamp,
+- senderName: message.user,
+- },
+- },
- );
- }
- });
-}
-\ No newline at end of file
diff --git a/website/server/libs/chatReporting/groupChatReporter.js b/website/server/libs/chatReporting/groupChatReporter.js
-index b41f142579..806358dbd7 100644
+index 11b6ea2106..7c7c027837 100644
--- a/website/server/libs/chatReporting/groupChatReporter.js
+++ b/website/server/libs/chatReporting/groupChatReporter.js
@@ -7,7 +7,6 @@ import {
NotFound,
} from '../errors';
import { sendTxn } from '../email';
--import slack from '../slack';
+-import * as slack from '../slack';
import { model as Group } from '../../models/group';
import { chatModel as Chat } from '../../models/message';
import apiError from '../apiError';
-@@ -49,22 +48,13 @@ export default class GroupChatReporter extends ChatReporter {
- return {message, group, userComment};
+@@ -50,22 +49,13 @@ export default class GroupChatReporter extends ChatReporter {
+ return { message, group, userComment };
}
- async notify (group, message, userComment, automatedComment = '') {
+ async notify (group, message, userComment) {
let emailVariables = await this.getMessageVariables(group, message);
emailVariables = emailVariables.concat([
- {name: 'REPORTER_COMMENT', content: userComment || ''},
+ { name: 'REPORTER_COMMENT', content: userComment || '' },
]);
sendTxn(FLAG_REPORT_EMAILS, 'flag-report-to-mods-with-comments', emailVariables);
@@ -6519,8 +6693,8 @@ index b41f142579..806358dbd7 100644
}
async flagGroupMessage (group, message, increaseFlagCount) {
-@@ -91,14 +81,12 @@ export default class GroupChatReporter extends ChatReporter {
- let {message, group, userComment} = await this.validate();
+@@ -92,14 +82,12 @@ export default class GroupChatReporter extends ChatReporter {
+ const { message, group, userComment } = await this.validate();
let increaseFlagCount = true;
- let automatedComment = '';
@@ -6536,14 +6710,14 @@ index b41f142579..806358dbd7 100644
return message;
}
diff --git a/website/server/libs/chatReporting/inboxChatReporter.js b/website/server/libs/chatReporting/inboxChatReporter.js
-index 207b570fd3..e8078d83cf 100644
+index 0a15902e5b..b20d5dc5e0 100644
--- a/website/server/libs/chatReporting/inboxChatReporter.js
+++ b/website/server/libs/chatReporting/inboxChatReporter.js
@@ -6,7 +6,6 @@ import {
BadRequest,
} from '../errors';
- import { getUserInfo, sendTxn} from '../email';
--import slack from '../slack';
+ import { getUserInfo, sendTxn } from '../email';
+-import * as slack from '../slack';
import apiError from '../apiError';
import * as inboxLib from '../inbox';
@@ -6562,25 +6736,27 @@ index 207b570fd3..e8078d83cf 100644
async getAuthorVariables (message) {
diff --git a/website/server/libs/cron.js b/website/server/libs/cron.js
-index 2e01b1a917..80642b16ab 100644
+index b0882b9ab7..3d7b12748f 100644
--- a/website/server/libs/cron.js
+++ b/website/server/libs/cron.js
-@@ -85,12 +85,12 @@ function grantEndOfTheMonthPerks (user, now) {
- // If offset is now less than 0, the user EITHER has a single-month recurring subscription and MIGHT be due for perks,
- // OR has a multi-month subscription that renewed some time in the previous calendar month and so they are due for a new set of perks
- // (strictly speaking, they should have been given the perks at the time that next payment was taken, but we don't have support for
+@@ -96,14 +96,14 @@ function grantEndOfTheMonthPerks (user, now) {
+ // in the previous calendar month and so they are due for a new set of perks
+ // (strictly speaking, they should have been given the perks
+ // at the time that next payment was taken, but we don't have support for
- // tracking payments like that - giving the perks when offset is < 0 is a workaround).
+ // tracking like that - giving the perks when offset is < 0 is a workaround).
if (plan.consecutive.offset < 0) {
if (plan.planId) {
- // NB gift subscriptions don't have a planID (which doesn't matter because we don't need to reapply perks for them and by this point they should have expired anyway)
-- let planIdRegExp = new RegExp('_([0-9]+)mo'); // e.g., matches 'google_6mo' / 'basic_12mo' and captures '6' / '12'
-+ let planIdRegExp = new RegExp('_([0-9]+)mo'); // e.g., matches 'basic_12mo' and captures '6' / '12'
- let match = plan.planId.match(planIdRegExp);
+ // NB gift subscriptions don't have a planID
+ // (which doesn't matter because we don't need to reapply perks
+ // for them and by this point they should have expired anyway)
+- const planIdRegExp = new RegExp('_([0-9]+)mo'); // e.g., matches 'google_6mo' / 'basic_12mo' and captures '6' / '12'
++ const planIdRegExp = new RegExp('_([0-9]+)mo'); // e.g., matches 'basic_12mo' and captures '6' / '12'
+ const match = plan.planId.match(planIdRegExp);
if (match !== null && match[0] !== null) {
- planMonthsLength = match[1]; // 3 for 3-month recurring subscription, etc
-@@ -172,32 +172,6 @@ function resetHabitCounters (user, tasksByType, now, daysMissed) {
+ // 3 for 3-month recurring subscription, etc
+@@ -196,35 +196,6 @@ function resetHabitCounters (user, tasksByType, now, daysMissed) {
});
}
@@ -6599,7 +6775,10 @@ index 2e01b1a917..80642b16ab 100644
- loginIncentives: user.loginIncentives,
- });
-
-- if (user.party && user.party.quest && !user.party.quest.RSVPNeeded && !user.party.quest.completed && user.party.quest.key && !user.preferences.sleep) {
+- if (
+- user.party && user.party.quest && !user.party.quest.RSVPNeeded
+- && !user.party.quest.completed && user.party.quest.key && !user.preferences.sleep
+- ) {
- analytics.track('quest participation', {
- category: 'behavior',
- uuid: user._id,
@@ -6613,58 +6792,76 @@ index 2e01b1a917..80642b16ab 100644
function awardLoginIncentives (user) {
if (user.loginIncentives > MAX_INCENTIVES) return;
-@@ -248,7 +222,7 @@ function awardLoginIncentives (user) {
-
+@@ -276,7 +247,7 @@ function awardLoginIncentives (user) {
// Perform various beginning-of-day reset actions.
export function cron (options = {}) {
-- let {user, tasksByType, analytics, now = new Date(), daysMissed, timezoneOffsetFromUserPrefs} = options;
-+ let {user, tasksByType, now = new Date(), daysMissed, timezoneOffsetFromUserPrefs} = options;
- let _progress = {down: 0, up: 0, collectedItems: 0};
+ const {
+- user, tasksByType, analytics, now = new Date(), daysMissed, timezoneOffsetFromUserPrefs,
++ user, tasksByType, now = new Date(), daysMissed, timezoneOffsetFromUserPrefs,
+ } = options;
+ let _progress = { down: 0, up: 0, collectedItems: 0 };
- // Record pre-cron values of HP and MP to show notifications later
-@@ -488,9 +462,7 @@ export function cron (options = {}) {
+@@ -537,9 +508,6 @@ export function cron (options = {}) {
mp: user.stats.mp - beforeCronStats.mp - (oldCronNotif ? oldCronNotif.data.mp : 0),
});
- // Analytics
- user.flags.cronCount++;
+ user.flags.cronCount += 1;
- trackCronAnalytics(analytics, user, _progress, options);
-
+-
return _progress;
}
diff --git a/website/server/libs/email.js b/website/server/libs/email.js
-index 02e236fe60..b37c3e8a0a 100644
+index 634d60ad9d..2385546ca6 100644
--- a/website/server/libs/email.js
+++ b/website/server/libs/email.js
-@@ -3,7 +3,6 @@ import { TAVERN_ID } from '../models/group';
+@@ -3,7 +3,6 @@ import got from 'got';
+ import { TAVERN_ID } from '../models/group'; // eslint-disable-line import/no-cycle
import { encrypt } from './encryption';
- import got from 'got';
import logger from './logger';
-import common from '../../common';
const IS_PROD = nconf.get('IS_PROD');
const EMAIL_SERVER = {
-@@ -25,12 +24,6 @@ export function getUserInfo (user, fields = []) {
+@@ -25,17 +24,6 @@ export function getUserInfo (user, fields = []) {
if (fields.indexOf('email') !== -1) {
if (user.auth.local && user.auth.local.email) {
info.email = user.auth.local.email;
- } else {
- common.constants.SUPPORTED_SOCIAL_NETWORKS.forEach(network => {
-- if (user.auth[network.key] && user.auth[network.key].emails && user.auth[network.key].emails[0] && user.auth[network.key].emails[0].value) {
+- if (
+- user.auth[network.key]
+- && user.auth[network.key].emails
+- && user.auth[network.key].emails[0]
+- && user.auth[network.key].emails[0].value
+- ) {
- info.email = user.auth[network.key].emails[0].value;
- }
- });
}
}
+diff --git a/website/server/libs/highlightMentions.js b/website/server/libs/highlightMentions.js
+index b04777ca2d..5c0e800950 100644
+--- a/website/server/libs/highlightMentions.js
++++ b/website/server/libs/highlightMentions.js
+@@ -10,7 +10,7 @@ export async function highlightMentions (text) { // eslint-disable-line import/p
+ const usernames = mentions.map(mention => mention.substr(1));
+ members = await User
+ .find({ 'auth.local.username': { $in: usernames }, 'flags.verifiedUsername': true })
+- .select(['auth.local.username', '_id', 'preferences.pushNotifications', 'pushDevices', 'party', 'guilds'])
++ .select(['auth.local.username', '_id', 'party', 'guilds'])
+ .lean()
+ .exec();
+ members.forEach(member => {
diff --git a/website/server/libs/inbox/index.js b/website/server/libs/inbox/index.js
-index 9cb610cc5e..b4c0649328 100644
+index 9dcbbdb01e..728213fdf6 100644
--- a/website/server/libs/inbox/index.js
+++ b/website/server/libs/inbox/index.js
@@ -1,10 +1,9 @@
- import {mapInboxMessage, inboxModel as Inbox} from '../../models/message';
- import {getUserInfo, sendTxn as sendTxnEmail} from '../email';
--import {sendNotification as sendPushNotification} from '../pushNotifications';
+ import { mapInboxMessage, inboxModel as Inbox } from '../../models/message';
+ import { getUserInfo, sendTxn as sendTxnEmail } from '../email'; // eslint-disable-line import/no-cycle
+-import { sendNotification as sendPushNotification } from '../pushNotifications';
const PM_PER_PAGE = 10;
@@ -6673,7 +6870,7 @@ index 9cb610cc5e..b4c0649328 100644
const messageSent = await sender.sendMessage(receiver, { receiverMsg: message });
const senderName = getUserInfo(sender, ['name']).name;
-@@ -14,19 +13,6 @@ export async function sentMessage (sender, receiver, message, translate) {
+@@ -14,23 +13,6 @@ export async function sentMessage (sender, receiver, message, translate) {
]);
}
@@ -6681,12 +6878,16 @@ index 9cb610cc5e..b4c0649328 100644
- sendPushNotification(
- receiver,
- {
-- title: translate('newPMNotificationTitle', {name: getUserInfo(sender, ['name']).name}, receiver.preferences.language),
+- title: translate(
+- 'newPMNotificationTitle',
+- { name: getUserInfo(sender, ['name']).name },
+- receiver.preferences.language,
+- ),
- message,
- identifier: 'newPM',
- category: 'newPM',
-- payload: {replyTo: sender._id, senderName, message},
-- }
+- payload: { replyTo: sender._id, senderName, message },
+- },
- );
- }
-
@@ -6694,7 +6895,7 @@ index 9cb610cc5e..b4c0649328 100644
}
diff --git a/website/server/libs/invites/index.js b/website/server/libs/invites/index.js
-index 2429794e68..7616855f2a 100644
+index 8c5cf612d9..9ed295dc0d 100644
--- a/website/server/libs/invites/index.js
+++ b/website/server/libs/invites/index.js
@@ -1,7 +1,6 @@
@@ -6720,8 +6921,8 @@ index 2429794e68..7616855f2a 100644
- title: group.name,
- message: res.t(identifier, userToInvite.preferences.language),
- identifier,
-- payload: {groupID: group._id, publicGuild},
-- }
+- payload: { groupID: group._id, publicGuild },
+- },
- );
-}
-
@@ -6736,17 +6937,17 @@ index 2429794e68..7616855f2a 100644
const userInvited = await userToInvite.save();
if (group.type === 'guild') {
-@@ -147,8 +129,6 @@ async function inviteByEmail (invite, group, inviter, req, res) {
-
- let userToContact = await User.findOne({$or: [
- {'auth.local.email': invite.email},
-- {'auth.facebook.emails.value': invite.email},
-- {'auth.google.emails.value': invite.email},
- ]})
- .select({_id: true, 'preferences.emailNotifications': true})
- .exec();
+@@ -153,8 +135,6 @@ async function inviteByEmail (invite, group, inviter, req, res) {
+ const userToContact = await User.findOne({
+ $or: [
+ { 'auth.local.email': invite.email },
+- { 'auth.facebook.emails.value': invite.email },
+- { 'auth.google.emails.value': invite.email },
+ ],
+ })
+ .select({ _id: true, 'preferences.emailNotifications': true })
diff --git a/website/server/libs/logger.js b/website/server/libs/logger.js
-index 7da144a7cf..8a260a1a6b 100644
+index 2e753828d4..a9be643acf 100644
--- a/website/server/libs/logger.js
+++ b/website/server/libs/logger.js
@@ -1,6 +1,5 @@
@@ -6767,15 +6968,15 @@ index 7da144a7cf..8a260a1a6b 100644
- json: true,
- });
}
- } else if (!IS_TEST || IS_TEST && ENABLE_LOGS_IN_TEST) { // Do not log anything when testing unless specified
- logger
+
+ // Do not log anything when testing unless specified
diff --git a/website/server/libs/payments/gems.js b/website/server/libs/payments/gems.js
-index 35d18cc706..400bf08e65 100644
+index 4904881e72..7962ea2576 100644
--- a/website/server/libs/payments/gems.js
+++ b/website/server/libs/payments/gems.js
@@ -1,9 +1,7 @@
--import analytics from '../analyticsService';
- import {
+-import * as analytics from '../analyticsService';
+ import { // eslint-disable-line import/no-cycle
getUserInfo,
sendTxn as txnEmail,
} from '../email';
@@ -6783,28 +6984,31 @@ index 35d18cc706..400bf08e65 100644
import shared from '../../../common';
function getGiftMessage (data, byUsername, gemAmount, language) {
-@@ -37,18 +35,6 @@ async function buyGemGift (data) {
+@@ -37,21 +35,6 @@ async function buyGemGift (data) {
]);
}
- // Only send push notifications if sending to a user other than yourself
-- if (data.gift.member._id !== data.user._id && data.gift.member.preferences.pushNotifications.giftedGems !== false) {
+- if (
+- data.gift.member._id !== data.user._id
+- && data.gift.member.preferences.pushNotifications.giftedGems !== false
+- ) {
- sendPushNotification(
- data.gift.member,
- {
- title: shared.i18n.t('giftedGems', languages[1]),
-- message: shared.i18n.t('giftedGemsInfo', {amount: gemAmount, name: byUsername}, languages[1]),
+- message: shared.i18n.t('giftedGemsInfo', { amount: gemAmount, name: byUsername }, languages[1]),
- identifier: 'giftedGems',
-- }
+- },
- );
- }
-
await data.gift.member.save();
}
-@@ -75,21 +61,10 @@ async function buyGems (data) {
+@@ -78,21 +61,10 @@ async function buyGems (data) {
updateUserBalance(data, amt);
- data.user.purchased.txnCount++;
+ data.user.purchased.txnCount += 1;
- if (!data.gift) txnEmail(data.user, 'donation');
-
@@ -6829,7 +7033,7 @@ index 35d18cc706..400bf08e65 100644
await data.user.save();
}
diff --git a/website/server/libs/payments/groupPayments.js b/website/server/libs/payments/groupPayments.js
-index ff4c9abf97..e3413ed12a 100644
+index c0f9878b01..f62518004f 100644
--- a/website/server/libs/payments/groupPayments.js
+++ b/website/server/libs/payments/groupPayments.js
@@ -1,4 +1,3 @@
@@ -6837,10 +7041,10 @@ index ff4c9abf97..e3413ed12a 100644
import _ from 'lodash';
import moment from 'moment';
-@@ -8,11 +7,9 @@ import {
+@@ -8,11 +7,9 @@ import { // eslint-disable-line import/no-cycle
basicFields as basicGroupFields,
} from '../../models/group';
- import {
+ import { // eslint-disable-line import/no-cycle
- getUserInfo,
sendTxn as txnEmail,
} from '../email';
@@ -6849,7 +7053,7 @@ index ff4c9abf97..e3413ed12a 100644
const JOINED_GROUP_PLAN = 'joined group plan';
function _dateDiff (earlyDate, lateDate) {
-@@ -53,8 +50,6 @@ async function addSubscriptionToGroupUsers (group) {
+@@ -51,8 +48,6 @@ async function addSubscriptionToGroupUsers (group) {
async function addSubToGroupUser (member, group) {
// These EMAIL_TEMPLATE constants are used to pass strings into templates that are
// stored externally and so their values must not be changed.
@@ -6858,30 +7062,35 @@ index ff4c9abf97..e3413ed12a 100644
const EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_GROUP_PLAN = 'group_plan_free_subscription';
const EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_LIFETIME_FREE = 'lifetime_free_subscription';
const EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NORMAL = 'normal_subscription';
-@@ -64,7 +59,6 @@ async function addSubToGroupUser (member, group) {
- // When changing customerIdsToIgnore or paymentMethodsToIgnore, the code blocks below for
- // the `group-member-join` email template will probably need to be changed.
- let customerIdsToIgnore = [this.constants.GROUP_PLAN_CUSTOMER_ID, this.constants.UNLIMITED_CUSTOMER_ID];
-- let paymentMethodsToIgnore = [this.constants.GOOGLE_PAYMENT_METHOD, this.constants.IOS_PAYMENT_METHOD];
+@@ -65,10 +60,6 @@ async function addSubToGroupUser (member, group) {
+ this.constants.GROUP_PLAN_CUSTOMER_ID,
+ this.constants.UNLIMITED_CUSTOMER_ID,
+ ];
+- const paymentMethodsToIgnore = [
+- this.constants.GOOGLE_PAYMENT_METHOD,
+- this.constants.IOS_PAYMENT_METHOD,
+- ];
let previousSubscriptionType = EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NONE;
- let leader = await User.findById(group.leader).exec();
+ const leader = await User.findById(group.leader).exec();
-@@ -99,29 +93,12 @@ async function addSubToGroupUser (member, group) {
- let memberPlan = member.purchased.plan;
- if (member.isSubscribed()) {
- let customerHasCancelledGroupPlan = memberPlan.customerId === this.constants.GROUP_PLAN_CUSTOMER_ID && !member.hasNotCancelled();
-- let ignorePaymentPlan = paymentMethodsToIgnore.indexOf(memberPlan.paymentMethod) !== -1;
- let ignoreCustomerId = customerIdsToIgnore.indexOf(memberPlan.customerId) !== -1;
+@@ -106,31 +97,12 @@ async function addSubToGroupUser (member, group) {
+ memberPlan.customerId === this.constants.GROUP_PLAN_CUSTOMER_ID
+ && !member.hasNotCancelled()
+ );
+- const ignorePaymentPlan = paymentMethodsToIgnore.indexOf(memberPlan.paymentMethod) !== -1;
+ const ignoreCustomerId = customerIdsToIgnore.indexOf(memberPlan.customerId) !== -1;
- if (ignorePaymentPlan) {
-- txnEmail({email: TECH_ASSISTANCE_EMAIL}, 'admin-user-subscription-details', [
-- {name: 'PROFILE_NAME', content: member.profile.name},
-- {name: 'UUID', content: member._id},
-- {name: 'EMAIL', content: getUserInfo(member, ['email']).email},
-- {name: 'PAYMENT_METHOD', content: memberPlan.paymentMethod},
-- {name: 'PURCHASED_PLAN', content: JSON.stringify(memberPlan)},
-- {name: 'ACTION_NEEDED', content: 'User has joined group plan and has been told to cancel their subscription then email us. Ensure they do that then give them free sub.'},
-- // TODO User won't get email instructions if they've opted out of all emails. See if we can make this email an exception and if not, report here whether they've opted out.
+- txnEmail({ email: TECH_ASSISTANCE_EMAIL }, 'admin-user-subscription-details', [
+- { name: 'PROFILE_NAME', content: member.profile.name },
+- { name: 'UUID', content: member._id },
+- { name: 'EMAIL', content: getUserInfo(member, ['email']).email },
+- { name: 'PAYMENT_METHOD', content: memberPlan.paymentMethod },
+- { name: 'PURCHASED_PLAN', content: JSON.stringify(memberPlan) },
+- { name: 'ACTION_NEEDED', content: 'User has joined group plan and has been told to cancel their subscription then email us. Ensure they do that then give them free sub.' },
+- // TODO User won't get email instructions if they've opted out of all emails.
+- // See if we can make this email an exception and if not,
+- // report here whether they've opted out.
- ]);
- }
-
@@ -6899,7 +7108,7 @@ index ff4c9abf97..e3413ed12a 100644
} else if (memberPlan.customerId === this.constants.GROUP_PLAN_CUSTOMER_ID) {
previousSubscriptionType = EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_GROUP_PLAN;
diff --git a/website/server/libs/payments/payments.js b/website/server/libs/payments/payments.js
-index da3e189d70..57b9a64b05 100644
+index 5d6b1bb9de..53017b3086 100644
--- a/website/server/libs/payments/payments.js
+++ b/website/server/libs/payments/payments.js
@@ -18,8 +18,6 @@ api.constants = {
@@ -6912,16 +7121,16 @@ index da3e189d70..57b9a64b05 100644
api.addSubscriptionToGroupUsers = addSubscriptionToGroupUsers;
diff --git a/website/server/libs/payments/subscriptions.js b/website/server/libs/payments/subscriptions.js
-index ba7305da8b..f01602701a 100644
+index c02d15f7fc..0c87288dc8 100644
--- a/website/server/libs/payments/subscriptions.js
+++ b/website/server/libs/payments/subscriptions.js
@@ -1,8 +1,6 @@
import _ from 'lodash';
import moment from 'moment';
--import analytics from '../analyticsService';
--import slack from '../slack';
- import {
+-import * as analytics from '../analyticsService';
+-import * as slack from '../slack'; // eslint-disable-line import/no-cycle
+ import { // eslint-disable-line import/no-cycle
getUserInfo,
sendTxn as txnEmail,
@@ -16,7 +14,6 @@ import {
@@ -6932,9 +7141,9 @@ index ba7305da8b..f01602701a 100644
// @TODO: Abstract to shared/constant
const JOINED_GROUP_PLAN = 'joined group plan';
-@@ -56,9 +53,6 @@ async function createSubscription (data) {
- let today = new Date();
- let plan;
+@@ -57,9 +54,6 @@ async function createSubscription (data) {
+ const months = Number(block.months);
+ const today = new Date();
let group;
- let groupId;
- let itemPurchased = 'Subscription';
@@ -6942,7 +7151,7 @@ index ba7305da8b..f01602701a 100644
let emailType = 'subscription-begins';
// If we are buying a group subscription
-@@ -75,10 +69,7 @@ async function createSubscription (data) {
+@@ -78,10 +72,7 @@ async function createSubscription (data) {
}
recipient = group;
@@ -6953,7 +7162,7 @@ index ba7305da8b..f01602701a 100644
recipient.purchased.plan.quantity = data.sub.quantity;
await this.addSubscriptionToGroupUsers(group);
-@@ -110,9 +101,7 @@ async function createSubscription (data) {
+@@ -113,9 +104,7 @@ async function createSubscription (data) {
paymentMethod: data.paymentMethod,
extraMonths: Number(plan.extraMonths) + _dateDiff(today, plan.dateTerminated),
dateTerminated: null,
@@ -6964,7 +7173,7 @@ index ba7305da8b..f01602701a 100644
nextPaymentProcessing: data.nextPaymentProcessing,
nextBillingDate: data.nextBillingDate,
additionalData: data.additionalData,
-@@ -150,19 +139,6 @@ async function createSubscription (data) {
+@@ -153,19 +142,6 @@ async function createSubscription (data) {
txnEmail(data.user, emailType);
}
@@ -6981,24 +7190,24 @@ index ba7305da8b..f01602701a 100644
- headers: data.headers,
- });
-
- if (!group) data.user.purchased.txnCount++;
+ if (!group) data.user.purchased.txnCount += 1;
if (data.gift) {
-@@ -197,48 +173,17 @@ async function createSubscription (data) {
- {name: 'X_MONTHS_SUBSCRIPTION', content: months},
+@@ -200,48 +176,17 @@ async function createSubscription (data) {
+ { name: 'X_MONTHS_SUBSCRIPTION', content: months },
]);
}
-
-- if (data.gift.member._id !== data.user._id) { // Only send push notifications if sending to a user other than yourself
+- // Only send push notifications if sending to a user other than yourself
+- if (data.gift.member._id !== data.user._id) {
- if (data.gift.member.preferences.pushNotifications.giftedSubscription !== false) {
- sendPushNotification(data.gift.member,
- {
- title: shared.i18n.t('giftedSubscription', languages[1]),
-- message: shared.i18n.t('giftedSubscriptionInfo', {months, name: byUserName}, languages[1]),
+- message: shared.i18n.t('giftedSubscriptionInfo', { months, name: byUserName }, languages[1]),
- identifier: 'giftedSubscription',
-- payload: {replyTo: data.user._id},
-- }
-- );
+- payload: { replyTo: data.user._id },
+- });
- }
- }
}
@@ -7031,9 +7240,9 @@ index ba7305da8b..f01602701a 100644
- let cancelType = 'unsubscribe';
- let groupId;
let emailType;
- let emailMergeData = [];
+ const emailMergeData = [];
let sendEmail = true;
-@@ -300,20 +245,6 @@ async function cancelSubscription (data) {
+@@ -305,20 +250,6 @@ async function cancelSubscription (data) {
}
if (sendEmail) txnEmail(data.user, emailType, emailMergeData);
@@ -7053,12 +7262,12 @@ index ba7305da8b..f01602701a 100644
- });
}
- module.exports = {
+ export {
diff --git a/website/server/libs/setupPassport.js b/website/server/libs/setupPassport.js
-index 215c91daa5..1d2c933392 100644
+index 6520d07df8..1d2c933392 100644
--- a/website/server/libs/setupPassport.js
+++ b/website/server/libs/setupPassport.js
-@@ -1,32 +1,9 @@
+@@ -1,33 +1,9 @@
import passport from 'passport';
-import nconf from 'nconf';
-import { Strategy as FacebookStrategy } from 'passport-facebook';
@@ -7076,7 +7285,8 @@ index 215c91daa5..1d2c933392 100644
passport.deserializeUser((obj, done) => done(null, obj));
-
-// TODO remove?
--// This auth strategy is no longer used. It's just kept around for auth.js#loginFacebook() (passport._strategies.facebook.userProfile)
+-// This auth strategy is no longer used.
+-// It's just kept around for auth.js#loginFacebook() (passport._strategies.facebook.userProfile)
-// The proper fix would be to move to a general OAuth module simply to verify accessTokens
-passport.use(new FacebookStrategy({
- clientID: nconf.get('FACEBOOK_KEY'),
@@ -7093,10 +7303,10 @@ index 215c91daa5..1d2c933392 100644
- clientSecret: nconf.get('GOOGLE_CLIENT_SECRET'),
-}, (accessToken, refreshToken, profile, done) => done(null, profile)));
diff --git a/website/server/libs/user/index.js b/website/server/libs/user/index.js
-index 1274e16d21..5737a9ed6c 100644
+index bf1a185a2d..54f0358b33 100644
--- a/website/server/libs/user/index.js
+++ b/website/server/libs/user/index.js
-@@ -198,12 +198,6 @@ export async function reset (req, res, { isV3 = false }) {
+@@ -194,12 +194,6 @@ export async function reset (req, res, { isV3 = false }) {
user.save(),
]);
@@ -7109,16 +7319,16 @@ index 1274e16d21..5737a9ed6c 100644
res.respond(200, ...resetRes);
}
-@@ -215,7 +209,7 @@ export async function reroll (req, res, { isV3 = false }) {
+@@ -211,7 +205,7 @@ export async function reroll (req, res, { isV3 = false }) {
...Tasks.taskIsGroupOrChallengeQuery,
};
- let tasks = await Tasks.Task.find(query).exec();
+ const tasks = await Tasks.Task.find(query).exec();
- const rerollRes = common.ops.reroll(user, tasks, req, res.analytics);
+ const rerollRes = common.ops.reroll(user, tasks, req);
if (isV3) {
rerollRes[0].user = await rerollRes[0].user.toJSONWithInbox();
}
-@@ -236,7 +230,7 @@ export async function rebirth (req, res, { isV3 = false }) {
+@@ -232,7 +226,7 @@ export async function rebirth (req, res, { isV3 = false }) {
...Tasks.taskIsGroupOrChallengeQuery,
}).exec();
@@ -7128,16 +7338,17 @@ index 1274e16d21..5737a9ed6c 100644
rebirthRes[0].user = await rebirthRes[0].user.toJSONWithInbox();
}
diff --git a/website/server/middlewares/appRoutes.js b/website/server/middlewares/appRoutes.js
-index 5819c7231d..ce018e7718 100644
+index 179ed0082d..63003fdc9d 100644
--- a/website/server/middlewares/appRoutes.js
+++ b/website/server/middlewares/appRoutes.js
-@@ -1,6 +1,5 @@
+@@ -1,7 +1,6 @@
import express from 'express';
import expressValidator from 'express-validator';
+ import path from 'path';
-import analytics from './analytics';
import setupBody from './setupBody';
- import routes from '../libs/routes';
- import path from 'path';
+ import * as routes from '../libs/routes';
+
@@ -16,7 +15,6 @@ app.set('view engine', 'pug');
app.set('views', `${__dirname}/../../views`);
@@ -7147,18 +7358,18 @@ index 5819c7231d..ce018e7718 100644
const topLevelRouter = express.Router(); // eslint-disable-line new-cap
diff --git a/website/server/middlewares/auth.js b/website/server/middlewares/auth.js
-index 402cb93c27..0908dd42d7 100644
+index b9f680db34..a094e244f6 100644
--- a/website/server/middlewares/auth.js
+++ b/website/server/middlewares/auth.js
@@ -6,7 +6,6 @@ import {
+ import {
+ model as User,
} from '../models/user';
- import nconf from 'nconf';
- import url from 'url';
-import gcpStackdriverTracer from '../libs/gcpTraceAgent';
const COMMUNITY_MANAGER_EMAIL = nconf.get('EMAILS_COMMUNITY_MANAGER_EMAIL');
const USER_FIELDS_ALWAYS_LOADED = ['_id', 'notifications', 'preferences', 'auth', 'flags'];
-@@ -40,13 +39,6 @@ function getUserFields (options, req) {
+@@ -38,13 +37,6 @@ function getUserFields (options, req) {
return userFieldOptions.concat(USER_FIELDS_ALWAYS_LOADED).join(' ');
}
@@ -7172,7 +7383,7 @@ index 402cb93c27..0908dd42d7 100644
// Strins won't be translated here because getUserLanguage has not run yet
// Authenticate a request through the x-api-user and x-api key header
-@@ -78,7 +70,6 @@ export function authWithHeaders (options = {}) {
+@@ -76,7 +68,6 @@ export function authWithHeaders (options = {}) {
res.locals.user = user;
req.session.userId = user._id;
@@ -7180,7 +7391,7 @@ index 402cb93c27..0908dd42d7 100644
user.auth.timestamps.updated = new Date();
return next();
})
-@@ -107,7 +98,6 @@ export function authWithSession (req, res, next) {
+@@ -104,7 +95,6 @@ export function authWithSession (req, res, next) {
if (!user) throw new NotAuthorized(res.t('invalidCredentials'));
res.locals.user = user;
@@ -7189,32 +7400,31 @@ index 402cb93c27..0908dd42d7 100644
return next();
})
diff --git a/website/server/middlewares/cron.js b/website/server/middlewares/cron.js
-index 47368dc8fd..6b1115a809 100644
+index 365acaefd6..da528abac9 100644
--- a/website/server/middlewares/cron.js
+++ b/website/server/middlewares/cron.js
-@@ -54,7 +54,6 @@ async function cronAsync (req, res) {
- let user = res.locals.user;
+@@ -56,7 +56,6 @@ async function cronAsync (req, res) {
+ let { user } = res.locals;
if (!user) return null; // User might not be available when authentication is not mandatory
-- let analytics = res.analytics;
- let now = new Date();
+- const { analytics } = res;
+ const now = new Date();
try {
-@@ -83,7 +82,7 @@ async function cronAsync (req, res) {
- tasks.forEach(task => tasksByType[`${task.type}s`].push(task));
-
- // Run cron
-- let progress = cron({user, tasksByType, now, daysMissed, analytics, timezoneOffsetFromUserPrefs, headers: req.headers});
-+ let progress = cron({user, tasksByType, now, daysMissed, timezoneOffsetFromUserPrefs, headers: req.headers});
-
- // Clear old completed todos - 30 days for free users, 90 for subscribers
- // Do not delete challenges completed todos TODO unless the task is broken?
+@@ -93,7 +92,6 @@ async function cronAsync (req, res) {
+ tasksByType,
+ now,
+ daysMissed,
+- analytics,
+ timezoneOffsetFromUserPrefs,
+ headers: req.headers,
+ });
diff --git a/website/server/middlewares/errorHandler.js b/website/server/middlewares/errorHandler.js
-index 5b3cdb7390..e10fb3f749 100644
+index 4fddc09dd0..659e828085 100644
--- a/website/server/middlewares/errorHandler.js
+++ b/website/server/middlewares/errorHandler.js
-@@ -50,12 +50,6 @@ module.exports = function errorHandler (err, req, res, next) { // eslint-disable
- });
+@@ -46,12 +46,6 @@ export default function errorHandler (err, req, res, next) { // eslint-disable-l
+ }));
}
- // Handle Stripe Card errors errors (can be safely shown to the users)
@@ -7227,7 +7437,7 @@ index 5b3cdb7390..e10fb3f749 100644
// Try to identify the error...
// ...
diff --git a/website/server/middlewares/notFound.js b/website/server/middlewares/notFound.js
-index adf74bcbd1..67f63b364d 100644
+index feb73d8a7f..67ee5801f2 100644
--- a/website/server/middlewares/notFound.js
+++ b/website/server/middlewares/notFound.js
@@ -7,10 +7,6 @@ import { serveClient } from '../libs/client';
@@ -7242,19 +7452,19 @@ index adf74bcbd1..67f63b364d 100644
'/email',
'/qr-code',
diff --git a/website/server/models/challenge.js b/website/server/models/challenge.js
-index 97b37338d8..3f3444501c 100644
+index 3a545e3975..f2d958fde6 100644
--- a/website/server/models/challenge.js
+++ b/website/server/models/challenge.js
-@@ -10,7 +10,6 @@ import {
+@@ -11,7 +11,6 @@ import { // eslint-disable-line import/no-cycle
import { removeFromArray } from '../libs/collectionManipulators';
import shared from '../../common';
- import { sendTxn as txnEmail } from '../libs/email';
+ import { sendTxn as txnEmail } from '../libs/email'; // eslint-disable-line import/no-cycle
-import { sendNotification as sendPushNotification } from '../libs/pushNotifications';
- import { TaskQueue } from 'cwait';
import { syncableAttrs, setNextDue } from '../libs/taskManager';
-@@ -342,14 +341,6 @@ schema.methods.closeChal = async function closeChal (broken = {}) {
- {name: 'CHALLENGE_NAME', content: challenge.name},
+ const { Schema } = mongoose;
+@@ -362,14 +361,6 @@ schema.methods.closeChal = async function closeChal (broken = {}) {
+ { name: 'CHALLENGE_NAME', content: challenge.name },
]);
}
- if (savedWinner.preferences.pushNotifications.wonChallenge !== false) {
@@ -7269,26 +7479,26 @@ index 97b37338d8..3f3444501c 100644
// Run some operations in the background withouth blocking the thread
diff --git a/website/server/models/coupon.js b/website/server/models/coupon.js
-index f08a8135eb..fe391c9684 100644
+index 789431ba08..20f6836642 100644
--- a/website/server/models/coupon.js
+++ b/website/server/models/coupon.js
@@ -12,7 +12,7 @@ import {
- export let schema = new mongoose.Schema({
- _id: {$type: String, default: couponCode.generate, required: true},
-- event: {$type: String, enum: ['wondercon', 'google_6mo']},
-+ event: {$type: String, enum: ['wondercon']},
- user: {$type: String, ref: 'User'},
+ export const schema = new mongoose.Schema({
+ _id: { $type: String, default: couponCode.generate, required: true },
+- event: { $type: String, enum: ['wondercon', 'google_6mo'] },
++ event: { $type: String, enum: ['wondercon'] },
+ user: { $type: String, ref: 'User' },
}, {
strict: true,
diff --git a/website/server/models/group.js b/website/server/models/group.js
-index f7325bc636..489aba6938 100644
+index c05cf32878..7a6abe0e17 100644
--- a/website/server/models/group.js
+++ b/website/server/models/group.js
@@ -28,18 +28,14 @@ import {
+ } from '../libs/errors';
import baseModel from '../libs/baseModel';
- import { sendTxn as sendTxnEmail } from '../libs/email';
- import nconf from 'nconf';
+ import { sendTxn as sendTxnEmail } from '../libs/email'; // eslint-disable-line import/no-cycle
-import { sendNotification as sendPushNotification } from '../libs/pushNotifications';
import {
syncableAttrs,
@@ -7296,44 +7506,65 @@ index f7325bc636..489aba6938 100644
import {
schema as SubscriptionPlanSchema,
} from './subscriptionPlan';
--import amazonPayments from '../libs/payments/amazon';
--import stripePayments from '../libs/payments/stripe';
- import { getGroupChat, translateMessage } from '../libs/chat/group-chat';
+-import amazonPayments from '../libs/payments/amazon'; // eslint-disable-line import/no-cycle
+-import stripePayments from '../libs/payments/stripe'; // eslint-disable-line import/no-cycle
+ import { getGroupChat, translateMessage } from '../libs/chat/group-chat'; // eslint-disable-line import/no-cycle
import { model as UserNotification } from './userNotification';
--import { sendChatPushNotifications } from '../libs/chat';
+-import { sendChatPushNotifications } from '../libs/chat'; // eslint-disable-line import/no-cycle
const questScrolls = shared.content.quests;
- const questSeriesAchievements = shared.content.questSeriesAchievements;
-@@ -513,7 +509,7 @@ schema.methods.getMemberCount = async function getMemberCount () {
- };
-
- schema.methods.sendChat = function sendChat (options = {}) {
-- const {message, user, metaData, client, flagCount = 0, info = {}, translate} = options;
-+ const {message, user, metaData, client, flagCount = 0, info = {}} = options;
- let newMessage = messageDefaults(message, user, client, flagCount, info);
- let newChatMessage = new Chat();
- newChatMessage = Object.assign(newChatMessage, newMessage);
-@@ -575,10 +571,6 @@ schema.methods.sendChat = function sendChat (options = {}) {
- User.update(query, lastSeenUpdateAddNew, {multi: true}).exec();
+ const { questSeriesAchievements } = shared.content;
+@@ -543,7 +539,6 @@ schema.methods.sendChat = function sendChat (options = {}) {
+ const {
+ message, user, metaData,
+ client, flagCount = 0, info = {},
+- translate, mentions, mentionedMembers,
+ } = options;
+ const newMessage = messageDefaults(message, user, client, flagCount, info);
+
+@@ -611,32 +606,6 @@ schema.methods.sendChat = function sendChat (options = {}) {
+ User.update(query, lastSeenUpdateAddNew, { multi: true }).exec();
});
- if (this.type === 'party' && user) {
-- sendChatPushNotifications(user, this, newChatMessage, translate);
+- sendChatPushNotifications(user, this, newChatMessage, mentions, translate);
+- }
+- if (mentionedMembers) {
+- mentionedMembers.forEach(member => {
+- if (member._id === user._id) return;
+- const pushNotifPrefs = member.preferences.pushNotifications;
+- if (this.type === 'party') {
+- if (pushNotifPrefs.mentionParty !== true || !this.isMember(member)) {
+- return;
+- }
+- } else if (this.isMember(member)) {
+- if (pushNotifPrefs.mentionJoinedGuild !== true) {
+- return;
+- }
+- } else {
+- if (this.privacy !== 'public') {
+- return;
+- }
+- if (pushNotifPrefs.mentionUnjoinedGuild !== true) {
+- return;
+- }
+- }
+- sendPushNotification(member, { identifier: 'chatMention', title: `${user.profile.name} mentioned you in ${this.name}`, message });
+- });
- }
--
return newChatMessage;
};
-@@ -622,7 +614,7 @@ schema.methods.startQuest = async function startQuest (user) {
+@@ -679,7 +648,7 @@ schema.methods.startQuest = async function startQuest (user) {
await User.find({
- _id: {$in: Object.keys(this.quest.members)},
+ _id: { $in: Object.keys(this.quest.members) },
})
- .select('party.quest party._id items.quests auth preferences.emailNotifications preferences.pushNotifications preferences.language pushDevices profile.name webhooks')
+ .select('party.quest party._id items.quests auth preferences.emailNotifications profile.name webhooks')
.lean()
.exec()
.then(partyMembers => {
-@@ -698,16 +690,6 @@ schema.methods.startQuest = async function startQuest (user) {
+@@ -755,16 +724,6 @@ schema.methods.startQuest = async function startQuest (user) {
if (member.preferences.emailNotifications.questStarted !== false) {
membersToEmail.push(member);
}
@@ -7350,7 +7581,7 @@ index f7325bc636..489aba6938 100644
}
// Send webhooks
-@@ -1580,7 +1562,7 @@ schema.methods.hasCancelled = function hasNotCancelled () {
+@@ -1661,7 +1620,7 @@ schema.methods.hasCancelled = function hasNotCancelled () {
return Boolean(this.isSubscribed() && plan.dateTerminated);
};
@@ -7359,27 +7590,30 @@ index f7325bc636..489aba6938 100644
// Recheck the group plan count
let members;
if (this.type === 'guild') {
-@@ -1589,12 +1571,6 @@ schema.methods.updateGroupPlan = async function updateGroupPlan (removingMember)
- members = await User.find({'party._id': this._id}).select('_id').exec();
+@@ -1670,15 +1629,6 @@ schema.methods.updateGroupPlan = async function updateGroupPlan (removingMember)
+ members = await User.find({ 'party._id': this._id }).select('_id').exec();
}
this.memberCount = members.length;
-
- if (this.purchased.plan.paymentMethod === stripePayments.constants.PAYMENT_METHOD) {
- await stripePayments.chargeForAdditionalGroupMember(this);
-- } else if (this.purchased.plan.paymentMethod === amazonPayments.constants.PAYMENT_METHOD && !removingMember) {
+- } else if (
+- this.purchased.plan.paymentMethod === amazonPayments.constants.PAYMENT_METHOD
+- && !removingMember
+- ) {
- await amazonPayments.chargeForAdditionalGroupMember(this);
- }
};
- export let model = mongoose.model('Group', schema);
+ export const model = mongoose.model('Group', schema);
diff --git a/website/server/models/subscriptionPlan.js b/website/server/models/subscriptionPlan.js
-index aaf2cbf148..383ea0c102 100644
+index d59e10b14f..d40bcfe1f3 100644
--- a/website/server/models/subscriptionPlan.js
+++ b/website/server/models/subscriptionPlan.js
-@@ -7,8 +7,8 @@ export let schema = new mongoose.Schema({
+@@ -7,8 +7,8 @@ export const schema = new mongoose.Schema({
subscriptionId: String,
- owner: {$type: String, ref: 'User', validate: [v => validator.isUUID(v), 'Invalid uuid.']},
- quantity: {$type: Number, default: 1},
+ owner: { $type: String, ref: 'User', validate: [v => validator.isUUID(v), 'Invalid uuid.'] },
+ quantity: { $type: Number, default: 1 },
- paymentMethod: String, // enum: ['Paypal', 'Stripe', 'Gift', 'Amazon Payments', 'Google', '']}
- customerId: String, // Billing Agreement Id in case of Amazon Payments
+ paymentMethod: String, // enum: ['Gift', '']}
@@ -7387,35 +7621,36 @@ index aaf2cbf148..383ea0c102 100644
dateCreated: Date,
dateTerminated: Date,
dateUpdated: Date,
-@@ -16,10 +16,10 @@ export let schema = new mongoose.Schema({
- gemsBought: {$type: Number, default: 0},
- mysteryItems: {$type: Array, default: () => []},
+@@ -16,12 +16,11 @@ export const schema = new mongoose.Schema({
+ gemsBought: { $type: Number, default: 0 },
+ mysteryItems: { $type: Array, default: () => [] },
lastReminderDate: Date, // indicates the last time a subscription reminder was sent
- lastBillingDate: Date, // Used only for Amazon Payments to keep track of billing date
-- additionalData: mongoose.Schema.Types.Mixed, // Example for Google: {'receipt': 'serialized receipt json', 'signature': 'signature string'}
+- // Example for Google: {'receipt': 'serialized receipt json', 'signature': 'signature string'}
+ lastBillingDate: Date,
-+ additionalData: mongoose.Schema.Types.Mixed,
- nextPaymentProcessing: Date, // indicates when the queue server should process this subscription again.
+ additionalData: mongoose.Schema.Types.Mixed,
+ // indicates when the queue server should process this subscription again.
+ nextPaymentProcessing: Date,
- nextBillingDate: Date, // Next time google will bill this user.
+ nextBillingDate: Date,
consecutive: {
- count: {$type: Number, default: 0},
- offset: {$type: Number, default: 0}, // when gifted subs, offset++ for each month. offset-- each new-month (cron). count doesn't ++ until offset==0
+ count: { $type: Number, default: 0 },
+ // when gifted subs, offset++ for each month. offset-- each new-month (cron).
diff --git a/website/server/models/user/methods.js b/website/server/models/user/methods.js
-index 5a49fea5a0..14ccb1fee8 100644
+index 11775ee37f..ffcabb0113 100644
--- a/website/server/models/user/methods.js
+++ b/website/server/models/user/methods.js
-@@ -17,9 +17,6 @@ import { model as UserNotification } from '../userNotification';
- import schema from './schema';
- import payments from '../../libs/payments/payments';
- import * as inboxLib from '../../libs/inbox';
--import amazonPayments from '../../libs/payments/amazon';
--import stripePayments from '../../libs/payments/stripe';
--import paypalPayments from '../../libs/payments/paypal';
+@@ -19,9 +19,6 @@ import { model as UserNotification } from '../userNotification';
+ import schema from './schema'; // eslint-disable-line import/no-cycle
+ import payments from '../../libs/payments/payments'; // eslint-disable-line import/no-cycle
+ import * as inboxLib from '../../libs/inbox'; // eslint-disable-line import/no-cycle
+-import amazonPayments from '../../libs/payments/amazon'; // eslint-disable-line import/no-cycle
+-import stripePayments from '../../libs/payments/stripe'; // eslint-disable-line import/no-cycle
+-import paypalPayments from '../../libs/payments/paypal'; // eslint-disable-line import/no-cycle
- const daysSince = common.daysSince;
+ const { daysSince } = common;
-@@ -244,7 +241,7 @@ schema.statics.addComputedStatsToJSONObj = function addComputedStatsToUserJSONOb
+@@ -266,7 +263,7 @@ schema.statics.addComputedStatsToJSONObj = function addComputedStatsToUserJSONOb
* @param options
* @param options.user The user object who is purchasing
* @param options.groupId The id of the group purchasing a subscription
@@ -7424,78 +7659,80 @@ index 5a49fea5a0..14ccb1fee8 100644
* @param options.cancellationReason A text string to control sending an email
*
* @return a Promise from api.cancelSubscription()
-@@ -255,18 +252,7 @@ schema.statics.addComputedStatsToJSONObj = function addComputedStatsToUserJSONOb
- // In summary, currently is is best practice to use this method to cancel a user subscription, rather than calling the
+@@ -281,18 +278,7 @@ schema.statics.addComputedStatsToJSONObj = function addComputedStatsToUserJSONOb
+ // rather than calling the
// payment helper.
schema.methods.cancelSubscription = async function cancelSubscription (options = {}) {
-- let plan = this.purchased.plan;
+- const { plan } = this.purchased;
-
options.user = this;
- if (plan.paymentMethod === amazonPayments.constants.PAYMENT_METHOD) {
-- return await amazonPayments.cancelSubscription(options);
-- } else if (plan.paymentMethod === stripePayments.constants.PAYMENT_METHOD) {
-- return await stripePayments.cancelSubscription(options);
-- } else if (plan.paymentMethod === paypalPayments.constants.PAYMENT_METHOD) {
-- return await paypalPayments.subscribeCancel(options);
+- return amazonPayments.cancelSubscription(options);
+- } if (plan.paymentMethod === stripePayments.constants.PAYMENT_METHOD) {
+- return stripePayments.cancelSubscription(options);
+- } if (plan.paymentMethod === paypalPayments.constants.PAYMENT_METHOD) {
+- return paypalPayments.subscribeCancel(options);
- }
- // Android and iOS subscriptions cannot be cancelled by Habitica.
-
- return await payments.cancelSubscription(options);
+ return payments.cancelSubscription(options);
};
diff --git a/website/server/models/user/schema.js b/website/server/models/user/schema.js
-index af67e08522..621f66e92c 100644
+index 316eda698d..1e472b4361 100644
--- a/website/server/models/user/schema.js
+++ b/website/server/models/user/schema.js
@@ -2,7 +2,6 @@ import mongoose from 'mongoose';
- import shared from '../../../common';
import validator from 'validator';
+ import shared from '../../../common';
import { schema as TagSchema } from '../tag';
-import { schema as PushDeviceSchema } from '../pushDevice';
import { schema as WebhookSchema } from '../webhook';
import {
schema as UserNotificationSchema,
-@@ -27,12 +26,6 @@ let schema = new Schema({
+@@ -27,14 +26,6 @@ export default new Schema({
auth: {
blocked: Boolean,
-- facebook: {$type: Schema.Types.Mixed, default: () => {
-- return {};
-- }},
-- google: {$type: Schema.Types.Mixed, default: () => {
-- return {};
-- }},
+- facebook: {
+- $type: Schema.Types.Mixed,
+- default: () => ({}),
+- },
+- google: {
+- $type: Schema.Types.Mixed,
+- default: () => ({}),
+- },
local: {
email: {
$type: String,
-@@ -493,22 +486,6 @@ let schema = new Schema({
- majorUpdates: {$type: Boolean, default: true},
- subscriptionReminders: {$type: Boolean, default: true},
+@@ -522,22 +513,6 @@ export default new Schema({
+ majorUpdates: { $type: Boolean, default: true },
+ subscriptionReminders: { $type: Boolean, default: true },
},
- pushNotifications: {
-- unsubscribeFromAll: {$type: Boolean, default: false},
-- newPM: {$type: Boolean, default: true},
-- wonChallenge: {$type: Boolean, default: true},
-- giftedGems: {$type: Boolean, default: true},
-- giftedSubscription: {$type: Boolean, default: true},
-- invitedParty: {$type: Boolean, default: true},
-- invitedGuild: {$type: Boolean, default: true},
-- questStarted: {$type: Boolean, default: true},
-- invitedQuest: {$type: Boolean, default: true},
-- majorUpdates: {$type: Boolean, default: true},
-- mentionParty: {$type: Boolean, default: true},
-- mentionJoinedGuild: {$type: Boolean, default: true},
-- mentionUnjoinedGuild: {$type: Boolean, default: true},
-- partyActivity: {$type: Boolean, default: true},
+- unsubscribeFromAll: { $type: Boolean, default: false },
+- newPM: { $type: Boolean, default: true },
+- wonChallenge: { $type: Boolean, default: true },
+- giftedGems: { $type: Boolean, default: true },
+- giftedSubscription: { $type: Boolean, default: true },
+- invitedParty: { $type: Boolean, default: true },
+- invitedGuild: { $type: Boolean, default: true },
+- questStarted: { $type: Boolean, default: true },
+- invitedQuest: { $type: Boolean, default: true },
+- majorUpdates: { $type: Boolean, default: true },
+- mentionParty: { $type: Boolean, default: true },
+- mentionJoinedGuild: { $type: Boolean, default: true },
+- mentionUnjoinedGuild: { $type: Boolean, default: true },
+- partyActivity: { $type: Boolean, default: true },
- },
suppressModals: {
- levelUp: {$type: Boolean, default: false},
- hatchPet: {$type: Boolean, default: false},
-@@ -589,7 +566,6 @@ let schema = new Schema({
- extra: {$type: Schema.Types.Mixed, default: () => {
- return {};
- }},
+ levelUp: { $type: Boolean, default: false },
+ hatchPet: { $type: Boolean, default: false },
+@@ -622,7 +597,6 @@ export default new Schema({
+ $type: Schema.Types.Mixed,
+ default: () => ({}),
+ },
- pushDevices: [PushDeviceSchema],
- _ABtests: {$type: Schema.Types.Mixed, default: () => {
- return {};
- }},
+ _ABtests: {
+ $type: Schema.Types.Mixed,
+ default: () => ({}),
diff --git a/pkgs/shabitica/patches/remove-news.patch b/pkgs/shabitica/patches/remove-news.patch
index bd5d072..8c31543 100644
--- a/pkgs/shabitica/patches/remove-news.patch
+++ b/pkgs/shabitica/patches/remove-news.patch
@@ -14,51 +14,50 @@ Date: Wed Apr 11 14:32:43 2018 +0200
Signed-off-by: aszlig <aszlig@nix.build>
Filename: remove-news.patch
-diff --git a/website/client/components/header/notifications/base.vue b/website/client/components/header/notifications/base.vue
-index fc6bcbaa68..9155977e45 100644
---- a/website/client/components/header/notifications/base.vue
-+++ b/website/client/components/header/notifications/base.vue
-@@ -4,7 +4,7 @@
- )
- .notification-icon.d-flex.justify-content-center.align-items-center(
- v-if="hasIcon",
-- :class="{'is-not-bailey': isNotBailey}",
-+ :class="is-not-bailey",
- )
- slot(name="icon")
- .notification-content
-@@ -131,9 +131,6 @@ export default {
+diff --git a/website/client/src/components/header/notifications/base.vue b/website/client/src/components/header/notifications/base.vue
+index ab6ed946fc..3fd0fdb5de 100644
+--- a/website/client/src/components/header/notifications/base.vue
++++ b/website/client/src/components/header/notifications/base.vue
+@@ -6,7 +6,7 @@
+ <div
+ v-if="hasIcon"
+ class="notification-icon d-flex justify-content-center align-items-center"
+- :class="{'is-not-bailey': isNotBailey}"
++ :class="is-not-bailey"
+ >
+ <slot name="icon"></slot>
+ </div>
+@@ -141,9 +141,6 @@ export default {
},
computed: {
- ...mapState({user: 'user.data'}),
+ ...mapState({ user: 'user.data' }),
- isNotBailey () {
- return this.notification.type !== 'NEW_STUFF';
- },
},
methods: {
...mapActions({
-diff --git a/website/client/components/header/notificationsDropdown.vue b/website/client/components/header/notificationsDropdown.vue
-index a325c054b9..de8dd8244a 100644
---- a/website/client/components/header/notificationsDropdown.vue
-+++ b/website/client/components/header/notificationsDropdown.vue
-@@ -79,7 +79,6 @@ import MessageCount from './messageCount';
- import successImage from 'assets/svg/success.svg';
+diff --git a/website/client/src/components/header/notificationsDropdown.vue b/website/client/src/components/header/notificationsDropdown.vue
+index c55d344242..cf69fa355b 100644
+--- a/website/client/src/components/header/notificationsDropdown.vue
++++ b/website/client/src/components/header/notificationsDropdown.vue
+@@ -112,7 +112,6 @@ import MessageCount from './messageCount';
+ import successImage from '@/assets/svg/success.svg';
// Notifications
-import NEW_STUFF from './notifications/newStuff';
import GROUP_TASK_NEEDS_WORK from './notifications/groupTaskNeedsWork';
import GUILD_INVITATION from './notifications/guildInvitation';
import PARTY_INVITATION from './notifications/partyInvitation';
-@@ -105,7 +104,7 @@ export default {
+@@ -138,7 +137,6 @@ export default {
MenuDropdown,
MessageCount,
// One component for each type
-- NEW_STUFF, GROUP_TASK_NEEDS_WORK,
-+ GROUP_TASK_NEEDS_WORK,
- GUILD_INVITATION, PARTY_INVITATION, CHALLENGE_INVITATION,
- QUEST_INVITATION, GROUP_TASK_APPROVAL, GROUP_TASK_APPROVED, GROUP_TASK_ASSIGNED, GROUP_TASK_CLAIMED,
- UNALLOCATED_STATS_POINTS, NEW_MYSTERY_ITEMS, CARD_RECEIVED,
-@@ -130,7 +129,7 @@ export default {
+- NEW_STUFF,
+ GROUP_TASK_NEEDS_WORK,
+ GUILD_INVITATION,
+ PARTY_INVITATION,
+@@ -175,7 +173,7 @@ export default {
// listed in the order they should appear in the notifications panel.
// NOTE: Those not listed here won't be shown in the notification panel!
handledNotifications: [
@@ -67,35 +66,35 @@ index a325c054b9..de8dd8244a 100644
'GUILD_INVITATION', 'PARTY_INVITATION', 'CHALLENGE_INVITATION',
'QUEST_INVITATION', 'GROUP_TASK_ASSIGNED', 'GROUP_TASK_APPROVAL', 'GROUP_TASK_APPROVED', 'GROUP_TASK_CLAIMED',
'NEW_MYSTERY_ITEMS', 'CARD_RECEIVED',
-diff --git a/website/client/components/notifications.vue b/website/client/components/notifications.vue
-index b5e688c1ad..154d127c4d 100644
---- a/website/client/components/notifications.vue
-+++ b/website/client/components/notifications.vue
-@@ -5,7 +5,6 @@ div
- @run-cron="runYesterDailiesAction()",
- )
- armoire-empty
-- new-stuff
- death
- low-health
- level-up
-@@ -102,7 +101,6 @@ import guide from 'client/mixins/guide';
+diff --git a/website/client/src/components/notifications.vue b/website/client/src/components/notifications.vue
+index b2201a5e1f..28b5fb9fde 100644
+--- a/website/client/src/components/notifications.vue
++++ b/website/client/src/components/notifications.vue
+@@ -5,7 +5,6 @@
+ @run-cron="runYesterDailiesAction()"
+ />
+ <armoire-empty />
+- <new-stuff />
+ <death />
+ <low-health />
+ <level-up />
+@@ -107,7 +106,6 @@ import notifications from '@/mixins/notifications';
+ import guide from '@/mixins/guide';
import yesterdailyModal from './yesterdailyModal';
- import welcomeModal from './achievements/welcome';
-import newStuff from './achievements/newStuff';
import death from './achievements/death';
import lowHealth from './achievements/lowHealth';
import levelUp from './achievements/levelUp';
-@@ -189,7 +187,6 @@ export default {
+@@ -239,7 +237,6 @@ export default {
+ joinedGuild,
joinedChallenge,
invitedFriend,
- welcomeModal,
- newStuff,
death,
lowHealth,
levelUp,
-@@ -441,10 +438,6 @@ export default {
+@@ -506,10 +503,6 @@ export default {
return this.$root.$emit('bv::show::modal', 'avatar-modal');
}
@@ -106,19 +105,27 @@ index b5e688c1ad..154d127c4d 100644
if (this.user.stats.hp <= 0) {
return this.showDeathModal();
}
-diff --git a/website/client/components/settings/site.vue b/website/client/components/settings/site.vue
-index 0fefae00d2..104cc29bc4 100644
---- a/website/client/components/settings/site.vue
-+++ b/website/client/components/settings/site.vue
-@@ -78,7 +78,6 @@
-
- hr
-
-- button.btn.btn-primary.mr-2.mb-2(@click='showBailey()', popover-trigger='mouseenter', popover-placement='right', :popover="$t('showBaileyPop')") {{ $t('showBailey') }}
- button.btn.btn-primary.mr-2.mb-2(@click='openRestoreModal()', popover-trigger='mouseenter', popover-placement='right', :popover="$t('fixValPop')") {{ $t('fixVal') }}
- button.btn.btn-primary.mb-2(v-if='user.preferences.disableClasses == true', @click='changeClassForUser(false)',
- popover-trigger='mouseenter', popover-placement='right', :popover="$t('enableClassPop')") {{ $t('enableClass') }}
-@@ -396,9 +395,6 @@ export default {
+diff --git a/website/client/src/components/settings/site.vue b/website/client/src/components/settings/site.vue
+index 2c96a9272f..ed4cece090 100644
+--- a/website/client/src/components/settings/site.vue
++++ b/website/client/src/components/settings/site.vue
+@@ -177,15 +177,6 @@
+ <label>{{ $t('suppressStreakModal') }}</label>
+ </div>
+ <hr>
+- <button
+- class="btn btn-primary mr-2 mb-2"
+- popover-trigger="mouseenter"
+- popover-placement="right"
+- :popover="$t('showBaileyPop')"
+- @click="showBailey()"
+- >
+- {{ $t('showBailey') }}
+- </button>
+ <button
+ class="btn btn-primary mr-2 mb-2"
+ popover-trigger="mouseenter"
+@@ -716,9 +707,6 @@ export default {
// User.set({'flags.showTour':true});
// Guide.goto('intro', 0, true);
},
@@ -126,31 +133,38 @@ index 0fefae00d2..104cc29bc4 100644
- this.$root.$emit('bv::show::modal', 'new-stuff');
- },
calculateNextCron () {
- let nextCron = moment().hours(this.newDayStart).minutes(0).seconds(0).milliseconds(0);
-
-diff --git a/website/client/components/static/staticWrapper.vue b/website/client/components/static/staticWrapper.vue
-index eefe1fe6ea..dee1f5a586 100644
---- a/website/client/components/static/staticWrapper.vue
-+++ b/website/client/components/static/staticWrapper.vue
-@@ -1,14 +1,14 @@
- <template lang="pug">
- div
-- static-header(v-if='showContentWrap', :class='{"home-header": ["home", "front"].indexOf($route.name) !== -1, "white-header": this.$route.name === "plans"}')
-+ static-header(:class='{"home-header": ["home", "front"].indexOf($route.name) !== -1, "white-header": this.$route.name === "plans"}')
-
- .static-wrapper
- router-view
-
-- div(:id='footerId', v-if='showContentWrap')
-+ div(:id='footerId')
- app-footer
-
-- #bottom-wrap.purple-4(v-if='showContentWrap && footerId')
-+ #bottom-wrap.purple-4(v-if='footerId')
- #bottom-background
- .seamless_mountains_demo_repeat
- .midground_foreground_extended2
-@@ -166,9 +166,6 @@ export default {
+ let nextCron = moment().hours(this.newDayStart).minutes(0).seconds(0)
+ .milliseconds(0);
+diff --git a/website/client/src/components/static/staticWrapper.vue b/website/client/src/components/static/staticWrapper.vue
+index 517db5f983..cb2962c7b9 100644
+--- a/website/client/src/components/static/staticWrapper.vue
++++ b/website/client/src/components/static/staticWrapper.vue
+@@ -1,7 +1,6 @@
+ <template>
+ <div>
+ <static-header
+- v-if="showContentWrap"
+ :class="{
+ 'home-header': ['home', 'front'].indexOf($route.name) !== -1,
+ 'white-header': this.$route.name === 'plans'
+@@ -10,14 +9,11 @@
+ <div class="static-wrapper">
+ <router-view />
+ </div>
+- <div
+- v-if="showContentWrap"
+- :id="footerId"
+- >
++ <div :id="footerId">
+ <app-footer />
+ </div>
+ <div
+- v-if="showContentWrap && footerId"
++ v-if="footerId"
+ id="bottom-wrap"
+ class="purple-4"
+ >
+@@ -181,9 +177,6 @@ export default {
StaticHeader,
},
computed: {
@@ -158,33 +172,35 @@ index eefe1fe6ea..dee1f5a586 100644
- return this.$route.name !== 'news';
- },
footerId () {
- if (this.$route.name === 'plans') return;
+ if (this.$route.name === 'plans') return null;
return 'purple-footer';
-diff --git a/website/client/router/index.js b/website/client/router/index.js
-index 983ff4e296..db9fbc0fae 100644
---- a/website/client/router/index.js
-+++ b/website/client/router/index.js
-@@ -12,7 +12,6 @@ const AppPage = () => import(/* webpackChunkName: "static" */'client/components/
- const ClearBrowserDataPage = () => import(/* webpackChunkName: "static" */'client/components/static/clearBrowserData');
- const FAQPage = () => import(/* webpackChunkName: "static" */'client/components/static/faq');
- const FeaturesPage = () => import(/* webpackChunkName: "static" */'client/components/static/features');
--const NewsPage = () => import(/* webpackChunkName: "static" */'client/components/static/newStuff');
- const OverviewPage = () => import(/* webpackChunkName: "static" */'client/components/static/overview');
- const PrivacyPage = () => import(/* webpackChunkName: "static" */'client/components/static/privacy');
- const TermsPage = () => import(/* webpackChunkName: "static" */'client/components/static/terms');
-@@ -239,7 +238,6 @@ const router = new VueRouter({
- { name: 'features', path: 'features', component: FeaturesPage, 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: 'privacy', path: 'privacy', component: PrivacyPage, meta: {requiresLogin: false}},
- { name: 'terms', path: 'terms', component: TermsPage, meta: {requiresLogin: false}},
-diff --git a/website/client/store/actions/user.js b/website/client/store/actions/user.js
-index c8edffe287..575752d9e9 100644
---- a/website/client/store/actions/user.js
-+++ b/website/client/store/actions/user.js
-@@ -132,11 +132,6 @@ export async function openMysteryItem (store) {
+diff --git a/website/client/src/router/index.js b/website/client/src/router/index.js
+index a45639ad32..f5d39e8a54 100644
+--- a/website/client/src/router/index.js
++++ b/website/client/src/router/index.js
+@@ -12,7 +12,6 @@ const AppPage = () => import(/* webpackChunkName: "static" */'@/components/stati
+ const ClearBrowserDataPage = () => import(/* webpackChunkName: "static" */'@/components/static/clearBrowserData');
+ const FAQPage = () => import(/* webpackChunkName: "static" */'@/components/static/faq');
+ const FeaturesPage = () => import(/* webpackChunkName: "static" */'@/components/static/features');
+-const NewsPage = () => import(/* webpackChunkName: "static" */'@/components/static/newStuff');
+ const OverviewPage = () => import(/* webpackChunkName: "static" */'@/components/static/overview');
+ const PrivacyPage = () => import(/* webpackChunkName: "static" */'@/components/static/privacy');
+ const TermsPage = () => import(/* webpackChunkName: "static" */'@/components/static/terms');
+@@ -258,9 +257,6 @@ const router = new VueRouter({
+ {
+ 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 },
+ },
+diff --git a/website/client/src/store/actions/user.js b/website/client/src/store/actions/user.js
+index 87697b39af..0248ac4797 100644
+--- a/website/client/src/store/actions/user.js
++++ b/website/client/src/store/actions/user.js
+@@ -130,11 +130,6 @@ export async function openMysteryItem (store) {
return axios.post('/api/v4/user/open-mystery-item');
}
@@ -194,10 +210,10 @@ index c8edffe287..575752d9e9 100644
-}
-
export async function rebirth () {
- let result = await axios.post('/api/v4/user/rebirth');
+ const result = await axios.post('/api/v4/user/rebirth');
diff --git a/website/server/libs/user/index.js b/website/server/libs/user/index.js
-index c65a199049..526fa4ac9c 100644
+index 0b5aea4984..26906b7621 100644
--- a/website/server/libs/user/index.js
+++ b/website/server/libs/user/index.js
@@ -41,7 +41,6 @@ const updatablePaths = [
@@ -209,19 +225,19 @@ index c65a199049..526fa4ac9c 100644
'achievements',
diff --git a/website/server/models/user/schema.js b/website/server/models/user/schema.js
-index 700c5e51bc..732a4f5bf9 100644
+index 7ab6dde58e..a84d3ca55b 100644
--- a/website/server/models/user/schema.js
+++ b/website/server/models/user/schema.js
-@@ -205,7 +205,6 @@ let schema = new Schema({
+@@ -215,7 +215,6 @@ export default new Schema({
},
- dropsEnabled: {$type: Boolean, default: false},
- itemsEnabled: {$type: Boolean, default: false},
-- newStuff: {$type: Boolean, default: false},
- rewrite: {$type: Boolean, default: true},
- classSelected: {$type: Boolean, default: false},
+ dropsEnabled: { $type: Boolean, default: false },
+ itemsEnabled: { $type: Boolean, default: false },
+- newStuff: { $type: Boolean, default: false },
+ rewrite: { $type: Boolean, default: true },
+ classSelected: { $type: Boolean, default: false },
mathUpdates: Boolean,
diff --git a/website/server/models/userNotification.js b/website/server/models/userNotification.js
-index aa3ed7abfc..a3d63a800c 100644
+index 747d5f98c6..4c077241cb 100644
--- a/website/server/models/userNotification.js
+++ b/website/server/models/userNotification.js
@@ -30,7 +30,6 @@ const NOTIFICATION_TYPES = [
diff --git a/pkgs/shabitica/patches/remove-presskit-merch-plans.patch b/pkgs/shabitica/patches/remove-presskit-merch-plans.patch
index 64d36c3..245c01b 100644
--- a/pkgs/shabitica/patches/remove-presskit-merch-plans.patch
+++ b/pkgs/shabitica/patches/remove-presskit-merch-plans.patch
@@ -9,42 +9,101 @@ Date: Sat Mar 31 02:10:24 2018 +0200
Signed-off-by: aszlig <aszlig@nix.build>
Filename: remove-presskit-merch-plans.patch
-diff --git a/website/client/components/static/header.vue b/website/client/components/static/header.vue
-index fefaa20896..7a865e176a 100644
---- a/website/client/components/static/header.vue
-+++ b/website/client/components/static/header.vue
-@@ -5,25 +5,13 @@
- .logo.svg-icon(v-html='icons.purpleLogo', v-if='this.$route.name === "plans"')
- .logo.svg-icon(v-html='icons.logo', v-else)
- .collapse.navbar-collapse
-- ul.navbar-nav.mr-auto(v-if='$route.name !== "home"')
-+ ul.navbar-nav.mr-auto
- router-link.nav-item(tag='li', to='/static/features')
- a.nav-link(v-once) {{ $t('companyAbout') }}
-- router-link.nav-item(tag='li', to='/static/plans')
-- a.nav-link(v-once) {{ $t('groupPlans') }}
-- li.nav-item
-- a.nav-link(href='https://habitica.wordpress.com/', target='_blank') {{ $t('companyBlog') }}
-- li.nav-item
-- a.nav-link(href='http://blog.habitrpg.com/', target='_blank') {{ $t('tumblr') }}
-- router-link.nav-item(tag='li', to='/static/press-kit')
-- a.nav-link(v-once) {{ $t('presskit') }}
-- ul.navbar-nav.mr-auto(v-else)
-- router-link.nav-item(tag='li', to='/register')
-- a.nav-link(v-once) {{ $t('getStarted') }}
-- li.nav-item.dropdown
-- a.nav-link.dropdown-toggle(v-once) {{ $t('learnMore') }}
-- .dropdown-menu
-- router-link.dropdown-item(to='/static/faq') {{ $t('faq') }}
-- router-link.dropdown-item(to='/static/plans') {{ $t('groupPlans') }}
-+ router-link.nav-item(tag='li', to='/static/faq')
-+ a.nav-link(v-once) {{ $t('faq') }}
-+ router-link.nav-item(tag='li', to='/static/overview')
-+ a.nav-link(v-once) {{ $t('overview') }}
- button.btn.btn-primary.pull-right(@click='playButtonClick()', v-if='$route.name !== "home"') {{ $t('playButtonFull') }}
- router-link.btn.btn-primary.login-button.pull-right(to='/login', v-if='$route.name === "home"') {{ $t('login') }}
- </template>
-@@ -88,66 +76,10 @@
+diff --git a/website/client/src/components/static/header.vue b/website/client/src/components/static/header.vue
+index 21046b842d..feb2b6b01d 100644
+--- a/website/client/src/components/static/header.vue
++++ b/website/client/src/components/static/header.vue
+@@ -18,10 +18,7 @@
+ </router-link>
+ </div>
+ <div class="collapse navbar-collapse">
+- <ul
+- v-if="$route.name !== 'home'"
+- class="navbar-nav mr-auto"
+- >
++ <ul class="navbar-nav mr-auto">
+ <router-link
+ class="nav-item"
+ tag="li"
+@@ -35,73 +32,24 @@
+ <router-link
+ class="nav-item"
+ tag="li"
+- to="/static/plans"
++ to="/static/faq"
+ >
+ <a
+ v-once
+ class="nav-link"
+- >{{ $t('groupPlans') }}</a>
++ >{{ $t('faq') }}</a>
+ </router-link>
+- <li class="nav-item">
+- <a
+- class="nav-link"
+- href="https://habitica.wordpress.com/"
+- target="_blank"
+- >{{ $t('companyBlog') }}</a>
+- </li>
+- <li class="nav-item">
+- <a
+- class="nav-link"
+- href="http://blog.habitrpg.com/"
+- target="_blank"
+- >{{ $t('tumblr') }}</a>
+- </li>
+ <router-link
+ class="nav-item"
+ tag="li"
+- to="/static/press-kit"
++ to="/static/overview"
+ >
+ <a
+ v-once
+ class="nav-link"
+- >{{ $t('presskit') }}</a>
++ >{{ $t('overview') }}</a>
+ </router-link>
+ </ul>
+- <ul
+- v-else
+- class="navbar-nav mr-auto"
+- >
+- <router-link
+- class="nav-item"
+- tag="li"
+- to="/register"
+- >
+- <a
+- v-once
+- class="nav-link"
+- >{{ $t('getStarted') }}</a>
+- </router-link>
+- <li class="nav-item dropdown">
+- <a
+- v-once
+- class="nav-link dropdown-toggle"
+- >{{ $t('learnMore') }}</a>
+- <div class="dropdown-menu">
+- <router-link
+- class="dropdown-item"
+- to="/static/faq"
+- >
+- {{ $t('faq') }}
+- </router-link>
+- <router-link
+- class="dropdown-item"
+- to="/static/plans"
+- >
+- {{ $t('groupPlans') }}
+- </router-link>
+- </div>
+- </li>
+- </ul>
+ <button
+ v-if="$route.name !== 'home'"
+ class="btn btn-primary pull-right"
+@@ -180,66 +128,10 @@
}
}
@@ -111,34 +170,50 @@ index fefaa20896..7a865e176a 100644
}
</style>
-diff --git a/website/client/router/index.js b/website/client/router/index.js
-index 246d9214f0..6f072043d8 100644
---- a/website/client/router/index.js
-+++ b/website/client/router/index.js
-@@ -12,11 +12,8 @@ const AppPage = () => import(/* webpackChunkName: "static" */'client/components/
- const ClearBrowserDataPage = () => import(/* webpackChunkName: "static" */'client/components/static/clearBrowserData');
- const FAQPage = () => import(/* webpackChunkName: "static" */'client/components/static/faq');
- const FeaturesPage = () => import(/* webpackChunkName: "static" */'client/components/static/features');
--const GroupPlansPage = () => import(/* webpackChunkName: "static" */'client/components/static/groupPlans');
--const MerchPage = () => import(/* webpackChunkName: "static" */'client/components/static/merch');
- const NewsPage = () => import(/* webpackChunkName: "static" */'client/components/static/newStuff');
- const OverviewPage = () => import(/* webpackChunkName: "static" */'client/components/static/overview');
--const PressKitPage = () => import(/* webpackChunkName: "static" */'client/components/static/pressKit');
- const PrivacyPage = () => import(/* webpackChunkName: "static" */'client/components/static/privacy');
- const TermsPage = () => import(/* webpackChunkName: "static" */'client/components/static/terms');
+diff --git a/website/client/src/router/index.js b/website/client/src/router/index.js
+index 0067b19f6e..93a2fb0df1 100644
+--- a/website/client/src/router/index.js
++++ b/website/client/src/router/index.js
+@@ -12,11 +12,8 @@ const AppPage = () => import(/* webpackChunkName: "static" */'@/components/stati
+ const ClearBrowserDataPage = () => import(/* webpackChunkName: "static" */'@/components/static/clearBrowserData');
+ const FAQPage = () => import(/* webpackChunkName: "static" */'@/components/static/faq');
+ const FeaturesPage = () => import(/* webpackChunkName: "static" */'@/components/static/features');
+-const GroupPlansPage = () => import(/* webpackChunkName: "static" */'@/components/static/groupPlans');
+-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 TermsPage = () => import(/* webpackChunkName: "static" */'@/components/static/terms');
-@@ -252,14 +249,10 @@ const router = new VueRouter({
- { name: 'clearBrowserData', path: 'clear-browser-data', component: ClearBrowserDataPage, meta: {requiresLogin: false}},
- { name: 'faq', path: 'faq', component: FAQPage, 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: 'merch', path: 'merch', component: MerchPage, 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} },
+@@ -267,30 +264,18 @@ const router = new VueRouter({
+ {
+ 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: 'merch', path: 'merch', component: MerchPage, 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 },
+ },
diff --git a/pkgs/shabitica/patches/remove-session-secret-from-config.patch b/pkgs/shabitica/patches/remove-session-secret-from-config.patch
index 216bab7..fe0c7c4 100644
--- a/pkgs/shabitica/patches/remove-session-secret-from-config.patch
+++ b/pkgs/shabitica/patches/remove-session-secret-from-config.patch
@@ -10,10 +10,10 @@ Date: Fri Mar 30 04:35:48 2018 +0200
Filename: remove-session-secret-from-config.patch
diff --git a/config.json.example b/config.json.example
-index 9fdd842b62..324e871af2 100644
+index 30cd9504fb..8bef015240 100644
--- a/config.json.example
+++ b/config.json.example
-@@ -13,9 +13,6 @@
+@@ -14,9 +14,6 @@
"NODE_ENV": "development",
"PATH": "bin:node_modules/.bin:/usr/local/bin:/usr/bin:/bin",
"PORT": 3000,
diff --git a/pkgs/shabitica/patches/remove-spritely.patch b/pkgs/shabitica/patches/remove-spritely.patch
index 86bf311..6d03e87 100644
--- a/pkgs/shabitica/patches/remove-spritely.patch
+++ b/pkgs/shabitica/patches/remove-spritely.patch
@@ -12,13 +12,13 @@ Date: Fri Jun 29 23:09:04 2018 +0200
Signed-off-by: aszlig <aszlig@nix.build>
Filename: remove-spritely.patch
-diff --git a/website/client/components/settings/api.vue b/website/client/components/settings/api.vue
-index ccacd0f280..c4ef9acf95 100644
---- a/website/client/components/settings/api.vue
-+++ b/website/client/components/settings/api.vue
-@@ -65,12 +65,6 @@ export default {
- showApiToken: false,
- };
+diff --git a/website/client/src/components/settings/api.vue b/website/client/src/components/settings/api.vue
+index 38c091e194..f32588ef1b 100644
+--- a/website/client/src/components/settings/api.vue
++++ b/website/client/src/components/settings/api.vue
+@@ -125,22 +125,7 @@ export default {
+ return this.credentials.API_TOKEN;
+ },
},
- mounted () {
- window.addEventListener('message', this.receiveMessage, false);
@@ -26,12 +26,6 @@ index ccacd0f280..c4ef9acf95 100644
- destroy () {
- window.removeEventListener('message', this.receiveMessage);
- },
- computed: {
- ...mapState({user: 'user.data', credentials: 'credentials'}),
- apiToken () {
-@@ -78,15 +72,6 @@ export default {
- },
- },
methods: {
- receiveMessage (eventFrom) {
- if (eventFrom.origin !== 'https://www.spritely.app') return;
@@ -43,5 +37,5 @@ index ccacd0f280..c4ef9acf95 100644
- eventFrom.source.postMessage(creds, eventFrom.origin);
- },
async addWebhook (url) {
- let webhookInfo = {
+ const webhookInfo = {
id: uuid(),
diff --git a/pkgs/shabitica/patches/remove-ssl-redirect-skip.patch b/pkgs/shabitica/patches/remove-ssl-redirect-skip.patch
index b7fbf50..7290459 100644
--- a/pkgs/shabitica/patches/remove-ssl-redirect-skip.patch
+++ b/pkgs/shabitica/patches/remove-ssl-redirect-skip.patch
@@ -11,10 +11,10 @@ Date: Wed Jan 30 04:54:38 2019 +0100
Filename: remove-ssl-redirect-skip.patch
diff --git a/config.json.example b/config.json.example
-index 00287d0621..a57e372c97 100644
+index 09f25c71d8..a80604b40c 100644
--- a/config.json.example
+++ b/config.json.example
-@@ -15,7 +15,5 @@
+@@ -16,7 +16,5 @@
"PATH": "bin:node_modules/.bin:/usr/local/bin:/usr/bin:/bin",
"PORT": 3000,
"TEST_DB_URI": "mongodb://localhost/habitrpg_test",
@@ -24,16 +24,16 @@ index 00287d0621..a57e372c97 100644
+ "WEB_CONCURRENCY": 1
}
diff --git a/test/api/unit/middlewares/redirects.js b/test/api/unit/middlewares/redirects.js
-index fdbff0d879..d93ed5345c 100644
+index 2399717437..440c4581e4 100644
--- a/test/api/unit/middlewares/redirects.js
+++ b/test/api/unit/middlewares/redirects.js
-@@ -73,56 +73,6 @@ describe('redirects middleware', () => {
+@@ -74,56 +74,6 @@ describe('redirects middleware', () => {
expect(res.redirect).to.have.not.been.called;
});
-
- it('does not redirect if passed skip ssl request param is passed with corrrect key', () => {
-- let nconfStub = sandbox.stub(nconf, 'get');
+- const nconfStub = sandbox.stub(nconf, 'get');
- nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
- nconfStub.withArgs('IS_PROD').returns(true);
- nconfStub.withArgs('SKIP_SSL_CHECK_KEY').returns('test-key');
@@ -49,7 +49,7 @@ index fdbff0d879..d93ed5345c 100644
- });
-
- it('does redirect if skip ssl request param is passed with incorrrect key', () => {
-- let nconfStub = sandbox.stub(nconf, 'get');
+- const nconfStub = sandbox.stub(nconf, 'get');
- nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
- nconfStub.withArgs('IS_PROD').returns(true);
- nconfStub.withArgs('SKIP_SSL_CHECK_KEY').returns('test-key');
@@ -66,7 +66,7 @@ index fdbff0d879..d93ed5345c 100644
- });
-
- it('does redirect if skip ssl check key is not set', () => {
-- let nconfStub = sandbox.stub(nconf, 'get');
+- const nconfStub = sandbox.stub(nconf, 'get');
- nconfStub.withArgs('BASE_URL').returns('https://habitica.com');
- nconfStub.withArgs('IS_PROD').returns(true);
- nconfStub.withArgs('SKIP_SSL_CHECK_KEY').returns(null);
@@ -85,7 +85,7 @@ index fdbff0d879..d93ed5345c 100644
context('forceHabitica', () => {
diff --git a/website/server/middlewares/redirects.js b/website/server/middlewares/redirects.js
-index 587474378e..a7c2a2a56c 100644
+index fd10d53d82..4053b61006 100644
--- a/website/server/middlewares/redirects.js
+++ b/website/server/middlewares/redirects.js
@@ -4,9 +4,6 @@ import url from 'url';
@@ -98,12 +98,15 @@ index 587474378e..a7c2a2a56c 100644
const BASE_URL_HOST = url.parse(BASE_URL).hostname;
-@@ -20,8 +17,7 @@ function isHTTP (req) {
+@@ -20,11 +17,7 @@ function isHTTP (req) {
}
export function forceSSL (req, res, next) {
-- const skipSSLCheck = req.query.skipSSLCheck;
-- if (isHTTP(req) && (!SKIP_SSL_CHECK_KEY || !skipSSLCheck || skipSSLCheck !== SKIP_SSL_CHECK_KEY)) {
+- const { skipSSLCheck } = req.query;
+- if (
+- isHTTP(req)
+- && (!SKIP_SSL_CHECK_KEY || !skipSSLCheck || skipSSLCheck !== SKIP_SSL_CHECK_KEY)
+- ) {
+ if (isHTTP(req)) {
return res.redirect(BASE_URL + req.originalUrl);
}
diff --git a/pkgs/shabitica/patches/remove-static-middleware.patch b/pkgs/shabitica/patches/remove-static-middleware.patch
index 890c240..d1ab2c2 100644
--- a/pkgs/shabitica/patches/remove-static-middleware.patch
+++ b/pkgs/shabitica/patches/remove-static-middleware.patch
@@ -11,18 +11,18 @@ Date: Wed Mar 28 08:26:40 2018 +0200
Filename: remove-static-middleware.patch
diff --git a/website/server/middlewares/index.js b/website/server/middlewares/index.js
-index 1c5894e469..745ac8f7cb 100644
+index 580cf3a73b..26542a05e7 100644
--- a/website/server/middlewares/index.js
+++ b/website/server/middlewares/index.js
-@@ -6,7 +6,6 @@ import nconf from 'nconf';
- import morgan from 'morgan';
- import cookieSession from 'cookie-session';
+@@ -12,7 +12,6 @@ import helmet from 'helmet';
+ import errorHandler from './errorHandler';
+ import notFoundHandler from './notFound';
import cors from './cors';
-import staticMiddleware from './static';
import domainMiddleware from './domain';
- import mongoose from 'mongoose';
- import compression from 'compression';
-@@ -98,7 +97,6 @@ module.exports = function attachMiddlewares (app, server) {
+ // import favicon from 'serve-favicon';
+ // import path from 'path';
+@@ -98,7 +97,6 @@ export default function attachMiddlewares (app, server) {
app.use('/api/v2', v2);
app.use('/api/v1', v1);
app.use(appRoutes); // the main app, also setup top-level routes
diff --git a/pkgs/shabitica/patches/remove-unneeded-settings.patch b/pkgs/shabitica/patches/remove-unneeded-settings.patch
index 433ad1b..39eadac 100644
--- a/pkgs/shabitica/patches/remove-unneeded-settings.patch
+++ b/pkgs/shabitica/patches/remove-unneeded-settings.patch
@@ -8,53 +8,83 @@ Date: Sat Apr 7 01:42:11 2018 +0200
Signed-off-by: aszlig <aszlig@nix.build>
Filename: remove-unneeded-settings.patch
-diff --git a/website/client/components/header/userDropdown.vue b/website/client/components/header/userDropdown.vue
-index 72019f8ddf..62fd87f3b8 100644
---- a/website/client/components/header/userDropdown.vue
-+++ b/website/client/components/header/userDropdown.vue
-@@ -16,14 +16,7 @@ menu-dropdown.item-user(:right="true")
- a.dropdown-item(@click='showProfile("achievements")') {{ $t('achievements') }}
- a.dropdown-item.dropdown-separated(@click='showProfile("profile")') {{ $t('profile') }}
- router-link.dropdown-item(:to="{name: 'site'}") {{ $t('settings') }}
-- router-link.dropdown-item.dropdown-separated(:to="{name: 'subscription'}") {{ $t('subscription') }}
- a.nav-link.dropdown-item.dropdown-separated(@click.prevent='logout()') {{ $t('logout') }}
-- li(v-if='!this.user.purchased.plan.customerId', @click='showBuyGemsModal("subscribe")')
-- .dropdown-item.text-center
-- h3.purple {{ $t('needMoreGems') }}
-- span.small-text {{ $t('needMoreGemsInfo') }}
-- .learn-background.py-2.text-center
-- button.btn.btn-primary.btn-lg.learn-button {{ $t('learnMore') }}
+diff --git a/website/client/src/components/header/userDropdown.vue b/website/client/src/components/header/userDropdown.vue
+index c1ab280fec..fe35343854 100644
+--- a/website/client/src/components/header/userDropdown.vue
++++ b/website/client/src/components/header/userDropdown.vue
+@@ -63,32 +63,10 @@
+ >
+ {{ $t('settings') }}
+ </router-link>
+- <router-link
+- class="dropdown-item dropdown-separated"
+- :to="{name: 'subscription'}"
+- >
+- {{ $t('subscription') }}
+- </router-link>
+ <a
+ class="nav-link dropdown-item dropdown-separated"
+ @click.prevent="logout()"
+ >{{ $t('logout') }}</a>
+- <li
+- v-if="!user.purchased.plan.customerId"
+- @click="showBuyGemsModal('subscribe')"
+- >
+- <div class="dropdown-item text-center">
+- <h3 class="purple">
+- {{ $t('needMoreGems') }}
+- </h3>
+- <span class="small-text">{{ $t('needMoreGemsInfo') }}</span>
+- </div>
+- <div class="learn-background py-2 text-center">
+- <button class="btn btn-primary btn-lg learn-button">
+- {{ $t('learnMore') }}
+- </button>
+- </div>
+- </li>
+ </div>
+ </menu-dropdown>
</template>
-
- <style lang='scss' scoped>
-diff --git a/website/client/components/settings/index.vue b/website/client/components/settings/index.vue
-index 68366e1107..9f8b08f3f5 100644
---- a/website/client/components/settings/index.vue
-+++ b/website/client/components/settings/index.vue
-@@ -4,8 +4,6 @@
- router-link.nav-link(:to="{name: 'site'}", exact, :class="{'active': $route.name === 'site'}") {{ $t('site') }}
- router-link.nav-link(:to="{name: 'api'}", :class="{'active': $route.name === 'api'}") {{ $t('API') }}
- router-link.nav-link(:to="{name: 'dataExport'}", :class="{'active': $route.name === 'dataExport'}") {{ $t('dataExport') }}
-- router-link.nav-link(:to="{name: 'promoCode'}", :class="{'active': $route.name === 'promoCode'}") {{ $t('promoCode') }}
-- router-link.nav-link(:to="{name: 'subscription'}", :class="{'active': $route.name === 'subscription'}") {{ $t('subscription') }}
- router-link.nav-link(:to="{name: 'notifications'}", :class="{'active': $route.name === 'notifications'}") {{ $t('notifications') }}
-
- .col-12
-diff --git a/website/client/router/index.js b/website/client/router/index.js
-index 6f072043d8..983ff4e296 100644
---- a/website/client/router/index.js
-+++ b/website/client/router/index.js
-@@ -30,9 +30,7 @@ const Settings = () => import(/* webpackChunkName: "settings" */'client/componen
- const API = () => import(/* webpackChunkName: "settings" */'client/components/settings/api');
- const DataExport = () => import(/* webpackChunkName: "settings" */'client/components/settings/dataExport');
- const Notifications = () => import(/* webpackChunkName: "settings" */'client/components/settings/notifications');
--const PromoCode = () => import(/* webpackChunkName: "settings" */'client/components/settings/promoCode');
- const Site = () => import(/* webpackChunkName: "settings" */'client/components/settings/site');
--const Subscription = () => import(/* webpackChunkName: "settings" */'client/components/settings/subscription');
+diff --git a/website/client/src/components/settings/index.vue b/website/client/src/components/settings/index.vue
+index 61e6f4bee7..872453694a 100644
+--- a/website/client/src/components/settings/index.vue
++++ b/website/client/src/components/settings/index.vue
+@@ -23,20 +23,6 @@
+ >
+ {{ $t('dataExport') }}
+ </router-link>
+- <router-link
+- class="nav-link"
+- :to="{name: 'promoCode'}"
+- :class="{'active': $route.name === 'promoCode'}"
+- >
+- {{ $t('promoCode') }}
+- </router-link>
+- <router-link
+- class="nav-link"
+- :to="{name: 'subscription'}"
+- :class="{'active': $route.name === 'subscription'}"
+- >
+- {{ $t('subscription') }}
+- </router-link>
+ <router-link
+ class="nav-link"
+ :to="{name: 'notifications'}"
+diff --git a/website/client/src/router/index.js b/website/client/src/router/index.js
+index 93a2fb0df1..a45639ad32 100644
+--- a/website/client/src/router/index.js
++++ b/website/client/src/router/index.js
+@@ -31,9 +31,7 @@ const Settings = () => import(/* webpackChunkName: "settings" */'@/components/se
+ 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');
// Hall
- const HallPage = () => import(/* webpackChunkName: "hall" */'client/components/hall/index');
-@@ -222,16 +220,6 @@ const router = new VueRouter({
+ const HallPage = () => import(/* webpackChunkName: "hall" */'@/components/hall/index');
+@@ -229,16 +227,6 @@ const router = new VueRouter({
path: 'data-export',
component: DataExport,
},
diff --git a/pkgs/shabitica/patches/remove-welcome-abtest.patch b/pkgs/shabitica/patches/remove-welcome-abtest.patch
index b1644c7..2bde82c 100644
--- a/pkgs/shabitica/patches/remove-welcome-abtest.patch
+++ b/pkgs/shabitica/patches/remove-welcome-abtest.patch
@@ -15,12 +15,12 @@ Date: Wed Feb 27 21:55:38 2019 +0100
Filename: remove-welcome-abtest.patch
diff --git a/website/server/libs/auth/index.js b/website/server/libs/auth/index.js
-index bf459d5e63..5dc9fc83b6 100644
+index 7eff5c8e87..c254177b1d 100644
--- a/website/server/libs/auth/index.js
+++ b/website/server/libs/auth/index.js
-@@ -175,12 +175,7 @@ async function registerLocal (req, res, { isV3 = false }) {
+@@ -184,12 +184,7 @@ async function registerLocal (req, res, { isV3 = false }) {
EmailUnsubscription
- .remove({email: savedUser.auth.local.email})
+ .remove({ email: savedUser.auth.local.email })
.then(() => {
- if (existingUser) return;
- if (newUser.registeredThrough === 'habitica-web') {
diff --git a/pkgs/shabitica/patches/server-client-path.patch b/pkgs/shabitica/patches/server-client-path.patch
index af5aee5..db2904a 100644
--- a/pkgs/shabitica/patches/server-client-path.patch
+++ b/pkgs/shabitica/patches/server-client-path.patch
@@ -12,14 +12,13 @@ Date: Wed Mar 28 08:39:05 2018 +0200
Filename: server-client-path.patch
diff --git a/website/server/libs/client.js b/website/server/libs/client.js
-index 12aa476c95..5acd5d2db9 100644
+index 525003bac5..c48b570174 100644
--- a/website/server/libs/client.js
+++ b/website/server/libs/client.js
@@ -1,5 +1,3 @@
-const ROOT = `${__dirname}/../../../`;
-
- export function serveClient (expressRes) {
-- return expressRes.sendFile('./dist-client/index.html', {root: ROOT});
+ export function serveClient (expressRes) { // eslint-disable-line import/prefer-default-export
+- return expressRes.sendFile('./website/client/dist/index.html', { root: ROOT });
+ return expressRes.send('@CLIENT_INDEX_DATA@');
}
-\ No newline at end of file
diff --git a/pkgs/shabitica/patches/socket-activation.patch b/pkgs/shabitica/patches/socket-activation.patch
index 42be73b..3984338 100644
--- a/pkgs/shabitica/patches/socket-activation.patch
+++ b/pkgs/shabitica/patches/socket-activation.patch
@@ -10,30 +10,30 @@ Date: Tue Mar 27 05:37:06 2018 +0200
Filename: socket-activation.patch
diff --git a/package.json b/package.json
-index ce88b86a20..01c208c60b 100644
+index beb83c7d32..5b86e60282 100644
--- a/package.json
+++ b/package.json
-@@ -76,6 +76,7 @@
- "svg-url-loader": "^3.0.0",
- "svgo": "^1.2.0",
- "svgo-loader": "^2.1.0",
+@@ -48,6 +48,7 @@
+ "regenerator-runtime": "^0.13.3",
+ "rimraf": "^3.0.0",
+ "superagent": "^5.0.2",
+ "systemd-socket": "^0.0.0",
- "update": "^0.7.4",
- "upgrade": "^1.1.0",
- "url-loader": "^1.0.0",
+ "useragent": "^2.1.9",
+ "uuid": "^3.3.3",
+ "validator": "^11.0.0",
diff --git a/website/server/server.js b/website/server/server.js
-index 6f717f7116..d704cdb1a1 100644
+index c952da4b04..1cde5120e9 100644
--- a/website/server/server.js
+++ b/website/server/server.js
@@ -2,6 +2,7 @@ import nconf from 'nconf';
- import logger from './libs/logger';
import express from 'express';
import http from 'http';
+ import logger from './libs/logger';
+import systemdSocket from 'systemd-socket';
- const server = http.createServer();
- const app = express();
-@@ -26,7 +27,7 @@ import './models/user';
+ // Setup translations
+ // Must come before attach middlewares so Mongoose validations can use translations
+@@ -26,7 +27,7 @@ app.set('port', nconf.get('PORT'));
attachMiddlewares(app, server);
server.on('request', app);
diff --git a/pkgs/shabitica/patches/strip-dependencies.patch b/pkgs/shabitica/patches/strip-dependencies.patch
index affb400..ea75240 100644
--- a/pkgs/shabitica/patches/strip-dependencies.patch
+++ b/pkgs/shabitica/patches/strip-dependencies.patch
@@ -10,45 +10,37 @@ Date: Tue Mar 27 05:37:02 2018 +0200
Filename: strip-dependencies.patch
diff --git a/package.json b/package.json
-index 239d0787c2..ce88b86a20 100644
+index 226c745932..beb83c7d32 100644
--- a/package.json
+++ b/package.json
-@@ -4,16 +4,9 @@
- "version": "4.116.4",
- "main": "./website/server/index.js",
- "dependencies": {
-- "@google-cloud/trace-agent": "^4.0.0",
+@@ -7,14 +7,8 @@
+ "@babel/core": "^7.6.4",
+ "@babel/preset-env": "^7.6.3",
+ "@babel/register": "^7.6.2",
+- "@google-cloud/trace-agent": "^4.2.2",
- "@slack/client": "^3.8.1",
"accepts": "^1.3.5",
- "amazon-payments": "^0.2.7",
- "amplitude": "^3.5.0",
-- "amplitude-js": "^5.2.2",
"apidoc": "^0.17.5",
- "apn": "^2.2.0",
- "autoprefixer": "^9.4.0",
-- "aws-sdk": "^2.432.0",
- "axios": "^0.19.0",
- "axios-progress-bar": "^1.2.0",
- "babel-core": "^6.26.3",
-@@ -52,11 +45,9 @@
- "gulp-nodemon": "^2.4.1",
- "gulp.spritesmith": "^6.9.0",
+- "aws-sdk": "^2.556.0",
+ "bcrypt": "^3.0.6",
+ "body-parser": "^1.18.3",
+ "compression": "^1.7.4",
+@@ -39,7 +33,6 @@
"habitica-markdown": "^1.3.0",
-- "hellojs": "^1.18.1",
- "helmet": "^3.21.0",
- "html-webpack-plugin": "^3.2.0",
- "image-size": "^0.8.0",
+ "helmet": "^3.21.2",
+ "image-size": "^0.8.3",
- "in-app-purchase": "^1.11.3",
- "intro.js": "^2.9.3",
- "jquery": ">=3.0.0",
"js2xmlparser": "^4.0.0",
-@@ -68,16 +59,10 @@
- "mongoose": "^5.6.9",
+ "lodash": "^4.17.15",
+ "merge-stream": "^2.0.0",
+@@ -49,27 +42,17 @@
+ "mongoose": "^5.7.7",
"morgan": "^1.7.0",
"nconf": "^0.10.0",
- "node-gcm": "^1.0.2",
- "node-sass": "^4.12.0",
- "ora": "^3.2.0",
"pageres": "^5.1.0",
"passport": "^0.4.0",
- "passport-facebook": "^3.0.0",
@@ -56,30 +48,47 @@ index 239d0787c2..ce88b86a20 100644
- "passport-google-oauth20": "1.0.0",
- "paypal-ipn": "3.0.0",
- "paypal-rest-sdk": "^1.8.1",
- "popper.js": "^1.14.3",
- "postcss-easy-import": "^3.0.0",
"ps-tree": "^1.0.0",
-@@ -86,15 +71,11 @@
- "rimraf": "^2.4.3",
- "sass-loader": "^7.0.3",
- "shelljs": "^0.8.2",
+ "regenerator-runtime": "^0.13.3",
+ "rimraf": "^3.0.0",
- "short-uuid": "^3.0.0",
-- "smartbanner.js": "^1.11.0",
-- "stripe": "^7.9.0",
+- "stripe": "^7.10.0",
"superagent": "^5.0.2",
- "svg-inline-loader": "^0.8.0",
- "svg-url-loader": "^3.0.0",
- "svgo": "^1.2.0",
- "svgo-loader": "^2.1.0",
- "universal-analytics": "^0.4.17",
- "update": "^0.7.4",
- "upgrade": "^1.1.0",
- "url-loader": "^1.0.0",
-@@ -113,7 +94,6 @@
- "webpack": "^3.12.0",
- "webpack-merge": "^4.1.3",
+ "useragent": "^2.1.9",
+ "uuid": "^3.3.3",
+ "validator": "^11.0.0",
+ "vinyl-buffer": "^1.0.1",
"winston": "^2.4.3",
- "winston-loggly-bulk": "^2.0.2",
"xml2js": "^0.4.4"
},
"private": true,
+diff --git a/website/client/package.json b/website/client/package.json
+index 3e52d9a989..bfa65805e4 100644
+--- a/website/client/package.json
++++ b/website/client/package.json
+@@ -16,7 +16,6 @@
+ "@vue/cli-plugin-unit-mocha": "^4.0.5",
+ "@vue/cli-service": "^4.0.5",
+ "@vue/test-utils": "1.0.0-beta.29",
+- "amplitude-js": "^5.6.0",
+ "axios": "^0.19.0",
+ "axios-progress-bar": "^1.2.0",
+ "babel-eslint": "^10.0.1",
+@@ -29,7 +28,6 @@
+ "eslint-plugin-mocha": "^5.3.0",
+ "eslint-plugin-vue": "^5.0.0",
+ "habitica-markdown": "^1.3.0",
+- "hellojs": "^1.18.1",
+ "inspectpack": "^4.2.2",
+ "intro.js": "^2.9.3",
+ "jquery": "^3.4.1",
+@@ -38,7 +36,6 @@
+ "nconf": "^0.10.0",
+ "sass": "^1.23.1",
+ "sass-loader": "^8.0.0",
+- "smartbanner.js": "^1.14.5",
+ "svg-inline-loader": "^0.8.0",
+ "svg-url-loader": "^3.0.2",
+ "svgo": "^1.3.0",
diff --git a/pkgs/shabitica/patches/subscriptions4all.patch b/pkgs/shabitica/patches/subscriptions4all.patch
index 2b8916d..3dd466b 100644
--- a/pkgs/shabitica/patches/subscriptions4all.patch
+++ b/pkgs/shabitica/patches/subscriptions4all.patch
@@ -14,10 +14,10 @@ Date: Tue Mar 27 05:37:09 2018 +0200
Filename: subscriptions4all.patch
diff --git a/test/api/unit/libs/payments/payments.test.js b/test/api/unit/libs/payments/payments.test.js
-index d33a0095cf..0b0fb3f42b 100644
+index b9144665bb..bcaf1898a4 100644
--- a/test/api/unit/libs/payments/payments.test.js
+++ b/test/api/unit/libs/payments/payments.test.js
-@@ -439,83 +439,6 @@ describe('payments/index', () => {
+@@ -443,83 +443,6 @@ describe('payments/index', () => {
});
});
@@ -30,8 +30,8 @@ index d33a0095cf..0b0fb3f42b 100644
- it('adds a month termination date by default', async () => {
- await api.cancelSubscription(data);
-
-- let now = new Date();
-- let daysTillTermination = moment(user.purchased.plan.dateTerminated).diff(now, 'days');
+- const now = new Date();
+- const daysTillTermination = moment(user.purchased.plan.dateTerminated).diff(now, 'days');
-
- expect(daysTillTermination).to.be.within(29, 30); // 1 month +/- 1 days
- });
@@ -41,8 +41,8 @@ index d33a0095cf..0b0fb3f42b 100644
-
- await api.cancelSubscription(data);
-
-- let now = new Date();
-- let daysTillTermination = moment(user.purchased.plan.dateTerminated).diff(now, 'days');
+- const now = new Date();
+- const daysTillTermination = moment(user.purchased.plan.dateTerminated).diff(now, 'days');
-
- expect(daysTillTermination).to.be.within(89, 90); // 3 months +/- 1 days
- });
@@ -52,8 +52,8 @@ index d33a0095cf..0b0fb3f42b 100644
-
- await api.cancelSubscription(data);
-
-- let now = new Date();
-- let daysTillTermination = moment(user.purchased.plan.dateTerminated).diff(now, 'days');
+- const now = new Date();
+- const daysTillTermination = moment(user.purchased.plan.dateTerminated).diff(now, 'days');
-
- expect(daysTillTermination).to.be.within(38, 39); // should be about 1 month + 1/3 month
- });
@@ -63,8 +63,8 @@ index d33a0095cf..0b0fb3f42b 100644
-
- await api.cancelSubscription(data);
-
-- let now = new Date();
-- let daysTillTermination = moment(user.purchased.plan.dateTerminated).diff(now, 'days');
+- const now = new Date();
+- const daysTillTermination = moment(user.purchased.plan.dateTerminated).diff(now, 'days');
-
- expect(daysTillTermination).to.be.within(13, 15);
- });
@@ -75,8 +75,8 @@ index d33a0095cf..0b0fb3f42b 100644
-
- await api.cancelSubscription(data);
-
-- let now = new Date();
-- let daysTillTermination = moment(user.purchased.plan.dateTerminated).diff(now, 'days');
+- const now = new Date();
+- const daysTillTermination = moment(user.purchased.plan.dateTerminated).diff(now, 'days');
-
- expect(daysTillTermination).to.be.within(13, 15);
- });
@@ -102,10 +102,10 @@ index d33a0095cf..0b0fb3f42b 100644
beforeEach(() => {
data = {
diff --git a/test/api/unit/models/user.test.js b/test/api/unit/models/user.test.js
-index 24652fa7b6..1e82b58f97 100644
+index 1e01c52b16..f8eedfc1c8 100644
--- a/test/api/unit/models/user.test.js
+++ b/test/api/unit/models/user.test.js
-@@ -299,13 +299,13 @@ describe('User Model', () => {
+@@ -300,13 +300,13 @@ describe('User Model', () => {
expect(await user.canGetGems()).to.equal(true);
});
@@ -122,19 +122,19 @@ index 24652fa7b6..1e82b58f97 100644
});
diff --git a/test/api/v3/integration/challenges/POST-challenges_challengeId_winner_winnerId.test.js b/test/api/v3/integration/challenges/POST-challenges_challengeId_winner_winnerId.test.js
-index 41c655b88c..76dd856514 100644
+index 3f3b75e7fe..28df002352 100644
--- a/test/api/v3/integration/challenges/POST-challenges_challengeId_winner_winnerId.test.js
+++ b/test/api/v3/integration/challenges/POST-challenges_challengeId_winner_winnerId.test.js
-@@ -115,7 +115,7 @@ describe('POST /challenges/:challengeId/winner/:winnerId', () => {
+@@ -116,7 +116,7 @@ describe('POST /challenges/:challengeId/winner/:winnerId', () => {
await expect(winningUser.sync()).to.eventually.have.property('balance', oldBalance + challenge.prize / 4);
});
- it('doesn\'t gives winner gems if group policy prevents it', async () => {
+ it('gives winner gems even if group policy prevents it', async () => {
- let oldBalance = winningUser.balance;
- let oldLeaderBalance = (await groupLeader.sync()).balance;
+ const oldBalance = winningUser.balance;
+ const oldLeaderBalance = (await groupLeader.sync()).balance;
-@@ -131,8 +131,8 @@ describe('POST /challenges/:challengeId/winner/:winnerId', () => {
+@@ -132,8 +132,8 @@ describe('POST /challenges/:challengeId/winner/:winnerId', () => {
await sleep(0.5);
@@ -146,7 +146,7 @@ index 41c655b88c..76dd856514 100644
it('doesn\'t refund gems to group leader', async () => {
diff --git a/test/api/v3/integration/user/DELETE-user.test.js b/test/api/v3/integration/user/DELETE-user.test.js
-index 1e70c3486e..1694349e53 100644
+index a7b75bfb1f..68eb7e8972 100644
--- a/test/api/v3/integration/user/DELETE-user.test.js
+++ b/test/api/v3/integration/user/DELETE-user.test.js
@@ -70,16 +70,13 @@ describe('DELETE /user', () => {
@@ -155,7 +155,7 @@ index 1e70c3486e..1694349e53 100644
- it('returns an error if user has active subscription', async () => {
+ it('returns no error if user has active subscription', async () => {
- let userWithSubscription = await generateUser({'purchased.plan.customerId': 'fake-customer-id'});
+ const userWithSubscription = await generateUser({ 'purchased.plan.customerId': 'fake-customer-id' });
- await expect(userWithSubscription.del('/user', {
+ await userWithSubscription.del('/user', {
@@ -170,7 +170,7 @@ index 1e70c3486e..1694349e53 100644
it('deletes the user\'s tasks', async () => {
diff --git a/test/api/v3/integration/user/POST-user_purchase.test.js b/test/api/v3/integration/user/POST-user_purchase.test.js
-index b1d3749256..9160226c5d 100644
+index 502bcb3790..9b4825d1d1 100644
--- a/test/api/v3/integration/user/POST-user_purchase.test.js
+++ b/test/api/v3/integration/user/POST-user_purchase.test.js
@@ -1,7 +1,6 @@
@@ -203,7 +203,7 @@ index b1d3749256..9160226c5d 100644
- it('cannot convert gold to gems if the group plan prevents it', async () => {
+ it('can convert gold to gems even if the group plan prevents it', async () => {
- let { group, members } = await createAndPopulateGroup({
+ const { group, members } = await createAndPopulateGroup({
groupDetails: {
name: 'test',
@@ -88,15 +78,10 @@ describe('POST /user/purchase/:type/:key', () => {
@@ -225,10 +225,10 @@ index b1d3749256..9160226c5d 100644
describe('bulk purchasing', () => {
diff --git a/website/server/libs/auth/index.js b/website/server/libs/auth/index.js
-index 0ec22f525c..97867e40b5 100644
+index b6424cd766..3dfed682e3 100644
--- a/website/server/libs/auth/index.js
+++ b/website/server/libs/auth/index.js
-@@ -121,6 +121,13 @@ async function registerLocal (req, res, { isV3 = false }) {
+@@ -130,6 +130,13 @@ async function registerLocal (req, res, { isV3 = false }) {
passwordHashMethod: 'bcrypt',
},
},
@@ -243,10 +243,10 @@ index 0ec22f525c..97867e40b5 100644
language: req.language,
},
diff --git a/website/server/libs/payments/groupPayments.js b/website/server/libs/payments/groupPayments.js
-index e3413ed12a..cd6aeb45f4 100644
+index f62518004f..9dcf824eaf 100644
--- a/website/server/libs/payments/groupPayments.js
+++ b/website/server/libs/payments/groupPayments.js
-@@ -10,8 +10,6 @@ import {
+@@ -10,8 +10,6 @@ import { // eslint-disable-line import/no-cycle
sendTxn as txnEmail,
} from '../email';
@@ -255,7 +255,7 @@ index e3413ed12a..cd6aeb45f4 100644
function _dateDiff (earlyDate, lateDate) {
if (!earlyDate || !lateDate || moment(lateDate).isBefore(earlyDate)) return 0;
-@@ -52,7 +50,6 @@ async function addSubToGroupUser (member, group) {
+@@ -50,7 +48,6 @@ async function addSubToGroupUser (member, group) {
// stored externally and so their values must not be changed.
const EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_GROUP_PLAN = 'group_plan_free_subscription';
const EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_LIFETIME_FREE = 'lifetime_free_subscription';
@@ -263,20 +263,20 @@ index e3413ed12a..cd6aeb45f4 100644
const EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_UNKNOWN = 'unknown_type_of_subscription';
const EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NONE = 'no_subscription';
-@@ -115,11 +112,6 @@ async function addSubToGroupUser (member, group) {
+@@ -119,11 +116,6 @@ async function addSubToGroupUser (member, group) {
return;
}
- if (member.hasNotCancelled()) {
-- await member.cancelSubscription({cancellationReason: JOINED_GROUP_PLAN});
+- await member.cancelSubscription({ cancellationReason: JOINED_GROUP_PLAN });
- previousSubscriptionType = EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NORMAL;
- }
-
- let today = new Date();
+ const today = new Date();
plan = member.purchased.plan.toObject();
let extraMonths = Number(plan.extraMonths);
diff --git a/website/server/libs/payments/subscriptions.js b/website/server/libs/payments/subscriptions.js
-index f01602701a..d0f7d9a397 100644
+index 0c87288dc8..5985aaaee4 100644
--- a/website/server/libs/payments/subscriptions.js
+++ b/website/server/libs/payments/subscriptions.js
@@ -15,9 +15,6 @@ import {
@@ -289,7 +289,7 @@ index f01602701a..d0f7d9a397 100644
function revealMysteryItems (user) {
const pushedItems = [];
-@@ -208,12 +205,7 @@ async function cancelSubscription (data) {
+@@ -213,12 +210,7 @@ async function cancelSubscription (data) {
await this.cancelGroupUsersSubscription(group);
} else {
@@ -302,20 +302,20 @@ index f01602701a..d0f7d9a397 100644
+ return;
}
- let now = moment();
+ const now = moment();
diff --git a/website/server/models/user/methods.js b/website/server/models/user/methods.js
-index 14ccb1fee8..1a12c34db8 100644
+index ffcabb0113..b3b27fe157 100644
--- a/website/server/models/user/methods.js
+++ b/website/server/models/user/methods.js
-@@ -15,7 +15,6 @@ import {
- import { defaults, map, flatten, flow, compact, uniq, partialRight } from 'lodash';
+@@ -17,7 +17,6 @@ import {
+
import { model as UserNotification } from '../userNotification';
- import schema from './schema';
--import payments from '../../libs/payments/payments';
- import * as inboxLib from '../../libs/inbox';
+ import schema from './schema'; // eslint-disable-line import/no-cycle
+-import payments from '../../libs/payments/payments'; // eslint-disable-line import/no-cycle
+ import * as inboxLib from '../../libs/inbox'; // eslint-disable-line import/no-cycle
- const daysSince = common.daysSince;
-@@ -235,27 +234,6 @@ schema.statics.addComputedStatsToJSONObj = function addComputedStatsToUserJSONOb
+ const { daysSince } = common;
+@@ -257,31 +256,6 @@ schema.statics.addComputedStatsToJSONObj = function addComputedStatsToUserJSONOb
return userStatsJSON;
};
@@ -330,25 +330,29 @@ index 14ccb1fee8..1a12c34db8 100644
- *
- * @return a Promise from api.cancelSubscription()
- */
--// @TODO: There is currently a three way relation between the user, payment methods and the payment helper
--// This creates some odd Dependency Injection issues. To counter that, we use the user as the third layer
--// To negotiate between the payment providers and the payment helper (which probably has too many responsiblities)
--// In summary, currently is is best practice to use this method to cancel a user subscription, rather than calling the
+-// @TODO: There is currently a three way relation between the user,
+-// payment methods and the payment helper
+-// This creates some odd Dependency Injection issues. To counter that,
+-// we use the user as the third layer
+-// To negotiate between the payment providers and the payment helper
+-// (which probably has too many responsiblities)
+-// In summary, currently is is best practice to use this method to cancel a user subscription,
+-// rather than calling the
-// payment helper.
-schema.methods.cancelSubscription = async function cancelSubscription (options = {}) {
- options.user = this;
-- return await payments.cancelSubscription(options);
+- return payments.cancelSubscription(options);
-};
-
schema.methods.daysUserHasMissed = function daysUserHasMissed (now, req = {}) {
// If the user's timezone has changed (due to travel or daylight savings),
// cron can be triggered twice in one day, so we check for that and use
-@@ -361,18 +339,7 @@ async function getUserGroupData (user) {
+@@ -400,17 +374,7 @@ async function getUserGroupData (user) {
// User is allowed to buy gems if no group has `leaderOnly.getGems` === true or if
// its the group leader
schema.methods.canGetGems = async function canObtainGems () {
- const user = this;
-- const plan = user.purchased.plan;
+- const { plan } = user.purchased;
-
- if (!user.isSubscribed() || plan.customerId !== payments.constants.GROUP_PLAN_CUSTOMER_ID) {
- return true;
@@ -356,9 +360,8 @@ index 14ccb1fee8..1a12c34db8 100644
-
- const groups = await getUserGroupData(user);
-
-- return groups.every(g => {
-- return !g.isSubscribed() || g.leader === user._id || g.leaderOnly.getGems !== true;
-- });
+- return groups
+- .every(g => !g.isSubscribed() || g.leader === user._id || g.leaderOnly.getGems !== true);
+ return true;
};
diff --git a/pkgs/shabitica/patches/systemd-notify.patch b/pkgs/shabitica/patches/systemd-notify.patch
index 1a47320..00be3d2 100644
--- a/pkgs/shabitica/patches/systemd-notify.patch
+++ b/pkgs/shabitica/patches/systemd-notify.patch
@@ -10,29 +10,29 @@ Date: Thu May 3 06:29:02 2018 +0200
Filename: systemd-notify.patch
diff --git a/package.json b/package.json
-index 1d5f379a88..66c75673b7 100644
+index 0251a63798..6a40c4a0b9 100644
--- a/package.json
+++ b/package.json
-@@ -70,6 +70,7 @@
+@@ -47,6 +47,7 @@
+ "ps-tree": "^1.0.0",
"regenerator-runtime": "^0.13.3",
- "rimraf": "^2.4.3",
- "sass-loader": "^7.0.3",
-+ "sd-notify": "^2.3.1",
- "shelljs": "^0.8.2",
+ "rimraf": "^3.0.0",
++ "sd-notify": "^2.7.2",
"superagent": "^5.0.2",
- "svg-inline-loader": "^0.8.0",
+ "systemd-socket": "^0.0.0",
+ "useragent": "^2.1.9",
diff --git a/website/server/server.js b/website/server/server.js
-index d704cdb1a1..03dc694f54 100644
+index 1cde5120e9..480c537136 100644
--- a/website/server/server.js
+++ b/website/server/server.js
-@@ -3,6 +3,7 @@ import logger from './libs/logger';
- import express from 'express';
+@@ -3,6 +3,7 @@ import express from 'express';
import http from 'http';
+ import logger from './libs/logger';
import systemdSocket from 'systemd-socket';
+import notify from 'sd-notify';
- const server = http.createServer();
- const app = express();
+ // Setup translations
+ // Must come before attach middlewares so Mongoose validations can use translations
@@ -29,6 +30,7 @@ attachMiddlewares(app, server);
server.on('request', app);
server.listen(systemdSocket() || app.get('port'), () => {
@@ -40,4 +40,4 @@ index d704cdb1a1..03dc694f54 100644
+ notify.ready();
});
- module.exports = server;
+ export default server;
diff --git a/pkgs/shabitica/patches/tavern-remove-staff-and-tiers.patch b/pkgs/shabitica/patches/tavern-remove-staff-and-tiers.patch
index 5970a10..885672d 100644
--- a/pkgs/shabitica/patches/tavern-remove-staff-and-tiers.patch
+++ b/pkgs/shabitica/patches/tavern-remove-staff-and-tiers.patch
@@ -9,71 +9,178 @@ Date: Sat Mar 31 01:16:24 2018 +0200
Signed-off-by: aszlig <aszlig@nix.build>
Filename: tavern-remove-staff-and-tiers.patch
-diff --git a/website/client/components/groups/tavern.vue b/website/client/components/groups/tavern.vue
-index e37284fec1..522a3b4f50 100644
---- a/website/client/components/groups/tavern.vue
-+++ b/website/client/components/groups/tavern.vue
-@@ -87,16 +87,6 @@
- li(v-once) {{ $t('sleepBullet4') }}
- button.btn.btn-secondary.pause-button(v-if='!user.preferences.sleep', @click='toggleSleep()', v-once) {{ $t('pauseDailies') }}
- button.btn.btn-secondary.pause-button(v-if='user.preferences.sleep', @click='toggleSleep()', v-once) {{ $t('unpauseDailies') }}
-- .px-3
-- sidebar-section(:title="$t('staffAndModerators')")
-- .row
-- .col-4.staff(v-for='user in staff', :class='{staff: user.type === "Staff", moderator: user.type === "Moderator", bailey: user.name === "It\'s Bailey"}')
-- div
-- router-link.title(:to="{'name': 'userProfile', 'params': {'userId': user.uuid}}") {{user.name}}
-- .svg-icon.staff-icon(v-html="icons.tierStaff", v-if='user.type === "Staff"')
-- .svg-icon.mod-icon(v-html="icons.tierMod", v-if='user.type === "Moderator" && user.name !== "It\'s Bailey"')
-- .svg-icon.npc-icon(v-html="icons.tierNPC", v-if='user.name === "It\'s Bailey"')
-- .type {{user.type}}
-
- sidebar-section(:title="$t('helpfulLinks')")
- ul
-@@ -108,42 +98,6 @@
- a(href='http://habitica.fandom.com/wiki/Habitica_Wiki' target='_blank', v-once) {{ $t('wiki') }}
- li
- a(href='https://oldgods.net/habitrpg/habitrpg_user_data_display.html', target='_blank', v-once) {{ $t('dataDisplayTool') }}
--
-- sidebar-section(:title="$t('playerTiers')")
-- .row
-- .col-12
-- p(v-once) {{ $t('playerTiersDesc') }}
-- ul.tier-list
-- li.tier1(v-once)
-- | {{ $t('tier1') }}
-- .svg-icon.tier1-icon(v-html="icons.tier1")
-- li.tier2(v-once)
-- | {{ $t('tier2') }}
-- .svg-icon.tier2-icon(v-html="icons.tier2")
-- li.tier3(v-once)
-- | {{ $t('tier3') }}
-- .svg-icon.tier3-icon(v-html="icons.tier3")
-- li.tier4(v-once)
-- | {{ $t('tier4') }}
-- .svg-icon.tier4-icon(v-html="icons.tier4")
-- li.tier5(v-once)
-- | {{ $t('tier5') }}
-- .svg-icon.tier5-icon(v-html="icons.tier5")
-- li.tier6(v-once)
-- | {{ $t('tier6') }}
-- .svg-icon.tier6-icon(v-html="icons.tier6")
-- li.tier7(v-once)
-- | {{ $t('tier7') }}
-- .svg-icon.tier7-icon(v-html="icons.tier7")
-- li.moderator(v-once)
-- | {{ $t('tierModerator') }}
-- .svg-icon.mod-icon(v-html="icons.tierMod")
-- li.staff(v-once)
-- | {{ $t('tierStaff') }}
-- .svg-icon.staff-icon(v-html="icons.tierStaff")
-- li.npc(v-once)
-- | {{ $t('tierNPC') }}
-- .svg-icon.npc-icon(v-html="icons.tierNPC")
- </template>
-
- <style lang='scss' scoped>
-@@ -190,26 +144,6 @@
+diff --git a/website/client/src/components/groups/tavern.vue b/website/client/src/components/groups/tavern.vue
+index c5c7a23014..99453781d4 100644
+--- a/website/client/src/components/groups/tavern.vue
++++ b/website/client/src/components/groups/tavern.vue
+@@ -261,48 +261,6 @@
+ {{ $t('unpauseDailies') }}
+ </button>
+ </div>
+- </div>
+- <div class="px-3">
+- <sidebar-section :title="$t('staffAndModerators')">
+- <div class="row">
+- <div
+- v-for="user in staff"
+- :key="user.uuid"
+- class="col-4 staff"
+- :class="{
+- staff: user.type === 'Staff',
+- moderator: user.type === 'Moderator',
+- bailey: user.name === 'It\'s Bailey'}"
+- >
+- <div>
+- <router-link
+- class="title"
+- :to="{'name': 'userProfile', 'params': {'userId': user.uuid}}"
+- >
+- {{ user.name }}
+- </router-link>
+- <div
+- v-if="user.type === 'Staff'"
+- class="svg-icon staff-icon"
+- v-html="icons.tierStaff"
+- ></div>
+- <div
+- v-if="user.type === 'Moderator' && user.name !== 'It\'s Bailey'"
+- class="svg-icon mod-icon"
+- v-html="icons.tierMod"
+- ></div>
+- <div
+- v-if="user.name === 'It\'s Bailey'"
+- class="svg-icon npc-icon"
+- v-html="icons.tierNPC"
+- ></div>
+- </div>
+- <div class="type">
+- {{ user.type }}
+- </div>
+- </div>
+- </div>
+- </sidebar-section>
+ <sidebar-section :title="$t('helpfulLinks')">
+ <ul>
+ <li>
+@@ -335,117 +293,6 @@
+ </li>
+ </ul>
+ </sidebar-section>
+- <sidebar-section :title="$t('playerTiers')">
+- <div class="row">
+- <div class="col-12">
+- <p v-once>
+- {{ $t('playerTiersDesc') }}
+- </p>
+- <ul class="tier-list">
+- <li
+- v-once
+- class="tier1"
+- >
+- {{ $t('tier1') }}
+- <div
+- class="svg-icon tier1-icon"
+- v-html="icons.tier1"
+- ></div>
+- </li>
+- <li
+- v-once
+- class="tier2"
+- >
+- {{ $t('tier2') }}
+- <div
+- class="svg-icon tier2-icon"
+- v-html="icons.tier2"
+- ></div>
+- </li>
+- <li
+- v-once
+- class="tier3"
+- >
+- {{ $t('tier3') }}
+- <div
+- class="svg-icon tier3-icon"
+- v-html="icons.tier3"
+- ></div>
+- </li>
+- <li
+- v-once
+- class="tier4"
+- >
+- {{ $t('tier4') }}
+- <div
+- class="svg-icon tier4-icon"
+- v-html="icons.tier4"
+- ></div>
+- </li>
+- <li
+- v-once
+- class="tier5"
+- >
+- {{ $t('tier5') }}
+- <div
+- class="svg-icon tier5-icon"
+- v-html="icons.tier5"
+- ></div>
+- </li>
+- <li
+- v-once
+- class="tier6"
+- >
+- {{ $t('tier6') }}
+- <div
+- class="svg-icon tier6-icon"
+- v-html="icons.tier6"
+- ></div>
+- </li>
+- <li
+- v-once
+- class="tier7"
+- >
+- {{ $t('tier7') }}
+- <div
+- class="svg-icon tier7-icon"
+- v-html="icons.tier7"
+- ></div>
+- </li>
+- <li
+- v-once
+- class="moderator"
+- >
+- {{ $t('tierModerator') }}
+- <div
+- class="svg-icon mod-icon"
+- v-html="icons.tierMod"
+- ></div>
+- </li>
+- <li
+- v-once
+- class="staff"
+- >
+- {{ $t('tierStaff') }}
+- <div
+- class="svg-icon staff-icon"
+- v-html="icons.tierStaff"
+- ></div>
+- </li>
+- <li
+- v-once
+- class="npc"
+- >
+- {{ $t('tierNPC') }}
+- <div
+- class="svg-icon npc-icon"
+- v-html="icons.tierNPC"
+- ></div>
+- </li>
+- </ul>
+- </div>
+- </div>
+- </sidebar-section>
+ </div>
+ </div>
+ </div>
+@@ -495,26 +342,6 @@
margin-left: .5em;
}
@@ -100,7 +207,7 @@ index e37284fec1..522a3b4f50 100644
.boss-icon {
width: 16px;
margin-top: .1em;
-@@ -220,88 +154,6 @@
+@@ -525,88 +352,6 @@
width: 48px;
}
@@ -189,27 +296,27 @@ index e37284fec1..522a3b4f50 100644
.boss-section {
padding: 1.75em;
}
-@@ -431,19 +283,7 @@ import questBackground from 'assets/svg/quest-background-border.svg';
- import rageIcon from 'assets/svg/rage.svg';
- import swordIcon from 'assets/svg/sword.svg';
+@@ -736,19 +481,7 @@ import questBackground from '@/assets/svg/quest-background-border.svg';
+ import rageIcon from '@/assets/svg/rage.svg';
+ import swordIcon from '@/assets/svg/sword.svg';
--import tier1 from 'assets/svg/tier-1.svg';
--import tier2 from 'assets/svg/tier-2.svg';
--import tier3 from 'assets/svg/tier-3.svg';
--import tier4 from 'assets/svg/tier-4.svg';
--import tier5 from 'assets/svg/tier-5.svg';
--import tier6 from 'assets/svg/tier-6.svg';
--import tier7 from 'assets/svg/tier-7.svg';
--import tierMod from 'assets/svg/tier-mod.svg';
--import tierNPC from 'assets/svg/tier-npc.svg';
--import tierStaff from 'assets/svg/tier-staff.svg';
--
- import quests from 'common/script/content/quests';
+-import tier1 from '@/assets/svg/tier-1.svg';
+-import tier2 from '@/assets/svg/tier-2.svg';
+-import tier3 from '@/assets/svg/tier-3.svg';
+-import tier4 from '@/assets/svg/tier-4.svg';
+-import tier5 from '@/assets/svg/tier-5.svg';
+-import tier6 from '@/assets/svg/tier-6.svg';
+-import tier7 from '@/assets/svg/tier-7.svg';
+-import tierMod from '@/assets/svg/tier-mod.svg';
+-import tierNPC from '@/assets/svg/tier-npc.svg';
+-import tierStaff from '@/assets/svg/tier-staff.svg';
+-
+ import * as quests from '@/../../common/script/content/quests';
-import staffList from '../../libs/staffList';
export default {
components: {
-@@ -464,16 +304,6 @@ export default {
+@@ -769,16 +502,6 @@ export default {
questBackground,
rageIcon,
swordIcon,
@@ -226,7 +333,7 @@ index e37284fec1..522a3b4f50 100644
}),
group: {
chat: [],
-@@ -481,7 +311,6 @@ export default {
+@@ -786,7 +509,6 @@ export default {
sections: {
worldBoss: true,
},
diff --git a/pkgs/shabitica/patches/webpack-node-path.patch b/pkgs/shabitica/patches/webpack-node-path.patch
deleted file mode 100644
index 37d16c6..0000000
--- a/pkgs/shabitica/patches/webpack-node-path.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-Author: aszlig <aszlig@nix.build>
-Date: Wed Mar 28 07:11:27 2018 +0200
-
- webpack: Use NODE_PATH for resolving dependencies
-
- While this won't help for resolving *all* required modules, this at
- least works around a few issues with file-loader.
-
- Signed-off-by: aszlig <aszlig@nix.build>
- Filename: webpack-node-path.patch
-
-diff --git a/webpack/webpack.base.conf.js b/webpack/webpack.base.conf.js
-index fcc86bc21b..05d3e2c025 100644
---- a/webpack/webpack.base.conf.js
-+++ b/webpack/webpack.base.conf.js
-@@ -1,6 +1,7 @@
- /* eslint-disable no-process-env, no-console */
-
- const path = require('path');
-+const fs = require('fs');
- const config = require('./config');
- const utils = require('./utils');
- const webpack = require('webpack');
-@@ -8,6 +9,10 @@ const projectRoot = path.resolve(__dirname, '../');
- const autoprefixer = require('autoprefixer');
- const postcssEasyImport = require('postcss-easy-import');
- const IS_PROD = process.env.NODE_ENV === 'production';
-+const nodePathBase = process.env.NODE_PATH.split(':');
-+const nodePathDeep = nodePathBase.map(p =>
-+ path.join(p, fs.readdirSync(p)[0], 'node_modules'));
-+const nodePath = nodePathBase.concat(nodePathDeep);
-
- const baseConfig = {
- entry: {
-@@ -28,13 +33,15 @@ const baseConfig = {
- return filename;
- },
- },
-+ resolveLoader: {
-+ modules: nodePath,
-+ },
- resolve: {
- extensions: ['*', '.js', '.vue', '.json'],
- modules: [
- path.join(projectRoot, 'website'),
- path.join(projectRoot, 'test/client/unit'),
-- path.join(projectRoot, 'node_modules'),
-- ],
-+ ].concat(nodePath),
- alias: {
- website: path.resolve(projectRoot, 'website'),
- common: path.resolve(projectRoot, 'website/common'),
-@@ -57,6 +64,7 @@ const baseConfig = {
- config.build.productionSourceMap :
- config.dev.cssSourceMap,
- extract: IS_PROD,
-+ modules: nodePath,
- }),
- postcss: [
- autoprefixer({
diff --git a/pkgs/shabitica/source.nix b/pkgs/shabitica/source.nix
index 4ce4176..e5d755b 100644
--- a/pkgs/shabitica/source.nix
+++ b/pkgs/shabitica/source.nix
@@ -6,14 +6,14 @@ stdenv.mkDerivation rec {
name = "shabitica-source-${version}";
# NOTE: If appropriate, run update-deps.py after changing this!
# Also, don't forget to run ./find-canaries.py after rebasing patches.
- version = "4.116.7";
+ version = "4.119.2";
src = fetchFromGitHub {
name = "habitica-source-${version}";
owner = "HabitRPG";
repo = "habitica";
rev = "v${version}";
- sha256 = "1n5r08y67hh11l2mfmablfm6ygddbvgzsys473gxl9h4p01dnq13";
+ sha256 = "1hdavvr89c37jia5l3w5adq8112ipa4sv66wvzvsk93cvz5h4j8r";
};
phases = [ "unpackPhase" "patchPhase" "checkPhase" "installPhase" ];
@@ -63,12 +63,6 @@ stdenv.mkDerivation rec {
# Don't restrict to use email domains such as habitica.com or habitrpg.com.
patches/dont-restrict-email-domains.patch
- # Fix an import of "../../website/common" to not use "../website".
- patches/fix-server-common-import.patch
-
- # Force webpack to use NODE_PATH.
- patches/webpack-node-path.patch
-
# Hardcode the server version using substituteInPlace below.
patches/hardcoded-server-version.patch
@@ -173,10 +167,6 @@ stdenv.mkDerivation rec {
# Use image proxy for profile photos.
patches/profile-photo-imageproxy.patch
- # The chat model has been refactored in version 4.62.2 and is now residing
- # in the same source file as other messages.
- patches/fix-import-of-chat-model.patch
-
# Get rid of artifacts (such as empty objects or other cruft) for the inbox
# migration.
patches/fix-inbox-migration.patch
@@ -225,37 +215,41 @@ stdenv.mkDerivation rec {
"test/api/v3/integration/user/*-user_push_device.test.js"
"test/api/v3/integration/user/auth/DELETE-user_auth_social_network.test.js"
"test/api/v3/integration/user/auth/POST-user_auth_social.test.js"
- "website/client/assets/scss/payments.scss"
- "website/client/assets/svg/amazonpay.svg"
- "website/client/assets/svg/credit-card.svg"
- "website/client/components/achievements/newStuff.vue"
- "website/client/components/auth/authForm.vue"
- "website/client/components/bannedAccountModal.vue"
- "website/client/components/group-plans/billing.vue"
- "website/client/components/group-plans/createGroupModalPages.vue"
- "website/client/components/group-plans/groupPlanOverviewModal.vue"
- "website/client/components/groups/communityGuidelines.vue"
- "website/client/components/header/notifications/newStuff.vue"
- "website/client/components/payments/amazonButton.vue"
- "website/client/components/payments/amazonModal.vue"
- "website/client/components/payments/buyGemsModal.vue"
- "website/client/components/payments/cancelModalConfirm.vue"
- "website/client/components/payments/canceledModal.vue"
- "website/client/components/payments/sendGemsModal.vue"
- "website/client/components/payments/successModal.vue"
- "website/client/components/static/communityGuidelines.vue"
- "website/client/components/static/contact.vue"
- "website/client/components/static/groupPlans.vue"
- "website/client/components/static/merch.vue"
- "website/client/components/static/newStuff.vue"
- "website/client/components/static/pressKit.vue"
- "website/client/libs/analytics.js"
- "website/client/libs/logging.js"
- "website/client/libs/modform.js"
- "website/client/libs/payments.js"
- "website/client/libs/staffList.js"
- "website/client/mixins/payments.js"
- "website/client/router/handleRedirect.js"
+ "website/client/package-lock.json"
+ "website/client/public/static/emails"
+ "website/client/public/static/merch"
+ "website/client/public/static/presskit"
+ "website/client/src/assets/scss/payments.scss"
+ "website/client/src/assets/svg/amazonpay.svg"
+ "website/client/src/assets/svg/credit-card.svg"
+ "website/client/src/components/achievements/newStuff.vue"
+ "website/client/src/components/auth/authForm.vue"
+ "website/client/src/components/bannedAccountModal.vue"
+ "website/client/src/components/group-plans/billing.vue"
+ "website/client/src/components/group-plans/createGroupModalPages.vue"
+ "website/client/src/components/group-plans/groupPlanOverviewModal.vue"
+ "website/client/src/components/groups/communityGuidelines.vue"
+ "website/client/src/components/header/notifications/newStuff.vue"
+ "website/client/src/components/payments/amazonButton.vue"
+ "website/client/src/components/payments/amazonModal.vue"
+ "website/client/src/components/payments/buyGemsModal.vue"
+ "website/client/src/components/payments/cancelModalConfirm.vue"
+ "website/client/src/components/payments/canceledModal.vue"
+ "website/client/src/components/payments/sendGemsModal.vue"
+ "website/client/src/components/payments/successModal.vue"
+ "website/client/src/components/static/communityGuidelines.vue"
+ "website/client/src/components/static/contact.vue"
+ "website/client/src/components/static/groupPlans.vue"
+ "website/client/src/components/static/merch.vue"
+ "website/client/src/components/static/newStuff.vue"
+ "website/client/src/components/static/pressKit.vue"
+ "website/client/src/libs/analytics.js"
+ "website/client/src/libs/logging.js"
+ "website/client/src/libs/modform.js"
+ "website/client/src/libs/payments.js"
+ "website/client/src/libs/staffList.js"
+ "website/client/src/mixins/payments.js"
+ "website/client/src/router/handleRedirect.js"
"website/common/locales/*/communityguidelines.json"
"website/common/locales/*/merch.json"
"website/server/controllers/api-v3/iap.js"
@@ -285,9 +279,6 @@ stdenv.mkDerivation rec {
"website/server/middlewares/analytics.js"
"website/server/middlewares/static.js"
"website/server/models/pushDevice.js"
- "website/static/emails"
- "website/static/merch"
- "website/static/presskit"
];
prePatch = lib.concatMapStringsSep "\n" (path: "rm -r ${path}") filesToKill;
@@ -405,7 +396,7 @@ stdenv.mkDerivation rec {
"api-v3/groups\\.js:.*await payments.createSubscription"
"api-v3/groups\\.js:import payments from"
"auth.js:.*function verifyDisplayName.*{"
- "hall/heroes\\.vue:.*Common titles:.*Scribe, Socialite, Storyteller"
+ "hall/heroes\\.vue:.*<strong>.*Scribe, Socialite, Storyteller"
"rebirth\\.vue:.*b-modal#rebirth"
"static/privacy\\.vue:.*doesn't use any analytics"
"static/terms\\.vue:.*such as Google Chrome"
@@ -431,8 +422,8 @@ stdenv.mkDerivation rec {
postPatch = ''
# See 'rewriteHabiticaURIs' attribute above.
- find . -path ./test -prune -o -path ./website/static -prune -o \
- -type f -exec sed -i -e "$rewriteHabiticaURIs" {} +
+ find . -path ./test -prune -o -path ./website/client/public/static \
+ -prune -o -type f -exec sed -i -e "$rewriteHabiticaURIs" {} +
echo "checking whether we have external services in the code..." >&2
extServices="$(
@@ -454,8 +445,9 @@ stdenv.mkDerivation rec {
exit 1
fi
- cp --no-preserve=mode -r "$googleFonts" website/static/fonts
- cp --no-preserve=mode -rt website/static "$emojis/public/graphics/emojis"
+ cp --no-preserve=mode -r "$googleFonts" website/client/public/static/fonts
+ cp --no-preserve=mode -rt website/client/public/static \
+ "$emojis/public/graphics/emojis"
'';
googleFonts = runCommand "google-fonts" {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment