authentication-strategy.e2e-spec.ts 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. import { pick } from '@vendure/common/lib/pick';
  2. import { mergeConfig } from '@vendure/core';
  3. import { createErrorResultGuard, createTestEnvironment, ErrorResultGuard } from '@vendure/testing';
  4. import gql from 'graphql-tag';
  5. import path from 'path';
  6. import { initialData } from '../../../e2e-common/e2e-initial-data';
  7. import { TEST_SETUP_TIMEOUT_MS, testConfig } from '../../../e2e-common/test-config';
  8. import { NativeAuthenticationStrategy } from '../src/config/auth/native-authentication-strategy';
  9. import { DefaultLogger } from '../src/config/logger/default-logger';
  10. import { TestAuthenticationStrategy, VALID_AUTH_TOKEN } from './fixtures/test-authentication-strategies';
  11. import {
  12. Authenticate,
  13. GetCustomerHistory,
  14. GetCustomers,
  15. GetCustomerUserAuth,
  16. HistoryEntryType,
  17. Me,
  18. } from './graphql/generated-e2e-admin-types';
  19. import { Register } from './graphql/generated-e2e-shop-types';
  20. import { GET_CUSTOMER_HISTORY, ME } from './graphql/shared-definitions';
  21. import { REGISTER_ACCOUNT } from './graphql/shop-definitions';
  22. import { assertThrowsWithMessage } from './utils/assert-throws-with-message';
  23. describe('AuthenticationStrategy', () => {
  24. const { server, adminClient, shopClient } = createTestEnvironment(
  25. mergeConfig(testConfig, {
  26. authOptions: {
  27. shopAuthenticationStrategy: [
  28. new NativeAuthenticationStrategy(),
  29. new TestAuthenticationStrategy(),
  30. ],
  31. },
  32. }),
  33. );
  34. beforeAll(async () => {
  35. await server.init({
  36. initialData,
  37. productsCsvPath: path.join(__dirname, 'fixtures/e2e-products-minimal.csv'),
  38. customerCount: 1,
  39. });
  40. await adminClient.asSuperAdmin();
  41. }, TEST_SETUP_TIMEOUT_MS);
  42. afterAll(async () => {
  43. await server.destroy();
  44. });
  45. describe('external auth', () => {
  46. const userData = {
  47. email: 'test@email.com',
  48. firstName: 'Cixin',
  49. lastName: 'Liu',
  50. };
  51. let newCustomerId: string;
  52. it(
  53. 'fails with a bad token',
  54. assertThrowsWithMessage(async () => {
  55. await shopClient.query(AUTHENTICATE, {
  56. input: {
  57. test_strategy: {
  58. token: 'bad-token',
  59. },
  60. },
  61. });
  62. }, 'The credentials did not match. Please check and try again'),
  63. );
  64. it('creates a new Customer with valid token', async () => {
  65. const { customers: before } = await adminClient.query<GetCustomers.Query>(GET_CUSTOMERS);
  66. expect(before.totalItems).toBe(1);
  67. const result = await shopClient.query<Authenticate.Mutation>(AUTHENTICATE, {
  68. input: {
  69. test_strategy: {
  70. token: VALID_AUTH_TOKEN,
  71. userData,
  72. },
  73. },
  74. });
  75. expect(result.authenticate.user.identifier).toEqual(userData.email);
  76. const { customers: after } = await adminClient.query<GetCustomers.Query>(GET_CUSTOMERS);
  77. expect(after.totalItems).toBe(2);
  78. expect(after.items.map(i => i.emailAddress)).toEqual([
  79. 'hayden.zieme12@hotmail.com',
  80. userData.email,
  81. ]);
  82. newCustomerId = after.items[1].id;
  83. });
  84. it('creates customer history entry', async () => {
  85. const { customer } = await adminClient.query<
  86. GetCustomerHistory.Query,
  87. GetCustomerHistory.Variables
  88. >(GET_CUSTOMER_HISTORY, {
  89. id: newCustomerId,
  90. });
  91. expect(
  92. customer?.history.items.sort((a, b) => (a.id > b.id ? 1 : -1)).map(pick(['type', 'data'])),
  93. ).toEqual([
  94. {
  95. type: HistoryEntryType.CUSTOMER_REGISTERED,
  96. data: {
  97. strategy: 'test_strategy',
  98. },
  99. },
  100. {
  101. type: HistoryEntryType.CUSTOMER_VERIFIED,
  102. data: {
  103. strategy: 'test_strategy',
  104. },
  105. },
  106. ]);
  107. });
  108. it('user authenticationMethod populated', async () => {
  109. const { customer } = await adminClient.query<
  110. GetCustomerUserAuth.Query,
  111. GetCustomerUserAuth.Variables
  112. >(GET_CUSTOMER_USER_AUTH, {
  113. id: newCustomerId,
  114. });
  115. expect(customer?.user?.authenticationMethods.length).toBe(1);
  116. expect(customer?.user?.authenticationMethods[0].strategy).toBe('test_strategy');
  117. });
  118. it('creates authenticated session', async () => {
  119. const { me } = await shopClient.query<Me.Query>(ME);
  120. expect(me?.identifier).toBe(userData.email);
  121. });
  122. it('log out', async () => {
  123. await shopClient.asAnonymousUser();
  124. });
  125. it('logging in again re-uses created User & Customer', async () => {
  126. const result = await shopClient.query<Authenticate.Mutation>(AUTHENTICATE, {
  127. input: {
  128. test_strategy: {
  129. token: VALID_AUTH_TOKEN,
  130. userData,
  131. },
  132. },
  133. });
  134. expect(result.authenticate.user.identifier).toEqual(userData.email);
  135. const { customers: after } = await adminClient.query<GetCustomers.Query>(GET_CUSTOMERS);
  136. expect(after.totalItems).toBe(2);
  137. expect(after.items.map(i => i.emailAddress)).toEqual([
  138. 'hayden.zieme12@hotmail.com',
  139. userData.email,
  140. ]);
  141. });
  142. it('registerCustomerAccount with external email', async () => {
  143. const successErrorGuard: ErrorResultGuard<{ success: boolean }> = createErrorResultGuard<{
  144. success: boolean;
  145. }>(input => input.success != null);
  146. const { registerCustomerAccount } = await shopClient.query<Register.Mutation, Register.Variables>(
  147. REGISTER_ACCOUNT,
  148. {
  149. input: {
  150. emailAddress: userData.email,
  151. },
  152. },
  153. );
  154. successErrorGuard.assertSuccess(registerCustomerAccount);
  155. expect(registerCustomerAccount.success).toBe(true);
  156. const { customer } = await adminClient.query<
  157. GetCustomerUserAuth.Query,
  158. GetCustomerUserAuth.Variables
  159. >(GET_CUSTOMER_USER_AUTH, {
  160. id: newCustomerId,
  161. });
  162. expect(customer?.user?.authenticationMethods.length).toBe(2);
  163. expect(customer?.user?.authenticationMethods[1].strategy).toBe('native');
  164. const { customer: customer2 } = await adminClient.query<
  165. GetCustomerHistory.Query,
  166. GetCustomerHistory.Variables
  167. >(GET_CUSTOMER_HISTORY, {
  168. id: newCustomerId,
  169. options: {
  170. skip: 2,
  171. },
  172. });
  173. expect(customer2?.history.items.map(pick(['type', 'data']))).toEqual([
  174. {
  175. type: HistoryEntryType.CUSTOMER_REGISTERED,
  176. data: {
  177. strategy: 'native',
  178. },
  179. },
  180. ]);
  181. });
  182. });
  183. });
  184. const AUTHENTICATE = gql`
  185. mutation Authenticate($input: AuthenticationInput!) {
  186. authenticate(input: $input) {
  187. user {
  188. id
  189. identifier
  190. }
  191. }
  192. }
  193. `;
  194. const GET_CUSTOMERS = gql`
  195. query GetCustomers {
  196. customers {
  197. totalItems
  198. items {
  199. id
  200. emailAddress
  201. }
  202. }
  203. }
  204. `;
  205. const GET_CUSTOMER_USER_AUTH = gql`
  206. query GetCustomerUserAuth($id: ID!) {
  207. customer(id: $id) {
  208. id
  209. user {
  210. id
  211. verified
  212. authenticationMethods {
  213. id
  214. strategy
  215. }
  216. }
  217. }
  218. }
  219. `;