Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Amplify Gen2: AuthMode Type Mismatch ('userPool' vs 'userPools') Causes Authentication Failures #3083

Open
georgechristman opened this issue Dec 18, 2024 · 2 comments

Comments

@georgechristman
Copy link

georgechristman commented Dec 18, 2024

Environment information

## Environment
System:
  - OS: macOS 15.1.1
  - CPU: (10) arm64 Apple M1 Pro
  - Memory: 133.06 MB / 32.00 GB
  - Shell: /bin/zsh

Binaries:
  - Node: 20.9.0
  - npm: 10.1.0
  - pnpm: 8.10.5

NPM Packages:
  - aws-amplify: 6.10.0
  - @aws-amplify/backend: 1.8.0
  - @aws-amplify/backend-cli: 1.4.2
  - @aws-amplify/backend-data: 1.2.1
  - @aws-amplify/backend-auth: 1.4.1
  - aws-cdk-lib: 2.171.1
  - typescript: 5.7.2

Describe the bug

AuthMode Type Definition Mismatch in Amplify Gen2

Description

There is a type definition mismatch between the runtime implementation and TypeScript types for AuthMode in Amplify Generation 2. The runtime expects 'userPools' (plural) as a valid auth mode, but the TypeScript type definition only includes 'userPool' (singular). This leads to TypeScript errors and potential runtime authentication issues.

Current Behavior

  • TypeScript type AuthMode includes 'userPool' (singular)
  • Runtime implementation expects 'userPools' (plural)
  • This causes type errors when trying to use the correct runtime value
  • When using 'userPool' (as suggested by types), results in authentication errors

Error Details

When attempting to create an order with userPool (as suggested by types):

Error: NoValidAuthTokens: No federated jwt
    at headerBasedAuth (webpack-internal:///(action-browser)/./node_modules/@aws-amplify/api-graphql/dist/esm/internals/graphqlAuth.mjs:49:23)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async GraphQLAPIClass._graphql (webpack-internal:///(action-browser)/./node_modules/@aws-amplify/api-graphql/dist/esm/internals/InternalGraphQLAPI.mjs:150:29)
    at async eval (webpack-internal:///(action-browser)/./node_modules/@aws-amplify/data-schema/dist/esm/runtime/internals/operations/get.mjs:47:42)

Recovery Suggestion: "If you intended to make an authenticated API request, review if the current user is signed in."

Expected Behavior

The TypeScript type definition should match the runtime implementation by including 'userPools' as a valid value for AuthMode, preventing both type errors and runtime authentication issues.

Reproduction Steps

  1. Create a new Amplify Gen2 project
  2. Try to use userPools as the auth mode:
const order = await client.models.Order.create(
  orderData,
  { 
    authMode: 'userPools', // Type error here
    authToken: token 
  }
);
  1. Observe the TypeScript error:
Type '"userPools"' is not assignable to type 'AuthMode | undefined'.
  1. If using 'userPool' as suggested by types, observe the runtime error as well as the [docs]:(https://docs.amplify.aws/react/build-a-backend/data/customize-authz/per-user-per-owner-data-access/)
NoValidAuthTokens: No federated jwt

Current Workaround

Currently, developers need to use type assertions to work around this issue:

authMode: 'userPools' as any

Additional Context

The AuthMode type is currently defined as:

export type AuthMode = 'apiKey' | 'iam' | 'identityPool' | 'oidc' | 'userPool' | 'lambda' | 'none';

This type definition enforces using 'userPool' (singular), but the runtime implementation requires using 'userPools' (plural). When we use the working runtime value 'userPools', TypeScript shows a compilation error because it's not included in the AuthMode type.

This leads to a situation where using the correct runtime value ('userPools') works at runtime but fails TypeScript compilation, forcing developers to use type assertions as a workaround.

Impact

This type mismatch:

  • Forces developers to use type assertions
  • Creates confusion about the correct value to use
  • Reduces type safety by requiring workarounds
  • Can lead to runtime authentication failures when following the type definitions
  • Wastes development time debugging what appears to be an authentication issue but is actually a type definition mismatch

Reproduction steps

Reproduction Steps

  1. Create a new Amplify Gen2 project
  2. Try to use userPool as the auth mode within an NextJS action
//amplifyServerUtils.ts
import { createServerRunner } from '@aws-amplify/adapter-nextjs';
import config from '@/amplify_outputs.json';
import { cookies } from 'next/headers';
import { getCurrentUser, fetchUserAttributes, fetchAuthSession } from 'aws-amplify/auth/server';
import { AuthError, AuthUser } from 'aws-amplify/auth';

export const { runWithAmplifyServerContext } = createServerRunner({
  config,
});

export interface AuthResult {
  user: AuthUser | null;
  isAuthenticated: boolean;
  token?: string;
}

export async function getServerSideUser(): Promise<AuthResult> {
  try {
    const result = await runWithAmplifyServerContext({
      nextServerContext: { cookies },
      operation: async (contextSpec) => {
        const user = await getCurrentUser(contextSpec);
        const session = await fetchAuthSession(contextSpec);
        const token = session.tokens?.idToken?.toString();
        return { user, token };
      },
    });

    return {
      user: result?.user ?? null,
      isAuthenticated: true,
      token: result?.token,
    };
  } catch (error) {
    if (error instanceof AuthError) {
      return {
        user: null,
        isAuthenticated: false,
        token: undefined,
      };
    }

    console.error('Unexpected error in getServerSideUser:', error);
    return {
      user: null,
      isAuthenticated: false,
      token: undefined,
    };
  }
}

// actions.ts
'use server';
export async function submitOrder(orderData: OrderFormData) {
  try {
    const { user, token } = await getServerSideUser();
    
    const order = await client.models.Order.create(
      orderData,
      { 
        authMode: 'userPools', // Type error: not assignable to type 'AuthMode'
        authToken: token 
      }
    );
  } catch (error) {
    console.error('Error:', error);
  }
}
@ykethan
Copy link
Member

ykethan commented Dec 18, 2024

Hey,👋 thanks for raising this! I'm going to transfer this over to our API repository for better assistance 🙂

@ykethan ykethan transferred this issue from aws-amplify/amplify-backend Dec 18, 2024
@Siqi-Shan
Copy link
Member

Hey @ykethan, thanks for raising the issue! We'll investigate and see what's going on there, and get to back to you for next steps

@chrisbonifacio chrisbonifacio self-assigned this Dec 18, 2024
@chrisbonifacio chrisbonifacio added to-be-reproduced Pending reproduction and removed pending-triage labels Dec 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants