Răsfoiți Sursa

fix(core): Fix admin authentication when no native auth in shop API

Fixes #2282
Michael Bromley 2 ani în urmă
părinte
comite
8fb9719213

+ 47 - 8
packages/core/e2e/authentication-strategy.e2e-spec.ts

@@ -18,12 +18,24 @@ import {
     VALID_AUTH_TOKEN,
 } from './fixtures/test-authentication-strategies';
 import { CURRENT_USER_FRAGMENT } from './graphql/fragments';
-import { CurrentUserFragment, CustomerFragment, HistoryEntryType } from './graphql/generated-e2e-admin-types';
+import {
+    AttemptLoginDocument,
+    CurrentUserFragment,
+    CustomerFragment,
+    HistoryEntryType,
+} from './graphql/generated-e2e-admin-types';
 import * as Codegen from './graphql/generated-e2e-admin-types';
 import { RegisterMutation, RegisterMutationVariables } from './graphql/generated-e2e-shop-types';
 import { CREATE_CUSTOMER, DELETE_CUSTOMER, GET_CUSTOMER_HISTORY, ME } from './graphql/shared-definitions';
 import { REGISTER_ACCOUNT } from './graphql/shop-definitions';
 
+const currentUserGuard: ErrorResultGuard<CurrentUserFragment> = createErrorResultGuard(
+    input => input.identifier != null,
+);
+const customerGuard: ErrorResultGuard<CustomerFragment> = createErrorResultGuard(
+    input => input.emailAddress != null,
+);
+
 describe('AuthenticationStrategy', () => {
     const { server, adminClient, shopClient } = createTestEnvironment(
         mergeConfig(testConfig(), {
@@ -52,13 +64,6 @@ describe('AuthenticationStrategy', () => {
         await server.destroy();
     });
 
-    const currentUserGuard: ErrorResultGuard<CurrentUserFragment> = createErrorResultGuard(
-        input => input.identifier != null,
-    );
-    const customerGuard: ErrorResultGuard<CustomerFragment> = createErrorResultGuard(
-        input => input.emailAddress != null,
-    );
-
     describe('external auth', () => {
         const userData = {
             email: 'test@email.com',
@@ -386,6 +391,40 @@ describe('AuthenticationStrategy', () => {
     });
 });
 
+describe('No NativeAuthStrategy on Shop API', () => {
+    const { server, adminClient, shopClient } = createTestEnvironment(
+        mergeConfig(testConfig(), {
+            authOptions: {
+                shopAuthenticationStrategy: [new TestAuthenticationStrategy()],
+            },
+        }),
+    );
+
+    beforeAll(async () => {
+        await server.init({
+            initialData,
+            productsCsvPath: path.join(__dirname, 'fixtures/e2e-products-minimal.csv'),
+            customerCount: 1,
+        });
+        await adminClient.asSuperAdmin();
+    }, TEST_SETUP_TIMEOUT_MS);
+
+    afterAll(async () => {
+        await server.destroy();
+    });
+
+    // https://github.com/vendure-ecommerce/vendure/issues/2282
+    it('can log in to Admin API', async () => {
+        const { login } = await adminClient.query(AttemptLoginDocument, {
+            username: 'superadmin',
+            password: 'superadmin',
+        });
+
+        currentUserGuard.assertSuccess(login);
+        expect(login.identifier).toBe('superadmin');
+    });
+});
+
 const AUTHENTICATE = gql`
     mutation Authenticate($input: AuthenticationInput!) {
         authenticate(input: $input) {

+ 14 - 1
packages/core/src/api/resolvers/admin/auth.resolver.ts

@@ -10,7 +10,9 @@ import {
 import { Request, Response } from 'express';
 
 import { NativeAuthStrategyError } from '../../../common/error/generated-graphql-admin-errors';
+import { NATIVE_AUTH_STRATEGY_NAME } from '../../../config/auth/native-authentication-strategy';
 import { ConfigService } from '../../../config/config.service';
+import { Logger } from '../../../config/logger/vendure-logger';
 import { AdministratorService } from '../../../service/services/administrator.service';
 import { AuthService } from '../../../service/services/auth.service';
 import { ChannelService } from '../../../service/services/channel.service';
@@ -79,6 +81,17 @@ export class AuthResolver extends BaseAuthResolver {
     }
 
     protected requireNativeAuthStrategy() {
-        return super.requireNativeAuthStrategy() as NativeAuthStrategyError | undefined;
+        const { adminAuthenticationStrategy } = this.configService.authOptions;
+        const nativeAuthStrategyIsConfigured = !!adminAuthenticationStrategy.find(
+            strategy => strategy.name === NATIVE_AUTH_STRATEGY_NAME,
+        );
+        if (!nativeAuthStrategyIsConfigured) {
+            const authStrategyNames = adminAuthenticationStrategy.map(s => s.name).join(', ');
+            const errorMessage =
+                'This GraphQL operation requires that the NativeAuthenticationStrategy be configured for the Admin API.\n' +
+                `Currently the following AuthenticationStrategies are enabled: ${authStrategyNames}`;
+            Logger.error(errorMessage);
+            return new NativeAuthStrategyError();
+        }
     }
 }

+ 2 - 27
packages/core/src/api/resolvers/base/base-auth.resolver.ts

@@ -14,15 +14,13 @@ import { Request, Response } from 'express';
 
 import { isGraphQlErrorResult } from '../../../common/error/error-result';
 import { ForbiddenError } from '../../../common/error/errors';
-import { NativeAuthStrategyError as AdminNativeAuthStrategyError } from '../../../common/error/generated-graphql-admin-errors';
 import {
     InvalidCredentialsError,
-    NativeAuthStrategyError as ShopNativeAuthStrategyError,
     NotVerifiedError,
 } from '../../../common/error/generated-graphql-shop-errors';
 import { NATIVE_AUTH_STRATEGY_NAME } from '../../../config/auth/native-authentication-strategy';
 import { ConfigService } from '../../../config/config.service';
-import { Logger, LogLevel } from '../../../config/logger/vendure-logger';
+import { LogLevel } from '../../../config/logger/vendure-logger';
 import { User } from '../../../entity/user/user.entity';
 import { getUserChannelsPermissions } from '../../../service/helpers/utils/get-user-channels-permissions';
 import { AdministratorService } from '../../../service/services/administrator.service';
@@ -34,19 +32,12 @@ import { RequestContext } from '../../common/request-context';
 import { setSessionToken } from '../../common/set-session-token';
 
 export class BaseAuthResolver {
-    protected readonly nativeAuthStrategyIsConfigured: boolean;
-
     constructor(
         protected authService: AuthService,
         protected userService: UserService,
         protected administratorService: AdministratorService,
         protected configService: ConfigService,
-    ) {
-        this.nativeAuthStrategyIsConfigured =
-            !!this.configService.authOptions.shopAuthenticationStrategy.find(
-                strategy => strategy.name === NATIVE_AUTH_STRATEGY_NAME,
-            );
-    }
+    ) {}
 
     /**
      * Attempts a login given the username and password of a user. If successful, returns
@@ -159,20 +150,4 @@ export class BaseAuthResolver {
             channels: getUserChannelsPermissions(user) as CurrentUserChannel[],
         };
     }
-
-    protected requireNativeAuthStrategy():
-        | AdminNativeAuthStrategyError
-        | ShopNativeAuthStrategyError
-        | undefined {
-        if (!this.nativeAuthStrategyIsConfigured) {
-            const authStrategyNames = this.configService.authOptions.shopAuthenticationStrategy
-                .map(s => s.name)
-                .join(', ');
-            const errorMessage =
-                'This GraphQL operation requires that the NativeAuthenticationStrategy be configured for the Shop API.\n' +
-                `Currently the following AuthenticationStrategies are enabled: ${authStrategyNames}`;
-            Logger.error(errorMessage);
-            return new AdminNativeAuthStrategyError();
-        }
-    }
 }

+ 13 - 1
packages/core/src/api/resolvers/shop/shop-auth.resolver.ts

@@ -34,6 +34,7 @@ import { ForbiddenError } from '../../../common/error/errors';
 import { NativeAuthStrategyError } from '../../../common/error/generated-graphql-shop-errors';
 import { NATIVE_AUTH_STRATEGY_NAME } from '../../../config/auth/native-authentication-strategy';
 import { ConfigService } from '../../../config/config.service';
+import { Logger } from '../../../config/logger/vendure-logger';
 import { AdministratorService } from '../../../service/services/administrator.service';
 import { AuthService } from '../../../service/services/auth.service';
 import { CustomerService } from '../../../service/services/customer.service';
@@ -326,6 +327,17 @@ export class ShopAuthResolver extends BaseAuthResolver {
     }
 
     protected requireNativeAuthStrategy() {
-        return super.requireNativeAuthStrategy() as NativeAuthStrategyError | undefined;
+        const { shopAuthenticationStrategy } = this.configService.authOptions;
+        const nativeAuthStrategyIsConfigured = !!shopAuthenticationStrategy.find(
+            strategy => strategy.name === NATIVE_AUTH_STRATEGY_NAME,
+        );
+        if (!nativeAuthStrategyIsConfigured) {
+            const authStrategyNames = shopAuthenticationStrategy.map(s => s.name).join(', ');
+            const errorMessage =
+                'This GraphQL operation requires that the NativeAuthenticationStrategy be configured for the Shop API.\n' +
+                `Currently the following AuthenticationStrategies are enabled: ${authStrategyNames}`;
+            Logger.error(errorMessage);
+            return new NativeAuthStrategyError();
+        }
     }
 }