auth.e2e-spec.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. import { SUPER_ADMIN_USER_IDENTIFIER, SUPER_ADMIN_USER_PASSWORD } from '@vendure/common/lib/shared-constants';
  2. import { DocumentNode } from 'graphql';
  3. import gql from 'graphql-tag';
  4. import path from 'path';
  5. import { TEST_SETUP_TIMEOUT_MS } from './config/test-config';
  6. import {
  7. CreateAdministrator,
  8. CreateRole,
  9. MutationCreateProductArgs,
  10. MutationLoginArgs,
  11. MutationUpdateProductArgs,
  12. Permission,
  13. } from './graphql/generated-e2e-admin-types';
  14. import { ATTEMPT_LOGIN, CREATE_ADMINISTRATOR, CREATE_PRODUCT, CREATE_ROLE, GET_PRODUCT_LIST, UPDATE_PRODUCT } from './graphql/shared-definitions';
  15. import { TestAdminClient } from './test-client';
  16. import { TestServer } from './test-server';
  17. describe('Authorization & permissions', () => {
  18. const client = new TestAdminClient();
  19. const server = new TestServer();
  20. beforeAll(async () => {
  21. const token = await server.init({
  22. productsCsvPath: path.join(__dirname, 'fixtures/e2e-products-minimal.csv'),
  23. customerCount: 1,
  24. });
  25. await client.init();
  26. }, TEST_SETUP_TIMEOUT_MS);
  27. afterAll(async () => {
  28. await server.destroy();
  29. });
  30. describe('admin permissions', () => {
  31. describe('Anonymous user', () => {
  32. beforeAll(async () => {
  33. await client.asAnonymousUser();
  34. });
  35. it('can attempt login', async () => {
  36. await assertRequestAllowed<MutationLoginArgs>(ATTEMPT_LOGIN, {
  37. username: SUPER_ADMIN_USER_IDENTIFIER,
  38. password: SUPER_ADMIN_USER_PASSWORD,
  39. rememberMe: false,
  40. });
  41. });
  42. });
  43. describe('ReadCatalog', () => {
  44. beforeAll(async () => {
  45. await client.asSuperAdmin();
  46. const { identifier, password } = await createAdministratorWithPermissions('ReadCatalog', [
  47. Permission.ReadCatalog,
  48. ]);
  49. await client.asUserWithCredentials(identifier, password);
  50. });
  51. it('can read', async () => {
  52. await assertRequestAllowed(GET_PRODUCT_LIST);
  53. });
  54. it('cannot uppdate', async () => {
  55. await assertRequestForbidden<MutationUpdateProductArgs>(UPDATE_PRODUCT, {
  56. input: {
  57. id: '1',
  58. translations: [],
  59. },
  60. });
  61. });
  62. it('cannot create', async () => {
  63. await assertRequestForbidden<MutationCreateProductArgs>(CREATE_PRODUCT, {
  64. input: {
  65. translations: [],
  66. },
  67. });
  68. });
  69. });
  70. describe('CRUD on Customers', () => {
  71. beforeAll(async () => {
  72. await client.asSuperAdmin();
  73. const { identifier, password } = await createAdministratorWithPermissions('CRUDCustomer', [
  74. Permission.CreateCustomer,
  75. Permission.ReadCustomer,
  76. Permission.UpdateCustomer,
  77. Permission.DeleteCustomer,
  78. ]);
  79. await client.asUserWithCredentials(identifier, password);
  80. });
  81. it('can create', async () => {
  82. await assertRequestAllowed(
  83. gql`
  84. mutation CreateCustomer($input: CreateCustomerInput!) {
  85. createCustomer(input: $input) {
  86. id
  87. }
  88. }
  89. `,
  90. { input: { emailAddress: '', firstName: '', lastName: '' } },
  91. );
  92. });
  93. it('can read', async () => {
  94. await assertRequestAllowed(gql`
  95. query GetCustomerCount {
  96. customers {
  97. totalItems
  98. }
  99. }
  100. `);
  101. });
  102. });
  103. });
  104. async function assertRequestAllowed<V>(operation: DocumentNode, variables?: V) {
  105. try {
  106. const status = await client.queryStatus(operation, variables);
  107. expect(status).toBe(200);
  108. } catch (e) {
  109. const errorCode = getErrorCode(e);
  110. if (!errorCode) {
  111. fail(`Unexpected failure: ${e}`);
  112. } else {
  113. fail(`Operation should be allowed, got status ${getErrorCode(e)}`);
  114. }
  115. }
  116. }
  117. async function assertRequestForbidden<V>(operation: DocumentNode, variables: V) {
  118. try {
  119. const status = await client.query(operation, variables);
  120. fail(`Should have thrown`);
  121. } catch (e) {
  122. expect(getErrorCode(e)).toBe('FORBIDDEN');
  123. }
  124. }
  125. function getErrorCode(err: any): string {
  126. return err.response.errors[0].extensions.code;
  127. }
  128. async function createAdministratorWithPermissions(
  129. code: string,
  130. permissions: Permission[],
  131. ): Promise<{ identifier: string; password: string }> {
  132. const roleResult = await client.query<CreateRole.Mutation, CreateRole.Variables>(CREATE_ROLE, {
  133. input: {
  134. code,
  135. description: '',
  136. permissions,
  137. },
  138. });
  139. const role = roleResult.createRole;
  140. const identifier = `${code}@${Math.random()
  141. .toString(16)
  142. .substr(2, 8)}`;
  143. const password = `test`;
  144. const adminResult = await client.query<CreateAdministrator.Mutation, CreateAdministrator.Variables>(
  145. CREATE_ADMINISTRATOR,
  146. {
  147. input: {
  148. emailAddress: identifier,
  149. firstName: code,
  150. lastName: 'Admin',
  151. password,
  152. roleIds: [role.id],
  153. },
  154. },
  155. );
  156. const admin = adminResult.createAdministrator;
  157. return {
  158. identifier,
  159. password,
  160. };
  161. }
  162. });