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

impersonation code breaks the build #80

Open
dror-trail opened this issue Sep 1, 2024 · 9 comments · May be fixed by #147
Open

impersonation code breaks the build #80

dror-trail opened this issue Sep 1, 2024 · 9 comments · May be fixed by #147

Comments

@dror-trail
Copy link

using Next.js (14.2.5) + "@workos-inc/authkit-nextjs": "^0.9.0"
i dont use the impersonation component but it still breaks

      Error: ./node_modules/@workos-inc/authkit-nextjs/dist/cjs/impersonation.js:54:21
      Ecmascript file had an error
        52 |             } },
        53 |             React.createElement("form", { action: async () => {
      > 54 |                     'use server';
           |                     ^^^^^^^^^^^^
        55 |                     await (0, auth_js_1.signOut)();
        56 |                 }, style: {
        57 |                     display: 'flex',
      
      It is not allowed to define inline "use server" annotated Server Actions in Client Components.
      To use Server Actions in a Client Component, you can either export them from a separate file with "use server" at the top, or pass them down through props from a Server Component.
@PaulAsjes
Copy link
Collaborator

I'm unable to reproduce with both Next.js 14.2.5 and authkit-next 0.9.0. Could you provide more details or an example repo that shows the issue?

@MHendrieAIOT
Copy link

I'm having this same problem. I need to use signOut() in an onClick event handler (outside of a form) and I haven't been able to get it to work.

Some minimal code that throws this error for me:

"use client"
import { signOut } from "@workos-inc/authkit-nextjs";
export default async function Example() {
  return (
    <button onClick={async () => await signOut()}>Sign out</button>
  );
}

The error still occurs if I extract the signOut call to a server action in a separate file and import it in my client component.

@PaulAsjes
Copy link
Collaborator

Hi all, we've found that the issue only appears in client components. We're working on a fix, but in the meanwhile for client components you should be able to treat signOut and signIn as a server function:

"use client"
import { signOut } from "@workos-inc/authkit-nextjs";
export default async function Example() {
  return (
    <button onClick={signOut}>Sign out</button>
  );
}

Impersonation and AuthKitProvider won't currently work in client components, but we're working on a fix.

@kmankan
Copy link

kmankan commented Nov 17, 2024

is there a solution for this yet? this means a bunch of client side function like withAuth don't work either... that's pretty important.

@PaulAsjes PaulAsjes linked a pull request Dec 10, 2024 that will close this issue
@monolithed
Copy link

monolithed commented Jan 1, 2025

I can't check the behavior in the latest version because it's broken. In version 0.16.2, when calling in a server or client component, the following error occurs:

Screenshot 2025-01-02 at 01 25 33

@PaulAsjes
Copy link
Collaborator

Hi all, I have a PR open (#147) that should fix this issue. Hoping to get it released next week.

@monolithed Are you using middleware auth mode and have devtools open by chance? I've seen this error occur when the browser tries to fetch source maps when the console is open. Those requests get blocked by the middleware in middleware auth mode.

@monolithed
Copy link

monolithed commented Jan 2, 2025

@PaulAsjes, I get this error regardless of whether devtools are open or closed. I initially saw it on use client, but after switching the page to use server, nothing changed. I followed the instructions: added the middleware, provider, and called the function.
I can't reproduce this in the example repository, maybe it's related to how I’m using the middleware and how I'm building the render. My middleware looks like this:

middlewares/combine.ts

import {NextFetchEvent, NextRequest, NextResponse} from 'next/server';
import type {NextMiddlewareResult} from 'next/dist/server/web/types';

type CustomMiddleware = (
    request: NextRequest,
    event: NextFetchEvent,
    response: NextResponse
) => NextMiddlewareResult | Promise<NextMiddlewareResult>;

type MiddlewareFactory = (middleware: CustomMiddleware) => CustomMiddleware;

const combineMiddleware = (middleware: MiddlewareFactory[] = [], index = 0): CustomMiddleware => {
    const current = middleware[index];

    if (current) {
        const next = combineMiddleware(middleware, index + 1);

        return current(next);
    }

    return (request, event, response) => response;
};

export {combineMiddleware};
export type {CustomMiddleware, MiddlewareFactory};

middlewares/with-auth-middleware.ts

import {NextResponse} from 'next/server';

import {authkitMiddleware, getSession} from '@workos-inc/authkit-nextjs';
import type {MiddlewareFactory} from '@/middlewares/combine';

const withAuthMiddleware: MiddlewareFactory = (middleware) => {
       return async (request, event, response) => {

        try {
            const authResponse = await authkitMiddleware({
                debug: true,
                middlewareAuth: {
                    enabled: true,
                    unauthenticatedPaths: ['/'],
                },
            })(request, event);

            const session = await getSession();

            if (!session) {
                const url = new URL('/sign-in', request.url);

                return NextResponse.redirect(url);
            }
        }
        catch (error) {
            console.error('Auth error:', error);
        }

        if (response) {
            return middleware(request, event, response);
        }

        return response;
    };
};

export {withAuthMiddleware};

middleware.ts

import {combineMiddleware} from '@/middlewares/combine';
import {withAuthMiddleware} from '@/middlewares/with-auth-middleware';

const middleware = combineMiddleware([
    withAuthMiddleware
]);

export const config = {
    matcher: ['/((?!api|static|.*\\..*|_next).*)']
};

export {middleware};

I also want to point out that in the root component, I have the following flag set:

export const dynamic = 'force-static';

Will it be possible to integrate Magic Auth after PR #147 is merged?

@PaulAsjes
Copy link
Collaborator

@monolithed For your first question, you don't appear to be setting your Next.js config anywhere in your middleware. See the readme for how to create a matcher.

In terms of Magic Auth, AuthKit supports it natively. You might need to configure your WorkOS settings if you don't see it show up when attempting to log in with AuthKit.

@monolithed
Copy link

@monolithed For your first question, you don't appear to be setting your Next.js config anywhere in your middleware. See the readme for how to create a matcher.

@PaulAsjes, nevertheless, other middlewares are working for me 😄
The example in the documentation suggests that only one middleware will be used, but in real applications, there are usually more. It's possible that I've made an error when passing parameters, which I will debug further. However, if it's not too much trouble, could you show me an example of how to properly call authkitMiddleware when other middlewares are also present?

In terms of Magic Auth, AuthKit supports it natively. You might need to configure your WorkOS settings if you don't see it show up when attempting to log in with AuthKit.

Yeah, I’ve already figured it out. Now I’m trying to find the setting to disable sending the code to the email so I can handle it myself. But that's a completely different question ))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

5 participants