Skip to content

Commit

Permalink
馃帹 handle case: sync email after logout (#8097)
Browse files Browse the repository at this point in the history
no issue

If the user changes the email in the remote auth service and executes a logout directly afterwards, the user would lock himself out of his blog, because the email sync happens once per hour right now.
For that case, we have to store the ghost auth id.
  • Loading branch information
kirrg001 authored and ErisDS committed Mar 8, 2017
1 parent 345003a commit 27f17c9
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 23 deletions.
9 changes: 7 additions & 2 deletions core/server/auth/auth-strategies.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ strategies = {
});
};

models.User.getByEmail(profile.email, options)
models.User.findOne({ghost_auth_id: profile.id}, options)
.then(function fetchedUser(user) {
if (user) {
return user;
Expand All @@ -142,7 +142,12 @@ strategies = {
})
.then(function updateGhostAuthToken(user) {
options.id = user.id;
return models.User.edit({ghost_auth_access_token: ghostAuthAccessToken}, options);

return models.User.edit({
email: profile.email,
ghost_auth_id: profile.id,
ghost_auth_access_token: ghostAuthAccessToken
}, options);
})
.then(function returnResponse(user) {
done(null, user, profile);
Expand Down
1 change: 1 addition & 0 deletions core/server/data/schema/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ module.exports = {
name: {type: 'string', maxlength: 191, nullable: false},
slug: {type: 'string', maxlength: 191, nullable: false, unique: true},
ghost_auth_access_token: {type: 'string', maxlength: 32, nullable: true},
ghost_auth_id: {type: 'string', maxlength: 24, nullable: true},
password: {type: 'string', maxlength: 60, nullable: false},
email: {type: 'string', maxlength: 191, nullable: false, unique: true, validations: {isEmail: true}},
image: {type: 'string', maxlength: 2000, nullable: true},
Expand Down
51 changes: 31 additions & 20 deletions core/test/unit/auth/auth-strategies_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,9 @@ describe('Auth Strategies', function () {
});

describe('Ghost Strategy', function () {
var userByEmailStub, inviteStub, userAddStub, userEditStub, userFindOneStub;
var inviteStub, userAddStub, userEditStub, userFindOneStub;

beforeEach(function () {
userByEmailStub = sandbox.stub(Models.User, 'getByEmail');
userFindOneStub = sandbox.stub(Models.User, 'findOne');
userAddStub = sandbox.stub(Models.User, 'add');
userEditStub = sandbox.stub(Models.User, 'edit');
Expand All @@ -214,15 +213,15 @@ describe('Auth Strategies', function () {
it('with invite, but with wrong invite token', function (done) {
var ghostAuthAccessToken = '12345',
req = {body: {inviteToken: 'wrong'}},
profile = {email: 'test@example.com'};
profile = {email: 'test@example.com', id: '1234'};

userByEmailStub.returns(Promise.resolve(null));
userFindOneStub.returns(Promise.resolve(null));
inviteStub.returns(Promise.reject(new errors.NotFoundError()));

authStrategies.ghostStrategy(req, ghostAuthAccessToken, null, profile, function (err) {
should.exist(err);
(err instanceof errors.NotFoundError).should.eql(true);
userByEmailStub.calledOnce.should.be.true();
userFindOneStub.calledOnce.should.be.true();
inviteStub.calledOnce.should.be.true();
done();
});
Expand All @@ -231,9 +230,9 @@ describe('Auth Strategies', function () {
it('with correct invite token, but expired', function (done) {
var ghostAuthAccessToken = '12345',
req = {body: {inviteToken: 'token'}},
profile = {email: 'test@example.com'};
profile = {email: 'test@example.com', id: '1234'};

userByEmailStub.returns(Promise.resolve(null));
userFindOneStub.returns(Promise.resolve(null));
inviteStub.returns(Promise.resolve(Models.Invite.forge({
id: 1,
token: 'token',
Expand All @@ -243,7 +242,7 @@ describe('Auth Strategies', function () {
authStrategies.ghostStrategy(req, ghostAuthAccessToken, null, profile, function (err) {
should.exist(err);
(err instanceof errors.NotFoundError).should.eql(true);
userByEmailStub.calledOnce.should.be.true();
userFindOneStub.calledOnce.should.be.true();
inviteStub.calledOnce.should.be.true();
done();
});
Expand All @@ -252,15 +251,15 @@ describe('Auth Strategies', function () {
it('with correct invite token', function (done) {
var ghostAuthAccessToken = '12345',
req = {body: {inviteToken: 'token'}},
invitedProfile = {email: 'test@example.com'},
invitedProfile = {email: 'test@example.com', id: '1234'},
invitedUser = {id: 2},
inviteModel = Models.Invite.forge({
id: 1,
token: 'token',
expires: Date.now() + 1000
});

userByEmailStub.returns(Promise.resolve(null));
userFindOneStub.returns(Promise.resolve(null));
userAddStub.returns(Promise.resolve(invitedUser));
userEditStub.returns(Promise.resolve(invitedUser));
inviteStub.returns(Promise.resolve(inviteModel));
Expand All @@ -273,7 +272,7 @@ describe('Auth Strategies', function () {
user.should.eql(invitedUser);
profile.should.eql(invitedProfile);

userByEmailStub.calledOnce.should.be.true();
userFindOneStub.calledOnce.should.be.true();
inviteStub.calledOnce.should.be.true();
done();
});
Expand All @@ -282,24 +281,32 @@ describe('Auth Strategies', function () {
it('setup', function (done) {
var ghostAuthAccessToken = '12345',
req = {body: {}},
ownerProfile = {email: 'test@example.com'},
ownerProfile = {email: 'test@example.com', id: '1234'},
owner = {id: 2};

userByEmailStub.returns(Promise.resolve(null));
userFindOneStub.returns(Promise.resolve(_.merge({}, {status: 'inactive'}, owner)));
userFindOneStub.withArgs({ghost_auth_id: ownerProfile.id})
.returns(Promise.resolve(null));

userFindOneStub.withArgs({slug: 'ghost-owner', status: 'inactive'})
.returns(Promise.resolve(_.merge({}, {status: 'inactive'}, owner)));

userEditStub.withArgs({status: 'active', email: 'test@example.com'}, {
context: {internal: true},
id: owner.id
}).returns(Promise.resolve(owner));

userEditStub.withArgs({ghost_auth_access_token: ghostAuthAccessToken}, {
userEditStub.withArgs({
ghost_auth_access_token: ghostAuthAccessToken,
ghost_auth_id: ownerProfile.id,
email: ownerProfile.email
}, {
context: {internal: true},
id: owner.id
}).returns(Promise.resolve(owner));

authStrategies.ghostStrategy(req, ghostAuthAccessToken, null, ownerProfile, function (err, user, profile) {
should.not.exist(err);
userByEmailStub.calledOnce.should.be.true();
userFindOneStub.calledTwice.should.be.true();
inviteStub.calledOnce.should.be.false();

should.exist(user);
Expand All @@ -313,18 +320,22 @@ describe('Auth Strategies', function () {
it('auth', function (done) {
var ghostAuthAccessToken = '12345',
req = {body: {}},
ownerProfile = {email: 'test@example.com'},
ownerProfile = {email: 'test@example.com', id: '12345'},
owner = {id: 2};

userByEmailStub.returns(Promise.resolve(owner));
userEditStub.withArgs({ghost_auth_access_token: ghostAuthAccessToken}, {
userFindOneStub.returns(Promise.resolve(owner));
userEditStub.withArgs({
ghost_auth_access_token: ghostAuthAccessToken,
ghost_auth_id: ownerProfile.id,
email: ownerProfile.email
}, {
context: {internal: true},
id: owner.id
}).returns(Promise.resolve(owner));

authStrategies.ghostStrategy(req, ghostAuthAccessToken, null, ownerProfile, function (err, user, profile) {
should.not.exist(err);
userByEmailStub.calledOnce.should.be.true();
userFindOneStub.calledOnce.should.be.true();
userEditStub.calledOnce.should.be.true();
inviteStub.calledOnce.should.be.false();

Expand Down
2 changes: 1 addition & 1 deletion core/test/unit/migration_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ should.equal(true, true);
// both of which are required for migrations to work properly.
describe('DB version integrity', function () {
// Only these variables should need updating
var currentSchemaHash = 'e648a7d1f9b9c5eb19512999756cd4db',
var currentSchemaHash = 'ae4ada98be2691b4d6e323eebcdb875f',
currentFixturesHash = 'b9e684a87353c592df9b23948e364c05';

// If this test is failing, then it is likely a change has been made that requires a DB version bump,
Expand Down

0 comments on commit 27f17c9

Please sign in to comment.