Help integrating with NestJS #149

Closed
opened 2026-03-13 07:35:21 -05:00 by GiteaMirror · 26 comments
Owner

Originally created by @iamstarcode on GitHub (Oct 28, 2024).

Given how NestJs handles route handling(not been handled directly by route handlers). How can we use the toNodeHandler to make Better Auth handle request in a NestJs app.

Originally created by @iamstarcode on GitHub (Oct 28, 2024). Given how NestJs handles route handling(not been handled directly by route handlers). How can we use the `toNodeHandler` to make Better Auth handle request in a NestJs app.
Author
Owner

@ghost commented on GitHub (Oct 29, 2024):

I haven't tested what I'm about to suggest in a real app, but I have tested it with boilerplate nestjs code, and the route handling works correctly.

I've setup a repo for you to check out what I did

Here's a screenshot to show you that the handler is setup correctly upon running the nest start script
image

You can also visit http://localhost:3000/api/auth/ok and if you get the following response, then it's working:

{
  "ok": true
}
@ghost commented on GitHub (Oct 29, 2024): I haven't tested what I'm about to suggest in a real app, but I have tested it with boilerplate nestjs code, and the route handling works correctly. I've setup a [repo](https://github.com/Snazzy72/better-auth-nestjs) for you to check out what I did Here's a screenshot to show you that the handler is setup correctly upon running the `nest start` script ![image](https://github.com/user-attachments/assets/1a211f75-964f-4cf6-8266-a4c8bd3e6e12) You can also visit `http://localhost:3000/api/auth/ok` and if you get the following response, then it's working: ``` { "ok": true } ```
Author
Owner

@iamstarcode commented on GitHub (Oct 30, 2024):

@Snazzy72 Thanks for the reply, this works. Will also be testing in real app.

@iamstarcode commented on GitHub (Oct 30, 2024): @Snazzy72 Thanks for the reply, this works. Will also be testing in real app.
Author
Owner

@danyalutsevich commented on GitHub (Oct 30, 2024):

@Snazzy72 how did you disabled cors?

@danyalutsevich commented on GitHub (Oct 30, 2024): @Snazzy72 how did you disabled cors?
Author
Owner

@ghost commented on GitHub (Oct 31, 2024):

@Snazzy72 how did you disabled cors?

Everything is in the repo. I've done nothing more/less

@ghost commented on GitHub (Oct 31, 2024): > @Snazzy72 how did you disabled cors? Everything is in the repo. I've done nothing more/less
Author
Owner

@BayBreezy commented on GitHub (Nov 2, 2024):

@Snazzy72 If you could clean this up, add support for other DB's in the example and do a PR for it to be added to the better auth example website, that would be great!
My first attempt left me with ESM errors, so I gave up but you went all the way. GG

@BayBreezy commented on GitHub (Nov 2, 2024): @Snazzy72 If you could clean this up, add support for other DB's in the example and do a PR for it to be added to the better auth example website, that would be great! My first attempt left me with ESM errors, so I gave up but you went all the way. GG
Author
Owner

@iamstarcode commented on GitHub (Nov 4, 2024):

Hi guys, I actually did tried this in an actual app now but got an error now,

ERROR [ExceptionsHandler] Response body object should not be disturbed or locked
TypeError: Response body object should not be disturbed or locked

I'am not sure why this error is happening, I think it might be has something to do with the response object been chnaged by both NestJs and Better-Auth resulting is some sort of error. Don't know if anybody has an idea on how this could be resolved. I did the nestjs @Res({ passthrough: true })response: Response , on the Response object but doesn't seems to work

@iamstarcode commented on GitHub (Nov 4, 2024): Hi guys, I actually did tried this in an actual app now but got an error now, ``` ERROR [ExceptionsHandler] Response body object should not be disturbed or locked TypeError: Response body object should not be disturbed or locked ``` I'am not sure why this error is happening, I think it might be has something to do with the response object been chnaged by both NestJs and Better-Auth resulting is some sort of error. Don't know if anybody has an idea on how this could be resolved. I did the nestjs `@Res({ passthrough: true })response: Response` , on the Response object but doesn't seems to work
Author
Owner

@iamstarcode commented on GitHub (Nov 4, 2024):

Full erro stack trace

[Nest] 88162  - 11/04/2024, 3:23:34 PM   ERROR [ExceptionsHandler] Response body object should not be disturbed or locked
TypeError: Response body object should not be disturbed or locked
    at extractBody (node:internal/deps/undici/undici:5325:17)
    at new Request (node:internal/deps/undici/undici:9499:48)
    at getRequest (file:///home/starcode/projects/Nodejs/better-auth-nestjs/node_modules/.pnpm/better-call@0.2.13/node_modules/better-call/src/adapter/request.ts:98:9)
    at file:///home/starcode/projects/Nodejs/better-auth-nestjs/node_modules/.pnpm/better-call@0.2.13/node_modules/better-call/src/adapter/node.ts:10:34
    at toNestJsController (file:///home/starcode/projects/Nodejs/better-auth-nestjs/src/lib/auth.ts:25:12)
    at BetterAuthController.handleAuth (file:///home/starcode/projects/Nodejs/better-auth-nestjs/src/better-auth.controller.ts:17:7)
    at /home/starcode/projects/Nodejs/better-auth-nestjs/node_modules/.pnpm/@nestjs+core@9.4.3_@nestjs+common@9.4.3_reflect-metadata@0.1.14_rxjs@7.8.1__@nestjs+platform-_hhtgoj34sxagmh36m5cxwgzlrm/node_modules/@nestjs/core/router/router-execution-context.js:46:28
    at /home/starcode/projects/Nodejs/better-auth-nestjs/node_modules/.pnpm/@nestjs+core@9.4.3_@nestjs+common@9.4.3_reflect-metadata@0.1.14_rxjs@7.8.1__@nestjs+platform-_hhtgoj34sxagmh36m5cxwgzlrm/node_modules/@nestjs/core/router/router-proxy.js:9:17
@iamstarcode commented on GitHub (Nov 4, 2024): Full erro stack trace ``` [Nest] 88162 - 11/04/2024, 3:23:34 PM ERROR [ExceptionsHandler] Response body object should not be disturbed or locked TypeError: Response body object should not be disturbed or locked at extractBody (node:internal/deps/undici/undici:5325:17) at new Request (node:internal/deps/undici/undici:9499:48) at getRequest (file:///home/starcode/projects/Nodejs/better-auth-nestjs/node_modules/.pnpm/better-call@0.2.13/node_modules/better-call/src/adapter/request.ts:98:9) at file:///home/starcode/projects/Nodejs/better-auth-nestjs/node_modules/.pnpm/better-call@0.2.13/node_modules/better-call/src/adapter/node.ts:10:34 at toNestJsController (file:///home/starcode/projects/Nodejs/better-auth-nestjs/src/lib/auth.ts:25:12) at BetterAuthController.handleAuth (file:///home/starcode/projects/Nodejs/better-auth-nestjs/src/better-auth.controller.ts:17:7) at /home/starcode/projects/Nodejs/better-auth-nestjs/node_modules/.pnpm/@nestjs+core@9.4.3_@nestjs+common@9.4.3_reflect-metadata@0.1.14_rxjs@7.8.1__@nestjs+platform-_hhtgoj34sxagmh36m5cxwgzlrm/node_modules/@nestjs/core/router/router-execution-context.js:46:28 at /home/starcode/projects/Nodejs/better-auth-nestjs/node_modules/.pnpm/@nestjs+core@9.4.3_@nestjs+common@9.4.3_reflect-metadata@0.1.14_rxjs@7.8.1__@nestjs+platform-_hhtgoj34sxagmh36m5cxwgzlrm/node_modules/@nestjs/core/router/router-proxy.js:9:17 ```
Author
Owner

@danyalutsevich commented on GitHub (Nov 4, 2024):

I have the same error
@Bekacru said you can just use auth.handler(req)
check this message in discord for more context

@danyalutsevich commented on GitHub (Nov 4, 2024): I have the same error @Bekacru said `you can just use auth.handler(req)` check this [message in discord](https://discord.com/channels/1288403910284935179/1288403910284935182/1297611630669987941) for more context
Author
Owner

@iamstarcode commented on GitHub (Nov 4, 2024):

Hi @danyalutsevich thanks for the response, I just tried what you suggested but end up with another error lol. I'am not sure if this is what you meant.

return await this.authService.auth.handler(request);
// await toNestJsController(this.authService, request, response);

But I ended up with another error

[Nest] 92532  - 11/04/2024, 3:47:57 PM   ERROR [ExceptionsHandler] Invalid URL
TypeError: Invalid URL
    at new URL (node:internal/url:806:29)
    at Object.handler (file:///home/starcode/projects/Nodejs/better-auth-nestjs/node_modules/.pnpm/better-auth@0.6.2_react@18.3.1_solid-js@1.9.3_vue@3.5.12_typescript@4.9.5_/node_modules/better-auth/dist/index.js:1:3217)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at BetterAuthController.handleAuth (file:///home/starcode/projects/Nodejs/better-auth-nestjs/src/better-auth.controller.ts:17:14)

And also in relation to the discord about been only web, I'am not sure if I understand that correctly, would that mean it wont work for native like the new added expo plugin. I have set up Hono correctly, but the codeabse I want to use Better-Auth with is written in Nestjs, This is really making me go crazy, 🤪 , If Hono could work why not NestJs😂

@iamstarcode commented on GitHub (Nov 4, 2024): Hi @danyalutsevich thanks for the response, I just tried what you suggested but end up with another error lol. I'am not sure if this is what you meant. ``` return await this.authService.auth.handler(request); // await toNestJsController(this.authService, request, response); ``` But I ended up with another error ``` [Nest] 92532 - 11/04/2024, 3:47:57 PM ERROR [ExceptionsHandler] Invalid URL TypeError: Invalid URL at new URL (node:internal/url:806:29) at Object.handler (file:///home/starcode/projects/Nodejs/better-auth-nestjs/node_modules/.pnpm/better-auth@0.6.2_react@18.3.1_solid-js@1.9.3_vue@3.5.12_typescript@4.9.5_/node_modules/better-auth/dist/index.js:1:3217) at processTicksAndRejections (node:internal/process/task_queues:95:5) at BetterAuthController.handleAuth (file:///home/starcode/projects/Nodejs/better-auth-nestjs/src/better-auth.controller.ts:17:14) ``` And also in relation to the discord about been only web, I'am not sure if I understand that correctly, would that mean it wont work for native like the new added expo plugin. I have set up Hono correctly, but the codeabse I want to use Better-Auth with is written in Nestjs, This is really making me go crazy, 🤪 , If Hono could work why not NestJs😂
Author
Owner

@danyalutsevich commented on GitHub (Nov 4, 2024):

yeah i got the same Invalid URL error may be @Bekacru or @NoHaxito can help.

@danyalutsevich commented on GitHub (Nov 4, 2024): yeah i got the same Invalid URL error may be @Bekacru or @NoHaxito can help.
Author
Owner

@NoHaxito commented on GitHub (Nov 4, 2024):

Hi @danyalutsevich thanks for the response, I just tried what you suggested but end up with another error lol. I'am not sure if this is what you meant.

return await this.authService.auth.handler(request);
// await toNestJsController(this.authService, request, response);

But I ended up with another error

[Nest] 92532  - 11/04/2024, 3:47:57 PM   ERROR [ExceptionsHandler] Invalid URL
TypeError: Invalid URL
    at new URL (node:internal/url:806:29)
    at Object.handler (file:///home/starcode/projects/Nodejs/better-auth-nestjs/node_modules/.pnpm/better-auth@0.6.2_react@18.3.1_solid-js@1.9.3_vue@3.5.12_typescript@4.9.5_/node_modules/better-auth/dist/index.js:1:3217)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at BetterAuthController.handleAuth (file:///home/starcode/projects/Nodejs/better-auth-nestjs/src/better-auth.controller.ts:17:14)

And also in relation to the discord about been only web, I'am not sure if I understand that correctly, would that mean it wont work for native like the new added expo plugin. I have set up Hono correctly, but the codeabse I want to use Better-Auth with is written in Nestjs, This is really making me go crazy, 🤪 , If Hono could work why not NestJs😂

You have setted the baseUrl in betterAuth?

@NoHaxito commented on GitHub (Nov 4, 2024): > Hi @danyalutsevich thanks for the response, I just tried what you suggested but end up with another error lol. I'am not sure if this is what you meant. > ``` > return await this.authService.auth.handler(request); > // await toNestJsController(this.authService, request, response); > ``` > But I ended up with another error > ``` > [Nest] 92532 - 11/04/2024, 3:47:57 PM ERROR [ExceptionsHandler] Invalid URL > TypeError: Invalid URL > at new URL (node:internal/url:806:29) > at Object.handler (file:///home/starcode/projects/Nodejs/better-auth-nestjs/node_modules/.pnpm/better-auth@0.6.2_react@18.3.1_solid-js@1.9.3_vue@3.5.12_typescript@4.9.5_/node_modules/better-auth/dist/index.js:1:3217) > at processTicksAndRejections (node:internal/process/task_queues:95:5) > at BetterAuthController.handleAuth (file:///home/starcode/projects/Nodejs/better-auth-nestjs/src/better-auth.controller.ts:17:14) > ``` > And also in relation to the discord about been only web, I'am not sure if I understand that correctly, would that mean it wont work for native like the new added expo plugin. I have set up Hono correctly, but the codeabse I want to use Better-Auth with is written in Nestjs, This is really making me go crazy, 🤪 , If Hono could work why not NestJs😂 You have setted the `baseUrl` in `betterAuth`?
Author
Owner

@NoHaxito commented on GitHub (Nov 4, 2024):

Or check if your BETTER_AUTH_URL env variable is being loaded

@NoHaxito commented on GitHub (Nov 4, 2024): Or check if your `BETTER_AUTH_URL` env variable is being loaded
Author
Owner

@iamstarcode commented on GitHub (Nov 4, 2024):

@NoHaxito Yeah the env variables are correctly set, even logged it to be sure it's been set, also gave it a bad url and Better-Auth was smart enough to tell me that's a bad URL.

@iamstarcode commented on GitHub (Nov 4, 2024): @NoHaxito Yeah the env variables are correctly set, even logged it to be sure it's been set, also gave it a bad url and Better-Auth was smart enough to tell me that's a bad URL.
Author
Owner

@NoHaxito commented on GitHub (Nov 4, 2024):

@iamstarcode so it's working now?
I didn't understand you very well.

@NoHaxito commented on GitHub (Nov 4, 2024): @iamstarcode so it's working now? I didn't understand you very well.
Author
Owner

@iamstarcode commented on GitHub (Nov 4, 2024):

@NoHaxito ,no sir/ma it didn't work.

@iamstarcode commented on GitHub (Nov 4, 2024): @NoHaxito ,no sir/ma it didn't work.
Author
Owner

@NoHaxito commented on GitHub (Nov 4, 2024):

@NoHaxito ,no sir/ma it didn't work.

How do you have better-auth configured?

@NoHaxito commented on GitHub (Nov 4, 2024): > @NoHaxito ,no sir/ma it didn't work. How do you have better-auth configured?
Author
Owner

@NoHaxito commented on GitHub (Nov 4, 2024):

@NoHaxito ,no sir/ma it didn't work.

Can you send your better-auth config?

@NoHaxito commented on GitHub (Nov 4, 2024): > @NoHaxito ,no sir/ma it didn't work. Can you send your better-auth config?
Author
Owner

@iamstarcode commented on GitHub (Nov 4, 2024):

I haven't tested what I'm about to suggest in a real app, but I have tested it with boilerplate nestjs code, and the route handling works correctly.

I've setup a repo for you to check out what I did

Here's a screenshot to show you that the handler is setup correctly upon running the nest start script image

You can also visit http://localhost:3000/api/auth/ok and if you get the following response, then it's working:

{
  "ok": true
}

I made use of @Snazzy72 repo, the "ok" endpoints works not just other parts of the API of Better-Auth. I think it's how Nestjs handles API routes that's the problem. If we could get express to directly handle the API routes in NestJs we could get it to work, I have tried Middleware that doesn't seems to work too.

@iamstarcode commented on GitHub (Nov 4, 2024): > I haven't tested what I'm about to suggest in a real app, but I have tested it with boilerplate nestjs code, and the route handling works correctly. > > I've setup a [repo](https://github.com/Snazzy72/better-auth-nestjs) for you to check out what I did > > Here's a screenshot to show you that the handler is setup correctly upon running the `nest start` script ![image](https://private-user-images.githubusercontent.com/69359713/381302369-1a211f75-964f-4cf6-8266-a4c8bd3e6e12.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzA3MzEzMDgsIm5iZiI6MTczMDczMTAwOCwicGF0aCI6Ii82OTM1OTcxMy8zODEzMDIzNjktMWEyMTFmNzUtOTY0Zi00Y2Y2LTgyNjYtYTRjOGJkM2U2ZTEyLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDExMDQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQxMTA0VDE0MzY0OFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWQzZTc3MWUyYzIzNGUwNTIyZmNhOTE1NTBjMTNiNDYzMjJkMzVmZDVkY2MyN2U2OTA3N2JmZWVkZDM1ZDIyMDUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.oC9_mkKEUQqWvNvanrT4rtIw0kYfUbYBkg1_AVS4BFg) > > You can also visit `http://localhost:3000/api/auth/ok` and if you get the following response, then it's working: > > ``` > { > "ok": true > } > ``` I made use of @Snazzy72 repo, the "ok" endpoints works not just other parts of the API of Better-Auth. I think it's how Nestjs handles API routes that's the problem. If we could get express to directly handle the API routes in NestJs we could get it to work, I have tried Middleware that doesn't seems to work too.
Author
Owner

@danyalutsevich commented on GitHub (Nov 4, 2024):

I've tried to get express app instance to attach node handler to it but I still get Invalid Url error
check my repo

Screenshot 2024-11-04 at 23 40 22
@danyalutsevich commented on GitHub (Nov 4, 2024): I've tried to get express app instance to attach node handler to it but I still get Invalid Url error check my [repo](https://github.com/danyalutsevich/sandbox/blob/base/js_ts/better-auth-nestjs/src/main.ts) <img width="674" alt="Screenshot 2024-11-04 at 23 40 22" src="https://github.com/user-attachments/assets/6f8617d2-4aad-4bc6-b926-ea57864b61d1">
Author
Owner

@wh5938316 commented on GitHub (Nov 5, 2024):

Hi guys, I actually did tried this in an actual app now but got an error now,

ERROR [ExceptionsHandler] Response body object should not be disturbed or locked
TypeError: Response body object should not be disturbed or locked

I'am not sure why this error is happening, I think it might be has something to do with the response object been chnaged by both NestJs and Better-Auth resulting is some sort of error. Don't know if anybody has an idea on how this could be resolved. I did the nestjs @Res({ passthrough: true })response: Response , on the Response object but doesn't seems to work

I encountered the same issue, but I managed to resolve it temporarily and successfully run it on Nest.js. See the details here.

The better-auth package depends on a repository called better-call. Nest.js runs the bodyParse middleware by default, which causes the request body to be parsed and destroyed prematurely.

To work around this, you can write a local toNestJsController method as a temporary solution.

export async function toNestJsController(authService: any, request: Request, response: Response) {
  // const { toNodeHandler } = await import('better-auth/node');
  // @ts-ignore
  const { setResponse } = await import('better-call');

  function toNodeHandler(handler: any) {
    return async (req: any, res: ServerResponse) => {
      const protocol = (req.connection as any)?.encrypted ? 'https' : 'http';
      const base = `${protocol}://${req.headers[':authority'] || req.headers.host}`;
      const response = await handler.handler(getRequest({ base, request: req }));

      setResponse(res, response);
    };
  }

  try {
    const authHandler = toNodeHandler(authService.auth);
    return authHandler(request as any, response as any);
  } catch (error) {
    console.log(error);
  }
}

function get_raw_body(req: IncomingMessage, body_size_limit?: number) {
  const h = req.headers;

  if (!h['content-type']) return null;

  const content_length = Number(h['content-length']);

  // check if no request body
  if (
    (req.httpVersionMajor === 1 && isNaN(content_length) && h['transfer-encoding'] == null) ||
    content_length === 0
  ) {
    return null;
  }

  let length = content_length;

  if (body_size_limit) {
    if (!length) {
      length = body_size_limit;
    } else if (length > body_size_limit) {
      throw Error(
        `Received content-length of ${length}, but only accept up to ${body_size_limit} bytes.`,
      );
    }
  }

  if (req.destroyed) {
    // @ts-ignore
    if (req.body) {
      return new ReadableStream({
        start(controller) {
          // @ts-ignore
          controller.enqueue(Buffer.from(JSON.stringify(req.body)));
          controller.close();
        },
      });
    } else {
      return new ReadableStream({
        start(controller) {
          controller.close();
        },
      });
    }
  }

  let size = 0;
  let cancelled = false;

  return new ReadableStream({
    start(controller) {
      req.on('error', (error) => {
        cancelled = true;
        controller.error(error);
      });

      req.on('end', () => {
        if (cancelled) return;
        controller.close();
      });

      req.on('data', (chunk) => {
        if (cancelled) return;

        size += chunk.length;

        if (size > length) {
          cancelled = true;

          controller.error(
            new Error(
              `request body size exceeded ${content_length ? "'content-length'" : 'BODY_SIZE_LIMIT'
              } of ${length}`,
            ),
          );
          return;
        }

        controller.enqueue(chunk);

        if (controller.desiredSize === null || controller.desiredSize <= 0) {
          req.pause();
        }
      });
    },

    pull() {
      req.resume();
    },

    cancel(reason) {
      cancelled = true;
      req.destroy(reason);
    },
  });
}

function getRequest({
  request,
  base,
  bodySizeLimit,
}: {
  base: string;
  bodySizeLimit?: number;
  request: IncomingMessage;
}) {
  return new Request(base + request.url, {
    // @ts-expect-error
    duplex: 'half',
    method: request.method,
    body: get_raw_body(request, bodySizeLimit),
    headers: request.headers as Record<string, string>,
  });
}
@wh5938316 commented on GitHub (Nov 5, 2024): > Hi guys, I actually did tried this in an actual app now but got an error now, > > ``` > ERROR [ExceptionsHandler] Response body object should not be disturbed or locked > TypeError: Response body object should not be disturbed or locked > ``` > > I'am not sure why this error is happening, I think it might be has something to do with the response object been chnaged by both NestJs and Better-Auth resulting is some sort of error. Don't know if anybody has an idea on how this could be resolved. I did the nestjs `@Res({ passthrough: true })response: Response` , on the Response object but doesn't seems to work I encountered the same issue, but I managed to resolve it temporarily and successfully run it on Nest.js. See the details [here](https://github.com/better-auth/better-auth/issues/406#issuecomment-2453777000). The better-auth package depends on a repository called better-call. Nest.js runs the bodyParse middleware by default, which causes the request body to be parsed and destroyed prematurely. To work around this, you can write a local toNestJsController method as a temporary solution. ``` export async function toNestJsController(authService: any, request: Request, response: Response) { // const { toNodeHandler } = await import('better-auth/node'); // @ts-ignore const { setResponse } = await import('better-call'); function toNodeHandler(handler: any) { return async (req: any, res: ServerResponse) => { const protocol = (req.connection as any)?.encrypted ? 'https' : 'http'; const base = `${protocol}://${req.headers[':authority'] || req.headers.host}`; const response = await handler.handler(getRequest({ base, request: req })); setResponse(res, response); }; } try { const authHandler = toNodeHandler(authService.auth); return authHandler(request as any, response as any); } catch (error) { console.log(error); } } function get_raw_body(req: IncomingMessage, body_size_limit?: number) { const h = req.headers; if (!h['content-type']) return null; const content_length = Number(h['content-length']); // check if no request body if ( (req.httpVersionMajor === 1 && isNaN(content_length) && h['transfer-encoding'] == null) || content_length === 0 ) { return null; } let length = content_length; if (body_size_limit) { if (!length) { length = body_size_limit; } else if (length > body_size_limit) { throw Error( `Received content-length of ${length}, but only accept up to ${body_size_limit} bytes.`, ); } } if (req.destroyed) { // @ts-ignore if (req.body) { return new ReadableStream({ start(controller) { // @ts-ignore controller.enqueue(Buffer.from(JSON.stringify(req.body))); controller.close(); }, }); } else { return new ReadableStream({ start(controller) { controller.close(); }, }); } } let size = 0; let cancelled = false; return new ReadableStream({ start(controller) { req.on('error', (error) => { cancelled = true; controller.error(error); }); req.on('end', () => { if (cancelled) return; controller.close(); }); req.on('data', (chunk) => { if (cancelled) return; size += chunk.length; if (size > length) { cancelled = true; controller.error( new Error( `request body size exceeded ${content_length ? "'content-length'" : 'BODY_SIZE_LIMIT' } of ${length}`, ), ); return; } controller.enqueue(chunk); if (controller.desiredSize === null || controller.desiredSize <= 0) { req.pause(); } }); }, pull() { req.resume(); }, cancel(reason) { cancelled = true; req.destroy(reason); }, }); } function getRequest({ request, base, bodySizeLimit, }: { base: string; bodySizeLimit?: number; request: IncomingMessage; }) { return new Request(base + request.url, { // @ts-expect-error duplex: 'half', method: request.method, body: get_raw_body(request, bodySizeLimit), headers: request.headers as Record<string, string>, }); } ```
Author
Owner

@iamstarcode commented on GitHub (Nov 5, 2024):

Hi @wh5938316 , great job you have done there, I can also comfirm this works, So many caveat goin on, Using this required the installation of better-call to be able to set the server response like you have highlighted, also instead of that function get_raw_body , NestJs already has a neat way of getting Raw Body will also simplifies things, so we can use this temporary fix, but I'm not sure how best we can add this into Better-Auth, I think @Bekacru or @NoHaxito would know how it's best to implement this. This is what the final code looks like.

function getRequest({
  base,
  request,
  rawBody,
}: {
  base: string;
  request: any;
  rawBody: any;
}) {
  return new Request(base + request.url, {
    // @ts-expect-error
    duplex: 'half',
    method: request.method,
    body: rawBody,
    headers: request.headers as Record<string, string>,
  });
}

export async function toNestJsController(
  authService: BetterAuthService,
  request: Request,
  response: Response
) {
  function toNodeHandler(handler: any) {
    return async (req: any, res: any) => {
      const { setResponse } = await import('better-call');
      const protocol = (req.connection as any)?.encrypted ? 'https' : 'http';
      const base = `${protocol}://${
        req.headers[':authority'] || req.headers.host
      }`;
      const response = await handler.handler(
        getRequest({ base, request: req, rawBody: req.rawBody })
      );

      setResponse(res, response);
    };
  }

  try {
    const authHandler = toNodeHandler(authService.auth);
    return authHandler(request as any, response as any);
  } catch (error) {
    console.log(error);
  }
}
@iamstarcode commented on GitHub (Nov 5, 2024): Hi @wh5938316 , great job you have done there, I can also comfirm this works, So many caveat goin on, Using this required the installation of `better-call` to be able to set the server response like you have highlighted, also instead of that function `get_raw_body` , NestJs already has a neat way of getting [Raw Body](https://docs.nestjs.com/faq/raw-body) will also simplifies things, so we can use this temporary fix, but I'm not sure how best we can add this into Better-Auth, I think @Bekacru or @NoHaxito would know how it's best to implement this. This is what the final code looks like. ``` function getRequest({ base, request, rawBody, }: { base: string; request: any; rawBody: any; }) { return new Request(base + request.url, { // @ts-expect-error duplex: 'half', method: request.method, body: rawBody, headers: request.headers as Record<string, string>, }); } export async function toNestJsController( authService: BetterAuthService, request: Request, response: Response ) { function toNodeHandler(handler: any) { return async (req: any, res: any) => { const { setResponse } = await import('better-call'); const protocol = (req.connection as any)?.encrypted ? 'https' : 'http'; const base = `${protocol}://${ req.headers[':authority'] || req.headers.host }`; const response = await handler.handler( getRequest({ base, request: req, rawBody: req.rawBody }) ); setResponse(res, response); }; } try { const authHandler = toNodeHandler(authService.auth); return authHandler(request as any, response as any); } catch (error) { console.log(error); } } ```
Author
Owner

@wh5938316 commented on GitHub (Nov 5, 2024):

Hi @iamstarcode

Currently, better-auth is not production-ready. I believe we can temporarily address this issue using a workaround for the time being.

We can look forward to @Bekacru completing native support for Nest.js, which appears to be part of the v1.0 roadmap. Standalone backend projects are more common in medium to large-scale projects that require team collaboration, and better-auth seems to prioritize full-stack frameworks(based on the number and completeness of integrations).

In my opinion, it might be beneficial to separate the core authentication logic into a core library, with the request handling part acting as glue for various frameworks. This way, simple projects can continue using the current approach, while more complex projects can directly utilize the core library. I have high hopes for better-auth, but currently, it feels too abstract, with all the additional code being passed into the betterAuth options.

These are just my initial thoughts, as I’ve only been using better-auth for two days.

@wh5938316 commented on GitHub (Nov 5, 2024): Hi @iamstarcode Currently, better-auth is not production-ready. I believe we can temporarily address this issue using a workaround for the time being. We can look forward to @Bekacru completing native support for Nest.js, which appears to be part of the v1.0 roadmap. Standalone backend projects are more common in medium to large-scale projects that require team collaboration, and better-auth seems to prioritize full-stack frameworks(based on the number and completeness of integrations). In my opinion, it might be beneficial to separate the core authentication logic into a core library, with the request handling part acting as glue for various frameworks. This way, simple projects can continue using the current approach, while more complex projects can directly utilize the core library. I have high hopes for better-auth, but currently, it feels too abstract, with all the additional code being passed into the betterAuth options. These are just my initial thoughts, as I’ve only been using better-auth for two days.
Author
Owner

@iamstarcode commented on GitHub (Nov 5, 2024):

@wh5938316 Great submission once again. The workaround is definitely OK, I don't see any pain in this workaround, it just requires few lines of code, and which will potentially save hundred of hours time implementing auth from ground up.

I completely agree on the isolation of core authentication logic, and I believe better-auth is somewhat that way with its plugin system. I have very high hopes for better-auth, it's such a beauty 😍 at a very young age. @Bekacru is doing such a great work, and I believe all issues you have raised will eventually be treated in the long run.

@iamstarcode commented on GitHub (Nov 5, 2024): @wh5938316 Great submission once again. The workaround is definitely OK, I don't see any pain in this workaround, it just requires few lines of code, and which will potentially save hundred of hours time implementing auth from ground up. I completely agree on the isolation of core authentication logic, and I believe better-auth is somewhat that way with its plugin system. I have very high hopes for better-auth, it's such a beauty 😍 at a very young age. @Bekacru is doing such a great work, and I believe all issues you have raised will eventually be treated in the long run.
Author
Owner

@Deliana90 commented on GitHub (Dec 3, 2024):

@wh5938316 how you know if "better-auth is not production-ready"

@Deliana90 commented on GitHub (Dec 3, 2024): @wh5938316 how you know if "better-auth is not production-ready"
Author
Owner

@wh5938316 commented on GitHub (Dec 3, 2024):

@wh5938316 how you know if "better-auth is not production-ready"

If you’re using a full-stack framework like Next.js, I would say yes, Better-Auth is production-ready.

However, if you’re using NestJS, there are still some caveats. Better Auth does not natively support NestJS yet, so you’ll need to write some glue code. That said, I have successfully integrated Better-Auth into my project.

Additionally, I know of an open-source project, mx-space, whose NestJS backend has already migrated to Better-Auth.

@wh5938316 commented on GitHub (Dec 3, 2024): > @wh5938316 how you know if "better-auth is not production-ready" If you’re using a full-stack framework like Next.js, I would say yes, Better-Auth is production-ready. However, if you’re using NestJS, there are still some caveats. Better Auth does not natively support NestJS yet, so you’ll need to write some glue code. That said, I have successfully integrated Better-Auth into my project. Additionally, I know of an open-source project, [mx-space](https://github.com/mx-space/core/blob/1bcb434a27d5b6e73759f833f01171be04d002e2/apps/core/src/modules/auth/auth.implement.ts#L10), whose NestJS backend has already migrated to Better-Auth.
Author
Owner

@Bekacru commented on GitHub (Dec 17, 2024):

I'm going to close this issue. We will track NestJS support with #171

@Bekacru commented on GitHub (Dec 17, 2024): I'm going to close this issue. We will track NestJS support with #171
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#149