Skip to content

Commit

Permalink
fix(core): Fix admin authentication when no native auth in shop API
Browse files Browse the repository at this point in the history
Fixes #2282
  • Loading branch information
michaelbromley committed Jul 13, 2023
1 parent 120a0bb commit 8fb9719
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 37 deletions.
55 changes: 47 additions & 8 deletions packages/core/e2e/authentication-strategy.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(), {
Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -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) {
Expand Down
15 changes: 14 additions & 1 deletion packages/core/src/api/resolvers/admin/auth.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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();
}
}
}
29 changes: 2 additions & 27 deletions packages/core/src/api/resolvers/base/base-auth.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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
Expand Down Expand Up @@ -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();
}
}
}
14 changes: 13 additions & 1 deletion packages/core/src/api/resolvers/shop/shop-auth.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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();
}
}
}

0 comments on commit 8fb9719

Please sign in to comment.