Skip to content

Commit

Permalink
fix(core): Update login credentials when changing customer email address
Browse files Browse the repository at this point in the history
Fixes #1071
  • Loading branch information
michaelbromley committed Sep 13, 2021
1 parent bd22dc5 commit 1ebc872
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 5 deletions.
11 changes: 11 additions & 0 deletions packages/core/e2e/customer.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
GetCustomerList,
GetCustomerOrders,
GetCustomerWithUser,
Me,
UpdateAddress,
UpdateCustomer,
UpdateCustomerNote,
Expand All @@ -45,6 +46,7 @@ import {
GET_CUSTOMER,
GET_CUSTOMER_HISTORY,
GET_CUSTOMER_LIST,
ME,
UPDATE_ADDRESS,
UPDATE_CUSTOMER,
UPDATE_CUSTOMER_NOTE,
Expand All @@ -64,6 +66,7 @@ let sendEmailFn: jest.Mock;
})
class TestEmailPlugin implements OnModuleInit {
constructor(private eventBus: EventBus) {}

onModuleInit() {
this.eventBus.ofType(AccountRegistrationEvent).subscribe(event => {
sendEmailFn(event);
Expand Down Expand Up @@ -483,6 +486,14 @@ describe('Customer resolver', () => {

expect(updateCustomer.emailAddress).toBe('[email protected]');
});

// https://github.com/vendure-ecommerce/vendure/issues/1071
it('updates the associated User email address', async () => {
await shopClient.asUserWithCredentials('[email protected]', 'test');
const { me } = await shopClient.query<Me.Query>(ME);

expect(me?.identifier).toBe('[email protected]');
});
});

describe('deletion', () => {
Expand Down
22 changes: 19 additions & 3 deletions packages/core/src/service/services/customer.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,10 @@ export class CustomerService {
const hasEmailAddress = (i: any): i is UpdateCustomerInput & { emailAddress: string } =>
Object.hasOwnProperty.call(i, 'emailAddress');

const customer = await this.connection.getEntityOrThrow(ctx, Customer, input.id, {
channelId: ctx.channelId,
});

if (hasEmailAddress(input)) {
const existingCustomerInChannel = await this.connection
.getRepository(ctx, Customer)
Expand All @@ -260,11 +264,23 @@ export class CustomerService {
if (existingCustomerInChannel) {
return new EmailAddressConflictAdminError();
}

if (customer.user) {
const existingUserWithEmailAddress = await this.userService.getUserByEmailAddress(
ctx,
input.emailAddress,
);

if (
existingUserWithEmailAddress &&
!idsAreEqual(customer.user.id, existingUserWithEmailAddress.id)
) {
return new EmailAddressConflictAdminError();
}
await this.userService.changeNativeIdentifier(ctx, customer.user.id, input.emailAddress);
}
}

const customer = await this.connection.getEntityOrThrow(ctx, Customer, input.id, {
channelId: ctx.channelId,
});
const updatedCustomer = patchEntity(customer, input);
await this.connection.getRepository(ctx, Customer).save(updatedCustomer, { reload: false });
await this.customFieldRelationService.updateRelations(ctx, Customer, input, updatedCustomer);
Expand Down
30 changes: 28 additions & 2 deletions packages/core/src/service/services/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ export class UserService {
}
const authenticationMethod = new NativeAuthenticationMethod();
if (this.configService.authOptions.requireVerification) {
authenticationMethod.verificationToken = this.verificationTokenGenerator.generateVerificationToken();
authenticationMethod.verificationToken =
this.verificationTokenGenerator.generateVerificationToken();
user.verified = false;
} else {
user.verified = true;
Expand Down Expand Up @@ -169,7 +170,8 @@ export class UserService {
return;
}
const nativeAuthMethod = user.getNativeAuthenticationMethod();
nativeAuthMethod.passwordResetToken = await this.verificationTokenGenerator.generateVerificationToken();
nativeAuthMethod.passwordResetToken =
await this.verificationTokenGenerator.generateVerificationToken();
await this.connection.getRepository(ctx, NativeAuthenticationMethod).save(nativeAuthMethod);
return user;
}
Expand Down Expand Up @@ -199,6 +201,30 @@ export class UserService {
}
}

/**
* Changes the User identifier without an email verification step, so this should be only used when
* an Administrator is setting a new email address.
*/
async changeNativeIdentifier(ctx: RequestContext, userId: ID, newIdentifier: string) {
const user = await this.getUserById(ctx, userId);
if (!user) {
return;
}
const nativeAuthMethod = user.getNativeAuthenticationMethod();
user.identifier = newIdentifier;
nativeAuthMethod.identifier = newIdentifier;
nativeAuthMethod.identifierChangeToken = null;
nativeAuthMethod.pendingIdentifier = null;
await this.connection
.getRepository(ctx, NativeAuthenticationMethod)
.save(nativeAuthMethod, { reload: false });
await this.connection.getRepository(ctx, User).save(user, { reload: false });
}

/**
* Changes the User identifier as part of the storefront flow used by Customers to set a
* new email address.
*/
async changeIdentifierByToken(
ctx: RequestContext,
token: string,
Expand Down

0 comments on commit 1ebc872

Please sign in to comment.