mirror of
https://github.com/sudoxnym/habitica-self-host.git
synced 2026-04-14 11:36:45 +00:00
* add date check * achievements modal polishing * refresh private-messages page when you are already on it * add countbadge knob to change the example * fix lint * typos * typos * typos * add toggle for achievements categories * typo * fix test * fix edit avatar modal cannot be closed * WIP(settings): subscriber page improvements * WIP(subscriptions): more design build-out * fix(css): disabled button styles * fix(css): better Amazon targeting * fix hide tooltip + align header correctly * disable perfect scroll * load messages on refresh event * fix header label + conversation actions not breaking layout on hover * WIP(g1g1): notif * WIP(g1g1): notif cont'd * fix(test): snowball change * fix(event): feature NYE card * chore(sprites): compile * fix(bgs): include TT required field * add gifting banner to the max height calculation * chore(event): enable winter customizations * WIP(gifting): partial modal implementation * feat(gifting): select giftee modal * fix(gifting): notification order, modal dismiss * Begin implementing sign in with apple # Conflicts: # package-lock.json # website/common/script/constants.js # website/server/libs/auth/social.js # website/server/models/user/schema.js * Add apple sign in button to website * fix lint errors * fix config json * fix(modals): correct some repops * fix(gifting): style updates * fix(buy): modal style changes * fix(modals): also clean out "prev" * Attempt workaround for sign in with apple on android * temporarily log everything as error * refactor(modals): hide in dismiss event * fix temporary test failure * changes to sign in with apple * fix: first batch of layout issues for private messages + auto sizing textarea * fix(modals): new dismiss logic * fix(modals): new dismiss no go?? * Only use email scope * print debugging * . * .. * ... * username second line - open profile on face-avatar/conversation name - fix textarea height * temporarily disable apple auth and just return data for debugging * Hopefully this works * ..... * WIP(subscription): unsubscribed state * . * .. * MAYBE THIS ACTUALLY WORKS??? * Implement apple sign in * fix some urls * fix urls * fix redirect and auth * attempt to also request name * fix lint error * WIP(subscription): partial subscribed * chore(sprites): compile * Change approach so that it actually works * fix config error * fix lint errors * Fix * fix lint error * lint error * WIP(subscription): finish subscribed * refresh on sync * new "you dont have any messages" style + changed min textarea height * new conversationItem style / layout * reset message unread on reload * chore(npm): update package-locks * fix styles / textarea height * feat(subscription): revised sub page RC * list optOut / chatRevoked informations for each conversation + show why its disabled * Improve apple redirect view * Fix apple icon on group task registration page * WIP(adventure): prereqs * Block / Unblock - correct disabled states - $gray-200 instead of 300/400 * canReceive not checking chatRevoked * fix: faceAvatar / userLink open the selected conversation user * check if the target user is blocking the logged-in user * fix(subs): style tweaks * fix(profiles): short circuit contributor Attempted fix for #11830 * chore(sprites): compile * fix(content): missing potion data * fix(content): missing string * WIP(drops): new modal * fix(subs): moar style tweaks * check if blocks is undefined * max-height instead of height * fix "no messages" state + canReceive on a new conversation * WIP(adventure): analytics fixes etc * Improve apple signin handling * fixed conversations width (280px on max 768 width page) * feat(adventure): random egg+potion on 2nd task * fix(lint): noworkies * fix(modal): correctly construct classes * fix(tests): expectations and escape * Fix typo * use base url from env variables * fix lint * call autosize after message is sent * fix urls * always verify token * throw error when social auth could not retrieve id * Store emails correctly for apple auth * Retrieve name when authenticating through apple * Fix lint errors * fix all lint errors * fix(content): missing strings * Revert "always verify token" This reverts commit 8ac40c76bfa880f68fa3ce350a86ce2151b9cf95. # Conflicts: # website/server/libs/auth/social.js * Correctly load name * remove extra changes * remove extra logger call * reset package and package-lock * add back missing packages * use name from apple * add support for multiple apple public keys * add some unit and integration tests * add apple auth integration test * tweak social signup buttons * pixel pushing Co-authored-by: Matteo Pagliazzi <matteopagliazzi@gmail.com> Co-authored-by: Sabe Jones <sabrecat@gmail.com> Co-authored-by: negue <eugen.bolz@gmail.com> Co-authored-by: Phillip Thelen <phillip@habitica.com>
237 lines
8 KiB
JavaScript
237 lines
8 KiB
JavaScript
/* eslint-disable global-require */
|
|
import got from 'got';
|
|
import nconf from 'nconf';
|
|
import requireAgain from 'require-again';
|
|
import { TAVERN_ID } from '../../../../website/server/models/group';
|
|
import { defer } from '../../../helpers/api-unit.helper';
|
|
|
|
function getUser () {
|
|
return {
|
|
_id: 'random _id',
|
|
auth: {
|
|
local: {
|
|
username: 'username',
|
|
email: 'email@email',
|
|
},
|
|
facebook: {
|
|
emails: [{
|
|
value: 'email@facebook',
|
|
}],
|
|
},
|
|
google: {
|
|
emails: [{
|
|
value: 'email@google',
|
|
}],
|
|
},
|
|
apple: {
|
|
emails: [{
|
|
value: 'email@apple',
|
|
}],
|
|
},
|
|
},
|
|
profile: {
|
|
name: 'profile name',
|
|
},
|
|
preferences: {
|
|
emailNotifications: {
|
|
unsubscribeFromAll: false,
|
|
},
|
|
},
|
|
};
|
|
}
|
|
|
|
describe('emails', () => {
|
|
const pathToEmailLib = '../../../../website/server/libs/email';
|
|
|
|
describe('getUserInfo', () => {
|
|
it('returns an empty object if no field request', () => {
|
|
const attachEmail = requireAgain(pathToEmailLib);
|
|
const { getUserInfo } = attachEmail;
|
|
expect(getUserInfo({}, [])).to.be.empty;
|
|
});
|
|
|
|
it('returns correct user data', () => {
|
|
const attachEmail = requireAgain(pathToEmailLib);
|
|
const { getUserInfo } = attachEmail;
|
|
const user = getUser();
|
|
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.local.email);
|
|
expect(data).to.have.property('_id', user._id);
|
|
expect(data).to.have.property('canSend', true);
|
|
});
|
|
|
|
it('returns correct user data [facebook users]', () => {
|
|
const attachEmail = requireAgain(pathToEmailLib);
|
|
const { getUserInfo } = attachEmail;
|
|
const user = getUser();
|
|
delete user.profile.name;
|
|
delete user.auth.local.email;
|
|
delete user.auth.google.emails;
|
|
delete user.auth.apple.emails;
|
|
|
|
const data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
|
|
|
|
expect(data).to.have.property('name', user.auth.local.username);
|
|
expect(data).to.have.property('email', user.auth.facebook.emails[0].value);
|
|
expect(data).to.have.property('_id', user._id);
|
|
expect(data).to.have.property('canSend', true);
|
|
});
|
|
|
|
it('returns correct user data [google users]', () => {
|
|
const attachEmail = requireAgain(pathToEmailLib);
|
|
const { getUserInfo } = attachEmail;
|
|
const user = getUser();
|
|
delete user.profile.name;
|
|
delete user.auth.local.email;
|
|
delete user.auth.facebook.emails;
|
|
delete user.auth.apple.emails;
|
|
|
|
const data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
|
|
|
|
expect(data).to.have.property('name', user.auth.local.username);
|
|
expect(data).to.have.property('email', user.auth.google.emails[0].value);
|
|
expect(data).to.have.property('_id', user._id);
|
|
expect(data).to.have.property('canSend', true);
|
|
});
|
|
|
|
it('returns correct user data [apple users]', () => {
|
|
const attachEmail = requireAgain(pathToEmailLib);
|
|
const { getUserInfo } = attachEmail;
|
|
const user = getUser();
|
|
delete user.profile.name;
|
|
delete user.auth.local.email;
|
|
delete user.auth.google.emails;
|
|
delete user.auth.facebook.emails;
|
|
|
|
const data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
|
|
|
|
expect(data).to.have.property('name', user.auth.local.username);
|
|
expect(data).to.have.property('email', user.auth.apple.emails[0].value);
|
|
expect(data).to.have.property('_id', user._id);
|
|
expect(data).to.have.property('canSend', true);
|
|
});
|
|
|
|
it('has fallbacks for missing data', () => {
|
|
const attachEmail = requireAgain(pathToEmailLib);
|
|
const { getUserInfo } = attachEmail;
|
|
const user = getUser();
|
|
delete user.auth.local.email;
|
|
delete user.auth.facebook;
|
|
delete user.auth.google;
|
|
delete user.auth.apple;
|
|
|
|
const data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
|
|
|
|
expect(data).to.have.property('name', user.auth.local.username);
|
|
expect(data).not.to.have.property('email');
|
|
expect(data).to.have.property('_id', user._id);
|
|
expect(data).to.have.property('canSend', true);
|
|
});
|
|
});
|
|
|
|
describe('getGroupUrl', () => {
|
|
it('returns correct url if group is the tavern', () => {
|
|
const { getGroupUrl } = require(pathToEmailLib); // eslint-disable-line import/no-dynamic-require, max-len
|
|
expect(getGroupUrl({ _id: TAVERN_ID, type: 'guild' })).to.eql('/groups/tavern');
|
|
});
|
|
|
|
it('returns correct url if group is a guild', () => {
|
|
const { getGroupUrl } = require(pathToEmailLib); // eslint-disable-line import/no-dynamic-require, max-len
|
|
expect(getGroupUrl({ _id: 'random _id', type: 'guild' })).to.eql('/groups/guild/random _id');
|
|
});
|
|
|
|
it('returns correct url if group is a party', () => {
|
|
const { getGroupUrl } = require(pathToEmailLib); // eslint-disable-line import/no-dynamic-require, max-len
|
|
expect(getGroupUrl({ _id: 'random _id', type: 'party' })).to.eql('party');
|
|
});
|
|
});
|
|
|
|
describe('sendTxnEmail', () => {
|
|
beforeEach(() => {
|
|
sandbox.stub(got, 'post').returns(defer().promise);
|
|
});
|
|
|
|
afterEach(() => {
|
|
sandbox.restore();
|
|
});
|
|
|
|
it('can send a txn email to one recipient', () => {
|
|
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
|
|
const attachEmail = requireAgain(pathToEmailLib);
|
|
const sendTxnEmail = attachEmail.sendTxn;
|
|
const emailType = 'an email type';
|
|
const mailingInfo = {
|
|
name: 'my name',
|
|
email: 'my@email',
|
|
};
|
|
|
|
sendTxnEmail(mailingInfo, emailType);
|
|
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
|
|
json: {
|
|
data: {
|
|
emailType: sinon.match.same(emailType),
|
|
to: sinon.match(value => Array.isArray(value) && value[0].name === mailingInfo.name, 'matches mailing info array'),
|
|
},
|
|
},
|
|
}));
|
|
});
|
|
|
|
it('does not send email if address is missing', () => {
|
|
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
|
|
const attachEmail = requireAgain(pathToEmailLib);
|
|
const sendTxnEmail = attachEmail.sendTxn;
|
|
const emailType = 'an email type';
|
|
const mailingInfo = {
|
|
name: 'my name',
|
|
// email: 'my@email',
|
|
};
|
|
|
|
sendTxnEmail(mailingInfo, emailType);
|
|
expect(got.post).not.to.be.called;
|
|
});
|
|
|
|
it('uses getUserInfo in case of user data', () => {
|
|
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
|
|
const attachEmail = requireAgain(pathToEmailLib);
|
|
const sendTxnEmail = attachEmail.sendTxn;
|
|
const emailType = 'an email type';
|
|
const mailingInfo = getUser();
|
|
|
|
sendTxnEmail(mailingInfo, emailType);
|
|
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
|
|
json: {
|
|
data: {
|
|
emailType: sinon.match.same(emailType),
|
|
to: sinon.match(val => val[0]._id === mailingInfo._id),
|
|
},
|
|
},
|
|
}));
|
|
});
|
|
|
|
it('sends email with some default variables', () => {
|
|
sandbox.stub(nconf, 'get').withArgs('IS_PROD').returns(true);
|
|
const attachEmail = requireAgain(pathToEmailLib);
|
|
const sendTxnEmail = attachEmail.sendTxn;
|
|
const emailType = 'an email type';
|
|
const mailingInfo = {
|
|
name: 'my name',
|
|
email: 'my@email',
|
|
};
|
|
const variables = [1, 2, 3];
|
|
|
|
sendTxnEmail(mailingInfo, emailType, variables);
|
|
expect(got.post).to.be.calledWith('undefined/job', sinon.match({
|
|
json: {
|
|
data: {
|
|
variables: sinon.match(value => value[0].name === 'BASE_URL', 'matches variables'),
|
|
personalVariables: sinon.match(value => value[0].rcpt === mailingInfo.email
|
|
&& value[0].vars[0].name === 'RECIPIENT_NAME'
|
|
&& value[0].vars[1].name === 'RECIPIENT_UNSUB_URL', 'matches personal variables'),
|
|
},
|
|
},
|
|
}));
|
|
});
|
|
});
|
|
});
|