Skip to content

Commit

Permalink
Merge branch 'develop' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
SabreCat committed Sep 19, 2022
2 parents d4f9555 + f030135 commit e60285e
Show file tree
Hide file tree
Showing 84 changed files with 2,418 additions and 1,372 deletions.
2 changes: 1 addition & 1 deletion habitica-images
Submodule habitica-images updated 34 files
+ gear/events/fall/broad_armor_special_fall2022Healer.png
+ gear/events/fall/broad_armor_special_fall2022Mage.png
+ gear/events/fall/broad_armor_special_fall2022Rogue.png
+ gear/events/fall/broad_armor_special_fall2022Warrior.png
+ gear/events/fall/head_special_fall2022Healer.png
+ gear/events/fall/head_special_fall2022Mage.png
+ gear/events/fall/head_special_fall2022Rogue.png
+ gear/events/fall/head_special_fall2022Warrior.png
+ gear/events/fall/shield_special_fall2022Healer.png
+ gear/events/fall/shield_special_fall2022Rogue.png
+ gear/events/fall/shield_special_fall2022Warrior.png
+ gear/events/fall/shop/shop_armor_special_fall2022Healer.png
+ gear/events/fall/shop/shop_armor_special_fall2022Mage.png
+ gear/events/fall/shop/shop_armor_special_fall2022Rogue.png
+ gear/events/fall/shop/shop_armor_special_fall2022Warrior.png
+ gear/events/fall/shop/shop_head_special_fall2022Healer.png
+ gear/events/fall/shop/shop_head_special_fall2022Mage.png
+ gear/events/fall/shop/shop_head_special_fall2022Rogue.png
+ gear/events/fall/shop/shop_head_special_fall2022Warrior.png
+ gear/events/fall/shop/shop_shield_special_fall2022Healer.png
+ gear/events/fall/shop/shop_shield_special_fall2022Rogue.png
+ gear/events/fall/shop/shop_shield_special_fall2022Warrior.png
+ gear/events/fall/shop/shop_weapon_special_fall2022Healer.png
+ gear/events/fall/shop/shop_weapon_special_fall2022Mage.png
+ gear/events/fall/shop/shop_weapon_special_fall2022Rogue.png
+ gear/events/fall/shop/shop_weapon_special_fall2022Warrior.png
+ gear/events/fall/slim_armor_special_fall2022Healer.png
+ gear/events/fall/slim_armor_special_fall2022Mage.png
+ gear/events/fall/slim_armor_special_fall2022Rogue.png
+ gear/events/fall/slim_armor_special_fall2022Warrior.png
+ gear/events/fall/weapon_special_fall2022Healer.png
+ gear/events/fall/weapon_special_fall2022Mage.png
+ gear/events/fall/weapon_special_fall2022Rogue.png
+ gear/events/fall/weapon_special_fall2022Warrior.png
1,089 changes: 788 additions & 301 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
"main": "./website/server/index.js",
"dependencies": {
"@babel/core": "^7.18.13",
"@babel/preset-env": "^7.18.10",
"@babel/preset-env": "^7.19.1",
"@babel/register": "^7.18.9",
"@google-cloud/trace-agent": "^5.1.6",
"@parse/node-apn": "^5.1.3",
"@slack/webhook": "^6.1.0",
"accepts": "^1.3.8",
"amazon-payments": "^0.2.9",
"amplitude": "^6.0.0",
"apidoc": "^0.52.0",
"apidoc": "^0.53.0",
"apple-auth": "^1.0.7",
"bcrypt": "^5.0.1",
"body-parser": "^1.20.0",
Expand Down Expand Up @@ -61,7 +61,7 @@
"paypal-rest-sdk": "^1.8.1",
"pp-ipn": "^1.1.0",
"ps-tree": "^1.0.0",
"rate-limiter-flexible": "^2.3.7",
"rate-limiter-flexible": "^2.3.10",
"redis": "^3.1.2",
"regenerator-runtime": "^0.13.9",
"remove-markdown": "^0.5.0",
Expand Down
25 changes: 0 additions & 25 deletions test/api/unit/libs/email.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ function getUser () {
username: 'username',
email: 'email@email',
},
facebook: {
emails: [{
value: 'email@facebook',
}],
},
google: {
emails: [{
value: 'email@google',
Expand Down Expand Up @@ -62,30 +57,12 @@ describe('emails', () => {
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']);
Expand All @@ -103,7 +80,6 @@ describe('emails', () => {
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']);

Expand All @@ -118,7 +94,6 @@ describe('emails', () => {
const { getUserInfo } = attachEmail;
const user = getUser();
delete user.auth.local.email;
delete user.auth.facebook;
delete user.auth.google;
delete user.auth.apple;

Expand Down
2 changes: 1 addition & 1 deletion test/api/unit/libs/password.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ describe('Password Utilities', () => {
it('returns false if the user has no local auth', async () => {
const user = await generateUser({
auth: {
facebook: {},
google: {},
},
});
const res = await validatePasswordResetCodeAndFindUser(encrypt(JSON.stringify({
Expand Down
39 changes: 0 additions & 39 deletions test/api/v3/integration/user/DELETE-user.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,45 +289,6 @@ describe('DELETE /user', () => {
});
});

context('user with Facebook auth', async () => {
beforeEach(async () => {
user = await generateUser({
auth: {
facebook: {
id: 'facebook-id',
},
},
});
});

it('returns an error if confirmation phrase is wrong', async () => {
await expect(user.del('/user', {
password: 'just-do-it',
})).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('incorrectDeletePhrase', { magicWord: 'DELETE' }),
});
});

it('returns an error if confirmation phrase is not supplied', async () => {
await expect(user.del('/user', {
password: '',
})).to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: t('missingPassword'),
});
});

it('deletes a Facebook user', async () => {
await user.del('/user', {
password: DELETE_CONFIRMATION,
});
await expect(checkExistence('users', user._id)).to.eventually.eql(false);
});
});

context('user with Google auth', async () => {
beforeEach(async () => {
user = await generateUser({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,44 +20,6 @@ describe('DELETE social registration', () => {
});
});

context('Facebook', () => {
it('fails if user does not have an alternative registration method', async () => {
await user.update({
'auth.facebook.id': 'some-fb-id',
'auth.local': { ok: true },
});
await expect(user.del('/user/auth/social/facebook')).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('cantDetachSocial'),
});
});

it('succeeds if user has a local registration', async () => {
await user.update({
'auth.facebook.id': 'some-fb-id',
});

const response = await user.del('/user/auth/social/facebook');
expect(response).to.eql({});
await user.sync();
expect(user.auth.facebook).to.be.undefined;
});

it('succeeds if user has a google registration', async () => {
await user.update({
'auth.facebook.id': 'some-fb-id',
'auth.google.id': 'some-google-id',
'auth.local': { ok: true },
});

const response = await user.del('/user/auth/social/facebook');
expect(response).to.eql({});
await user.sync();
expect(user.auth.facebook).to.be.undefined;
});
});

context('Google', () => {
it('fails if user does not have an alternative registration method', async () => {
await user.update({
Expand All @@ -81,19 +43,6 @@ describe('DELETE social registration', () => {
await user.sync();
expect(user.auth.google).to.be.undefined;
});

it('succeeds if user has a facebook registration', async () => {
await user.update({
'auth.google.id': 'some-google-id',
'auth.facebook.id': 'some-facebook-id',
'auth.local': { ok: true },
});

const response = await user.del('/user/auth/social/google');
expect(response).to.eql({});
await user.sync();
expect(user.auth.goodl).to.be.undefined;
});
});

context('Apple', () => {
Expand All @@ -119,18 +68,5 @@ describe('DELETE social registration', () => {
await user.sync();
expect(user.auth.apple).to.be.undefined;
});

it('succeeds if user has a facebook registration', async () => {
await user.update({
'auth.apple.id': 'some-apple-id',
'auth.facebook.id': 'some-facebook-id',
'auth.local': { ok: true },
});

const response = await user.del('/user/auth/social/apple');
expect(response).to.eql({});
await user.sync();
expect(user.auth.goodl).to.be.undefined;
});
});
});
141 changes: 0 additions & 141 deletions test/api/v3/integration/user/auth/POST-user_auth_social.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ describe('POST /user/auth/social', () => {
let user;
const endpoint = '/user/auth/social';
let randomAccessToken = '123456';
let randomFacebookId = 'facebookId';
let randomGoogleId = 'googleId';
let network = 'NoNetwork';

Expand All @@ -33,146 +32,6 @@ describe('POST /user/auth/social', () => {
});
});

describe('facebook', () => {
beforeEach(async () => {
randomFacebookId = generateUUID();
const expectedResult = {
id: randomFacebookId,
displayName: 'a facebook user',
emails: [
{ value: `${user.auth.local.username}+facebook@example.com` },
],
};
sandbox.stub(passport._strategies.facebook, 'userProfile').yields(null, expectedResult);
network = 'facebook';
});

afterEach(async () => {
passport._strategies.facebook.userProfile.restore();
});

it('registers a new user', async () => {
const response = await api.post(endpoint, {
authResponse: { access_token: randomAccessToken }, // eslint-disable-line camelcase
network,
});

expect(response.apiToken).to.exist;
expect(response.id).to.exist;
expect(response.newUser).to.be.true;
expect(response.username).to.exist;

await expect(getProperty('users', response.id, 'profile.name')).to.eventually.equal('a facebook user');
await expect(getProperty('users', response.id, 'auth.local.lowerCaseUsername')).to.exist;
await expect(getProperty('users', response.id, 'auth.local.email')).to.eventually.equal(`${user.auth.local.username}+facebook@example.com`);
await expect(getProperty('users', response.id, 'auth.facebook.id')).to.eventually.equal(randomFacebookId);
});

it('logs an existing user in', async () => {
const registerResponse = await api.post(endpoint, {
authResponse: { access_token: randomAccessToken }, // eslint-disable-line camelcase
network,
});

const response = await api.post(endpoint, {
authResponse: { access_token: randomAccessToken }, // eslint-disable-line camelcase
network,
});

expect(response.apiToken).to.eql(registerResponse.apiToken);
expect(response.id).to.eql(registerResponse.id);
expect(response.newUser).to.be.false;
expect(registerResponse.newUser).to.be.true;
});

it('logs an existing user in if they have local auth with matching email', async () => {
passport._strategies.facebook.userProfile.restore();
const expectedResult = {
id: randomFacebookId,
displayName: 'a facebook user',
emails: [
{ value: user.auth.local.email },
],
};
sandbox.stub(passport._strategies.facebook, 'userProfile').yields(null, expectedResult);

const response = await api.post(endpoint, {
authResponse: { access_token: randomAccessToken }, // eslint-disable-line camelcase
network,
});

expect(response.apiToken).to.eql(user.apiToken);
expect(response.id).to.eql(user._id);
expect(response.newUser).to.be.false;
});

it('logs an existing user into their social account if they have local auth with matching email', async () => {
const registerResponse = await api.post(endpoint, {
authResponse: { access_token: randomAccessToken }, // eslint-disable-line camelcase
network,
});
expect(registerResponse.newUser).to.be.true;
// This is important for existing accounts before the new social handling
passport._strategies.facebook.userProfile.restore();
const expectedResult = {
id: randomFacebookId,
displayName: 'a facebook user',
emails: [
{ value: user.auth.local.email },
],
};
sandbox.stub(passport._strategies.facebook, 'userProfile').yields(null, expectedResult);

const response = await api.post(endpoint, {
authResponse: { access_token: randomAccessToken }, // eslint-disable-line camelcase
network,
});

expect(response.apiToken).to.eql(registerResponse.apiToken);
expect(response.id).to.eql(registerResponse.id);
expect(response.apiToken).not.to.eql(user.apiToken);
expect(response.id).not.to.eql(user._id);
expect(response.newUser).to.be.false;
});

it('add social auth to an existing user', async () => {
const response = await user.post(endpoint, {
authResponse: { access_token: randomAccessToken }, // eslint-disable-line camelcase
network,
});

expect(response.apiToken).to.eql(user.apiToken);
expect(response.id).to.eql(user._id);
expect(response.newUser).to.be.false;
});

it('does not log into other account if social auth already exists', async () => {
const registerResponse = await api.post(endpoint, {
authResponse: { access_token: randomAccessToken }, // eslint-disable-line camelcase
network,
});
expect(registerResponse.newUser).to.be.true;

await expect(user.post(endpoint, {
authResponse: { access_token: randomAccessToken }, // eslint-disable-line camelcase
network,
})).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('socialAlreadyExists'),
});
});

xit('enrolls a new user in an A/B test', async () => {
await api.post(endpoint, {
authResponse: { access_token: randomAccessToken }, // eslint-disable-line camelcase
network,
});

await expect(getProperty('users', user._id, '_ABtests')).to.eventually.be.a('object');
});
});

describe('google', () => {
beforeEach(async () => {
randomGoogleId = generateUUID();
Expand Down
Loading

0 comments on commit e60285e

Please sign in to comment.