Customer Accounts
Customers can register accounts and thereby gain the ability to:
- View past orders
- Store multiple addresses
- Maintain an active order across devices
- Take advantage of plugins that expose functionality to registered customers only, such as wishlists & loyalty points.
Querying the active customer
The activeCustomer
query will return a Customer
object if the customer is registered and logged in, otherwise it will return null
. This can be used in the storefront header for example to
determine whether to display a "sign in" or "my account" link.
- Query
- Result
query GetCustomerAddresses {
activeCustomer {
id
title
firstName
lastName
emailAddress
}
}
{
"data": {
"activeCustomer": {
"id": "12345",
"title": "Mr.",
"firstName": "John",
"lastName": "Doe",
"emailAddress": "john.doe@email.com"
}
}
}
Logging in and out
The login
mutation is used to attempt to log in using email address and password.
Given correct credentials, a new authenticated session will begin for that customer.
- Query
- Variables
- Result
mutation LogIn($emailAddress: String!, $password: String!, $rememberMe: Boolean!) {
login(username: $emailAddress, password: $password, rememberMe: $rememberMe) {
... on CurrentUser {
id
identifier
}
... on ErrorResult {
errorCode
message
}
}
}
{
"emailAddress": "john.doe@email.com",
"password": "**********",
"rememberMe": true,
}
{
"data": {
"login": {
"id": "12345",
"identifier": "john.doe@email.com"
}
}
}
The logout
mutation will end an authenticated customer session.
- Query
- Result
mutation LogOut {
logout {
success
}
}
{
"data": {
"logout": {
"success": true,
}
}
}
The login
mutation, as well as the following mutations related to registration & password recovery only
apply when using the built-in NativeAuthenticationStrategy
.
If you are using alternative authentication strategies in your storefront, you would use the authenticate
mutation as covered in the External Authentication guide.
Registering a customer account
The registerCustomerAccount
mutation is used to register a new customer account.
There are three possible registration flows:
If authOptions.requireVerification
is set to true
(the default):
- The Customer is registered with a password. A verificationToken will be created (and typically emailed to the Customer). That verificationToken would then be passed to the verifyCustomerAccount mutation without a password. The Customer is then verified and authenticated in one step.
- The Customer is registered without a password. A verificationToken will be created (and typically emailed to the Customer). That verificationToken would then be passed to the verifyCustomerAccount mutation with the chosen password of the Customer. The Customer is then verified and authenticated in one step.
If authOptions.requireVerification
is set to false
:
- The Customer must be registered with a password. No further action is needed - the Customer is able to authenticate immediately.
Here's a diagram of the second scenario, where the password is supplied during the verification step.
Here's how the mutations would look for the above flow:
- Mutation
- Variables
- Result
mutation Register($input: RegisterCustomerInput!) {
registerCustomerAccount(input: $input) {
... on Success {
success
}
...on ErrorResult {
errorCode
message
}
}
}
{
"input: {
"title": "Mr."
"firstName": "Nicky",
"lastName": "Wire",
"emailAddress": "nicky@example.com",
"phoneNumber": "1234567",
}
}
{
"data": {
"registerCustomerAccount": {
"success": true,
}
}
}
Note that in the variables above, we did not specify a password, as this will be done at the verification step. If a password does get passed at this step, then it won't be needed at the verification step. This is a decision you can make based on the desired user experience of your storefront.
Upon registration, the EmailPlugin will generate an email to the customer containing a link to the verification page. In a default Vendure installation this is set in the vendure config file:
EmailPlugin.init({
route: 'mailbox',
handlers: defaultEmailHandlers,
templatePath: path.join(__dirname, '../static/email/templates'),
outputPath: path.join(__dirname, '../static/email/output'),
globalTemplateVars: {
fromAddress: '"Vendure Demo Store" <noreply@vendure.io>',
verifyEmailAddressUrl: 'https://demo.vendure.io/storefront/account/verify',
passwordResetUrl: 'https://demo.vendure.io/storefront/account/reset-password',
changeEmailAddressUrl: 'https://demo.vendure.io/storefront/account/change-email-address'
},
devMode: true,
}),
The verification page needs to get the token from the query string, and pass it to the verifyCustomerAccount
mutation:
- Mutation
- Variables
- Result
mutation Verify($password: String!, $token: String!) {
verifyCustomerAccount(password: $password, token: $token) {
...on CurrentUser {
id
identifier
}
...on ErrorResult {
errorCode
message
}
}
}
{
"password": "*********",
"token": "MjAxOS0xMC0wMlQxNToxOTo1NC45NDVa_1DYEWYAB7S3S82JT"
}
{
"data": {
"verifyCustomerAccount": {
"id": "123",
"identifier": "nicky@example.com"
}
}
}
Password reset
Here's how to implement a password reset flow. It is conceptually very similar to the verification flow described above.
A password reset is triggered by the requestPasswordReset
mutation:
- Mutation
- Variables
- Result
mutation RequestPasswordReset($emailAddress: String!) {
requestPasswordReset(emailAddress: $emailAddress) {
... on Success {
success
}
... on ErrorResult {
errorCode
message
}
}
}
{
"emailAddress": "nicky@example.com",
}
{
"data": {
"requestPasswordReset": {
"success": true,
}
}
}
Again, this mutation will trigger an event which the EmailPlugin's default email handlers will pick up and send
an email to the customer. The password reset page then needs to get the token from the url and pass it to the
resetPassword
mutation:
- Mutation
- Variables
- Result
mutation ResetPassword($token: String! $password: String!) {
resetPassword(token: $token password: $password) {
...on CurrentUser {
id
identifier
}
... on ErrorResult {
errorCode
message
}
}
}
{
"token": "MjAxOS0xMC0wMlQxNToxOTo1NC45NDVa_1DYEWYAB7S3S82JT",
"password": "************"
}
{
"data": {
"resetPassword": {
"id": "123",
"identifier": "nicky@example.com"
}
}
}