Giter VIP home page Giter VIP logo

auth-astro's People

Contributors

alexvuka1 avatar arnavk-09 avatar bonavida avatar brycerussell avatar kcoderhtml avatar kfranqueiro avatar nowaythatworked avatar panteliselef avatar pietervdwerk avatar rzmk avatar theotterlord avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

auth-astro's Issues

Auth configuration filename hidden in README

What's the issue?

I got stuck at the step of the README that explains how to set up the auth config because the filename for the config does not show up in GitHub. I had to go searching around in issue and the code to try and the expected name for the config file.

Even though the code-block contains a title with the filename it is not visible in GitHub and I was only able to see it after cloning the repo.

image

Potential fixes

Showing the file name would improve the experience of setup.

Two options that jump out to me are either as follows:

  1. Putting the filename as comment in in the codeblock
// auth.config.ts
import GitHub from '@auth/core/providers/github'
import { defineConfig } from 'auth-astro'

export default defineConfig({
	providers: [
		GitHub({
			clientId: import.meta.env.GITHUB_CLIENT_ID,
			clientSecret: import.meta.env.GITHUB_CLIENT_SECRET,
		}),
	],
})
  1. Changing the sentence before the codeblock to include the filename

Add your auth configuration to auth.config.ts in the root of your project.

Happy to make a PR if you have a preference.

Incompatible with `@astrojs/image`

This doesn't matter too much, as the image integration is due to be discontinued, but if the same issues exist with astro:assets it's more of a problem. Still worth fixing this though, for older sites that still rely on the image integration.

Session cookies not changing when session is updated

I am using the Credentials provider with a custom backend service for authentication. I have some logic in the jwt callback that checks if the token is about to expire and makes a call to the backend service to fetch new tokens if needed, somewhat like so:

export default {
  ...
  callbacks: {
    async jwt({ token, user }) {
      if (user) return { ...token, ...user };
      if (!hasExpired(token)) return token;
      const newToken = getNewToken(token.refreshToken) // backend service call
      return { ...token, ...newToken }
    }
  }
  ...
}

Upon calling getSession or on page refresh, I see that this logic is fired, the token is refreshed accordingly and I get back the refreshed token. However, I noticed that despite updating the token, when the jwt callback is fired again, the token destructured in the jwt callback is the initial expired token, not the updated one.

I noticed that the auth.js cookies are set during sign in, but they don't change when the session is updated in this callback, which might be causing this issue. Any thoughts or feedback on this would be much appreciated!

Authentication fails with @auth/core/providers/twitch

I'm working on refactoring a project to use Astro, and auth-astro seems like a great way to handle authentication, but I'm having trouble getting it to work with the Twitch provider from @auth/core. Everything builds and sign in with GitHub works correctly showing my GitHub username in the session. I'm failry sure I have the clientId and clientSectret set up properly since the twitch authentication process does recognize that I've authenticated and it shows up in my connections on my twitch account, but when returning from id.twitch.tv to the callbackURL http://localhost:3000/api/auth/callback/twitch after authorizing my app, I get redirected to: http://localhost:3000/api/auth/error?error=CallbackRouteError which shows "Error localhost:3000 in the browser", and I get the following error in the node console from Astro:

[auth][cause]: OperationProcessingError: "response" body "scope" property must be a string
    at processGenericAccessTokenResponse (file:///D:/devroot/astro-migration/web/node_modules/oauth4webapi/build/index.js:917:15)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Module.processAuthorizationCodeOpenIDResponse (file:///D:/devroot/astro-migration/web/node_modules/oauth4webapi/build/index.js:1011:20)
    at async handleOAuth (file:///D:/devroot/astro-migration/web/node_modules/@auth/core/lib/oauth/callback.js:79:24)
    at async Module.callback (file:///D:/devroot/astro-migration/web/node_modules/@auth/core/lib/routes/callback.js:14:41)
    at async AuthInternal (file:///D:/devroot/astro-migration/web/node_modules/@auth/core/lib/index.js:64:38)
    at async Proxy.Auth (file:///D:/devroot/astro-migration/web/node_modules/@auth/core/index.js:100:30)
    at async eval (/node_modules/auth-astro/server.ts:44:17)
    at async Module.get (/node_modules/auth-astro/server.ts:65:14)
    at async call (file:///D:/devroot/astro-migration/web/node_modules/astro/dist/core/endpoint/index.js:72:20)
[auth][details]: {
  "provider": "twitch"
}

Astro doesn't retain a session from that login attempt, and just returns null for await getSession(Astro.request) where using the GitHub provider to log in gives me name, email, etc in the session as expected.

I have tested with the same twitch client id and secret using SvelteKitAuth @auth/sveltekit also using @auth/core/providers/twitch in a separate project and authenticated there successfully. Since that also uses @auth/core, I'm hoping there is just some minor tweak I'm missing.


My astro.config.mjs:

import { defineConfig } from "astro/config";
import { loadEnv } from "vite";
import node from "@astrojs/node";
import auth from "auth-astro";
import TwitchProvider from "@auth/core/providers/twitch";
import GithubProvider from "@auth/core/providers/github";
const env = loadEnv( "production", process.cwd(), "" );

const Twitch = TwitchProvider( {
  clientId     : env.TWITCH_CLIENT_ID,
  clientSecret : env.TWITCH_CLIENT_SECRET,
} );

const GitHub = GithubProvider( {
  clientId     : env.GITHUB_CLIENT_ID,
  clientSecret : env.GITHUB_CLIENT_SECRET,
} );

export default defineConfig( {
  output  : "server",
  adapter : node( {
    mode : "middleware"
  } ),
  integrations : [
    auth( {
      providers : [
        Twitch,
        GitHub,
      ],
    } ),
  ]
} );

I've tried with standalone instead of middleware for the node adapter mode, and it there is no difference in the resulting behavior when running astro dev (although I do need eventually middleware mode since this is going to be built and imported to another project serving with express and used just as part of a site.)


index.astro for testing:

---
import Layout from '../layouts/Layout.astro';

import type { Session } from '@auth/core/types';
import { SignIn, SignOut } from 'auth-astro/components';
import { getSession } from 'auth-astro/server';

const session = await getSession(Astro.request);
const sessionDump = JSON.stringify(session);
---

<Layout title="Auth test">
  <main>
    <h1>Welcome to <span class="text-gradient">Astro</span></h1>
    <p class="instructions">
      This is just a test.
    </p>
        {session ? 
          <SignOut>Logout</SignOut>
        :
          <SignIn>Login</SignIn>
        }
        <p>
          {session ? `Logged in as ${session.user?.name}` : 'Not logged in'}
        </p>
    sessionDump: {sessionDump}
  </main>
</Layout>

<style>
  main {
    margin: auto;
    padding: 1.5rem;
    max-width: 60ch;
  }
  h1 {
    font-size: 3rem;
    font-weight: 800;
    margin: 0;
  }
  .text-gradient {
    background-image: var(--accent-gradient);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-size: 400%;
    background-position: 0%;
  }
  .instructions {
    line-height: 1.6;
    margin: 1rem 0;
    border: 1px solid rgba(var(--accent), 25%);
    background-color: white;
    padding: 1rem;
    border-radius: 0.4rem;
  }
</style>

Is there something missing in auth-astro integration regarding the handling of the response body from the oidc/oauth process when the scope is returned? Any idea what I'm missing here?

adapters don't work when stringified in a virtual module

When the integration config is converted to a virutal module in config.ts, the adapter instance is lost when JSON.stringify() can't stringify the adapter's functions

I'm hoping this isn't an issue with wrapping everything up in an Astro integration, the astro add auth-astro flow makes for a really nice developer experience!

I think the main challenge is how the various provider and adapter packages are setup. To go through a Vite virtual module the integration really needs to know the package name used for providers an integrations rather than an object instance. That would allow the config.ts virtual module to handle building the logic for actually creating instances in the virtual module itself.

Contributing

I'm happy to work on a PR if there's a direction you have in mind! I'm just learning this codebase (along with the rest of Auth.js) - curious if you all have thoughts on a different solution I hadn't considered yet before I dig in too far!

Build failed: Could not resolve "auth:config"

Hey, thanks for developing this library! I ran into an error when following the instructions.

I'm using [email protected], node 17.4, and I also tried 18.16. I'm on MacOS 13.2.1 (although I don't think it's related)

✘ [ERROR] Could not resolve "auth:config"

    node_modules/auth-astro/server.ts:30:23:
      30 │ import authConfig from 'auth:config'
         ╵                        ~~~~~~~~~~~~~

  You can mark the path "auth:config" as external to exclude it from the bundle, which will remove
  this error.

Cloudflare adapter `crypto.subtle` undefined

When using auth-astro with the @astrojs/node adapter it works wonderfully. However, using the cloudflare adapter throws the following error:

TypeError: Cannot read properties of undefined (reading 'digest') on the following @auth/core function.

/** Web compatible method to create a hash, using SHA256 */
export async function createHash(message) {
    const data = new TextEncoder().encode(message);
    const hash = await crypto.subtle.digest("SHA-256", data);
^
    return Array.from(new Uint8Array(hash))
        .map((b) => b.toString(16).padStart(2, "0"))
        .join("")
        .toString();
}

Cloudflare documentation on workers runtime states that crypto.subtle.digest is available.

How to use credential provider?

Hello and thank you for this amazing project! I hope the PR will be merged soon.

I'm struggling to get this work with classical form data (https://next-auth.js.org/configuration/providers/credentials). I tried to look in different forks of this project before submitting the question, so sorry for the noob question.

I was able to create a example where I use external providers like Google or Apple, but not with Credentials.

auth.config.ts:

import Credentials from "@auth/core/providers/credentials";
import type { AuthConfig } from "@auth/core";

export default {
    providers: [
        Credentials({
            id: 'exampleAAAA',
            credentials: {
                username: {
                    label: "Username"
                },
                password: {
                    label: "Password",
                    type: "password"
                }
            },
            async authorize(credentials, request) {
                const user = {
                    id: "1",
                    name: "J Smith",
                    email: "[email protected]"
                };
                if (user) {
                    // Any object returned will be saved in `user` property of the JWT
                    return user;
                } else {
                    // If you return null then an error will be displayed advising the user to check their details.
                    return null;

                    // You can also Reject this callback with an Error thus the user will be sent to the error page with the error message as a query parameter
                }
            }
        })
    ]
} satisfies AuthConfig;

src/pages/login.astro

---
---

<html>
    <head>
        <script>
            const { signIn, signOut } = await import('auth-astro/client')

            async function processForm(e) {
                if (e.preventDefault) e.preventDefault()

                const form = e.target

                /* do what you want with the form */
                const formData = new FormData(form as HTMLFormElement)
                const data = Object.fromEntries(formData)
                await signIn('exampleAAAA', data)

                // You must return false to prevent the default form behavior
                return false
            }

            var form = document.getElementById('login-form')
            if (form.attachEvent) {
                form.attachEvent('submit', processForm)
            } else {
                form.addEventListener('submit', processForm)
            }
        </script>
    </head>
    <body>
        <form method="post" id="login-form">
            <label for="username">Name</label>
            <input type="text" name="username" />

            <label for="password">Password</label>
            <input type="password" name="password" />

            <input type="submit" value="Submit" />
        </form>
    </body>
</html>

The astro.config.mjs have the integration enabled.

With this basic form, when I click on submit, it redirects me to a login form instead of actually submitting the credentials. What I'm doing wrong?

Thank you in advance

restrict users

Is there a way to use an OAuth provider and still restrict the user?

For example only allow certain users from Github?

I didn't find that yet.

Setting up callbackUrl

Hello all,

I am trying to get callbackUrl's working to redirect into the correct context after signing in but am unable to find the correct hook.

I have tried the following per authjs docs but it's not worked:

signIn(provider, { callbackUrl: '/welcome', })

Does anyone have this working?

Thanks!

Sign In with Credentials Provider always return OK

Reasoning

I have been trying to implement error handling with auth-astro after managed to have sign in function works. However, there is an issue that making the return object from signIn with { redirect : false } always get 200 as the return status.

  • Down here is my configuration file
import postSignIn from "@/modules/auth/services/sign-in-api";

import Credentials from "@auth/core/providers/credentials";
import { defineConfig } from "auth-astro";

export default defineConfig({
  providers: [
    Credentials({
      id: "credentials",
      authorize: async (credentials, _) => {
        if (!credentials.email || !credentials.password) return null;

        try {
          const res = await postSignIn({
            email: credentials.email as string,
            password: credentials.password as string,
          });

          return {
            ...res.data.data,
            ...res.data.meta,
          };
        } catch (err) {
          return null;
        }
      },
    }),
  ],
  callbacks: {
    jwt: ({ token, user }) => {
      return {
        ...token,
        ...user,
      };
    },
    session: ({ session, token }) => {
      session.user = {
        id: token.id,
        type: token.type,
        emailVerified: new Date(token.attributes.confirmed_at),
        ...token.attributes,
      };

      session.tokens = {
        iat: token.iat,
        exp: token.exp,
        jti: token.jti,
        sub: token.sub,
        at: token.accessToken,
        rt: token.refreshToken,
      };
      return {
        ...session,
      };
    },
  },
  pages: {
    error: "/auth/error",
    newUser: "/onboarding/welcome",
    signIn: "/auth/sign-in",
    signOut: "/",
    verifyRequest: "/verify",
  },
  session: {
    strategy: "jwt",
  },
  trustHost: true,
});
  • Down here is where I used the sign in
...
  return (
    <Form {...form}>
      <form
        method="POST"
        onSubmit={form.handleSubmit(async (values) => {
          const res = await signIn("credentials", {
            redirect: false,
            callbackUrl: "/auth/sign-in",
            ...values,
          });

          console.log(res, await res?.json());
        })}
        className="w-full space-y-2"
      >
...
  • Down here is the console
body: (...),
bodyUsed: true,
headers: Headers {},
ok: true,
redirected: false,
status: 200,
statusText: "OK",
type: "basic",
url: "http://localhost:4321/api/auth/callback/credentials?"

Initialize auth config lazily

I ran into an issue when Astro SSR node build tried to eagerly initialize Auth.js config and required a working connection to the adapter DB (Mongo in my case). Unfortunately Auth.js config doesn't allow passing a factory function instead of an adapter instance.

I wonder if auth-astro could instead use a factory of Auth.js config in its build phase to avoid eagerly evaluating adapters.

As a workaround, I manager to use Proxy to wrap and lazy initialize the MongoDBAdapter. But that feels like a horrible hack.

I think issues like #52 might be resolved by that change as well.

Auth verification error not handled as expected

Setup with an Email provider. Sign in via magic link works.

The problem arises when you click on a magic link that was previously used. Expected behaviour is redirection to the error page with the search param ?error=Verification.

However, it leads to a TypeError immutable

The erring line

res.headers.delete('Set-Cookie')

This, I suspect is because the headers guard is set to immutable. More here

So, a work-around:

// ...
try {
  res.headers.delete('Set-Cookie')
} catch(error) {
  if (error instanceof TypeError) {
    const mutableHeaders = new Headers(res.headers)
    mutableHeaders.delete('Set-Cookie')
    return new Response(res.body, {
      headers: res.headers
    })
  }
}
// ...

This avoids the crash, but still no redirection to the error page, simply a 200 response.

I do see the error being logged though:

[auth][error] Verification: Read more at https://errors.authjs.dev#verification
    at Module.callback (file:///Users/aseem/Sites/astro-xata-vercel/node_modules/@auth/core/lib/actions/callback/index.js:126:23)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async AuthInternal (file:///Users/aseem/Sites/astro-xata-vercel/node_modules/@auth/core/lib/index.js:27:24)
    at async Module.Auth (file:///Users/aseem/Sites/astro-xata-vercel/node_modules/@auth/core/index.js:104:29)
    at async eval (/Users/aseem/Sites/astro-xata-vercel/node_modules/auth-astro/server.ts:25:17)
    at async Module.GET (/Users/aseem/Sites/astro-xata-vercel/node_modules/auth-astro/server.ts:55:14)
    at async renderEndpoint (file:///Users/aseem/Sites/astro-xata-vercel/node_modules/astro/dist/runtime/server/endpoint.js:25:20)
    at async file:///Users/aseem/Sites/astro-xata-vercel/node_modules/astro/dist/core/endpoint/index.js:121:14
    at async callMiddleware (file:///Users/aseem/Sites/astro-xata-vercel/node_modules/astro/dist/core/middleware/callMiddleware.js:12:10)
    at async callEndpoint (file:///Users/aseem/Sites/astro-xata-vercel/node_modules/astro/dist/core/endpoint/index.js:120:16)
13:28:47 [200] /api/auth/callback/resend 1008ms

auth-astro causes build to fail when building for cloudflare

Repro:
https://github.com/its-jman/auth-astro-repro

When running astro build with auth() included as an integration, the build fails saying The package "path" wasn't found on the file system....

There seems to be a import "path"; injected at the beginning of the build output which causes this error

If you have ideas I'm happy to investigate further, but I haven't found any solutions so far.

astro.config.mjs:

import { defineConfig } from 'astro/config';
import cloudflare from "@astrojs/cloudflare";
import auth from "auth-astro";

export default defineConfig({
  integrations: [auth()],
  output: "server",
  adapter: cloudflare()
});

Errors trying to use Keycloak as OIDC provider

I'm evaluating Astro for a project, I'm using Keycloak as my OIDC provider and I'm running into an issue when trying to login.

This is the contents of my auth.config.mjs:

import Keycloak from '@auth/core/providers/keycloak';
import { defineConfig } from 'auth-astro';

export default defineConfig({
  providers: [
    Keycloak({
      clientId: import.meta.env.AUTH_KEYCLOAK_ID,
      clientSecret: import.meta.env.AUTH_KEYCLOAK_SECRET,
      issuer: `${import.meta.env.KEYCLOAK_URL}/realms/agmd-frontend`,
			authorization: { params: { scope: "profile email openid" } },
			async profile(profile) {
				return {
					id: profile.sub,
					name: profile.name,
					firstname: profile.given_name,
					lastname: profile.family_name,
					email: profile.email,
				};
			},
    }),
  ],
});

This is the error I get when trying to login:

agmd-frontend-1           | [auth][error] TypeError: fetch failed
agmd-frontend-1           |     at node:internal/deps/undici/undici:12502:13
agmd-frontend-1           |     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
agmd-frontend-1           |     at async getAuthorizationUrl (file:///app/node_modules/@auth/core/lib/actions/signin/authorization-url.js:18:35)
agmd-frontend-1           |     at async Module.signIn (file:///app/node_modules/@auth/core/lib/actions/signin/index.js:10:56)
agmd-frontend-1           |     at async AuthInternal (file:///app/node_modules/@auth/core/lib/index.js:58:24)
agmd-frontend-1           |     at async Module.Auth (file:///app/node_modules/@auth/core/index.js:104:29)
agmd-frontend-1           |     at async eval (/app/node_modules/auth-astro/server.ts:25:17)
agmd-frontend-1           |     at async Module.POST (/app/node_modules/auth-astro/server.ts:47:14)
agmd-frontend-1           |     at async renderEndpoint (file:///usr/local/lib/node_modules/astro/dist/runtime/server/endpoint.js:34:20)
agmd-frontend-1           |     at async callMiddleware (file:///usr/local/lib/node_modules/astro/dist/core/middleware/callMiddleware.js:21:10)
agmd-frontend-1           | 23:13:35 [200] POST /api/auth/signin/keycloak 4ms
agmd-frontend-1           | 23:13:35 [500] /api/auth/error 4ms

My issuer URL is resolving just fine so I'm not sure what URL authjs is trying to fetch.

Any ideas on how I can fix or debug this? There's not that much information on how to use keycloak as a provider with astro and authjs.

Thanks.

getUserByAccount is not a function when trying to use an adapter

[auth][error][CallbackRouteError]: Read more at https://errors.authjs.dev#callbackrouteerror
[auth][cause]: TypeError: getUserByAccount is not a function
    at Module.callback (file:///D:/Coding/auth-astro-test/node_modules/@auth/core/lib/routes/callback.js:35:45)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async AuthInternal (file:///D:/Coding/auth-astro-test/node_modules/@auth/core/lib/index.js:64:38)
    at async Proxy.Auth (file:///D:/Coding/auth-astro-test/node_modules/@auth/core/index.js:100:30)
    at async eval (/node_modules/auth-astro/server.ts:44:17)
    at async Module.get (/node_modules/auth-astro/server.ts:65:14)
    at async call (file:///D:/Coding/auth-astro-test/node_modules/astro/dist/core/endpoint/index.js:72:20)
    at async call (file:///D:/Coding/auth-astro-test/node_modules/astro/dist/core/endpoint/dev/index.js:15:10)
    at async handleRoute (file:///D:/Coding/auth-astro-test/node_modules/astro/dist/vite-plugin-astro-server/route.js:117:20)
    at async run (file:///D:/Coding/auth-astro-test/node_modules/astro/dist/vite-plugin-astro-server/request.js:46:14)
[auth][details]: {
  "provider": "github"
}

I'm trying to set up the Email provider in Auth.js which requires a database adapter to work. No matter what adapter I try or settings I mess with I can't seem to get it to run though.
Here is the repo I've been working in if that would help at all. There is a good chance I'm just doing something wrong, this is my first time really messing with setting up Auth.js on my own and not having another tool do it for me. Let me know if any other details are needed! https://github.com/MonsteRico/auth-astro-test

AstroAuth (Receiving Undefined Options)

I am attempting to introduce auth0 as a provider in my project. Hence my auth.config.ts is as such

import Auth0 from "@auth/core/providers/auth0";
...
export default {
  providers: [
    Auth0({
      clientId: [value],
      clientSecret: [value],
    }),
  ],
}

Upon login in my user, I am receiving the error Cannot read properties of undefined (reading 'secret')
The challenge is that the API call which calls AstroAuth is receiving an empty (or undefined) authConfig options.
Upon following the configuration convention in the readme, I am not certain why this method is not receiving the values introduce in the auth.config.ts declaration. At least this what it looks like by the type (what shall be received by this method)

Any guidance, direction, recommendation or clues will be very much appreciate it.

How to use with Cloudflare Pages env vars?

Hello, you briefly mention Cloudflare Pages in the Readme, and other issues mention it too (i.e. the import 'path' vs import 'node:path' situation that was easy to patch on my end) - so I assume that this should work on CF Pages.

However, we are running into issues - our AUTH_SECRET and client ID and secrets are stored for local development in a .dev.vars file and for deployment we created them in the cloudflare pages dashboard as secrets.
We can access them in Astro component via Astro.locals.runtime.env.AUTH_SECRET successfully, but to the best of my knowledge and from what I could find, these runtime env variables are not available at the stage where the auth.config.ts file is processed and I do not seem to have access to the Cloudflare env vars through the suggested method of using import.meta.env.

What is the suggested minimal workflow to get this to work on Cloudflare Pages?

As a sidenote - the provided link to the Authjs docs ( Create your [auth configuration](https://authjs.dev/getting-started/oauth-tutorial#creating-the-server-config) file in the root of your project. ) 404's

Add support for api context callback to auth config

What's the issue?

Currently, at least for now, there is no way to add a D1 database adapter or any other ORM ones when using Cloudflare D1 as you can only access the binding / client to access the database during the runtime environment.

So when I have an auth.config.ts file to define my Auth.js config I cannot add a database at all with my use case.

What's a possible solution?

Would it be possible to add a function overload to the defineConfig handler that instead of taking in a auth config as a parameter takes in a callback handler that exposes the Astro API route context.

For example:

import { D1Adapter } from '@auth/d1-adapter';
import { defineConfig } from 'auth-astro';

export default defineConfig((ctx) => ({
	adapter: D1Adapter(ctx.locals.runtime.env.MY_DATABASE_BINDING),
	providers: [],
}));

The alternative which I have experimented with is to disable injecting endpoints but that then ended up with me re-implementing the majority of the logic in server.ts all to generate an auth config in each handler rather than passing it all the way down.

Any thoughts or feedback on this would be much appreciated

get provider source with getSession

I am using three providers at the same time. The getSession function gives me the user's ID, but it can conflict with the ID of another user in another provider. So, I created a table called users which has a user_id_provider and a user_provider column corresponding to a unique user UUID. When I want to log in and execute methods, I need the UUID. To find the actual UUID, I need the user's provider ID and the user's provider, but getSession only gives me the user's provider ID. Is there any way to get the actual provider session?

Use of JWT callback to persist additional token info results in session being null.

I am using the JWT callback to add additional information to the token like access_token, refresh_token and expires_at as outlined in the Auth.js docs here for the JWT callback and here for refresh token rotation.

While I have this working fine using Next.js 13 and Qwik, I have been struggling with Astro. As soon as I include logic in the JWT callback to enhance the token the session ends up being empty. When I remove the enhancement in the JWT callback the default session data is returned.

No errors are reported in the console. I am using the Azure AD provider.

export default {
  secret: import.meta.env.AUTH_SECRET,
  trustHost: true,
  providers: [
    AzureAd({
      clientId: import.meta.env.AZURE_CLIENT_ID,
      clientSecret: import.meta.env.AZURE_CLIENT_SECRET,
      tenantId: import.meta.env.AZURE_TENANT_ID,
      authorization: {
        params: {
          scope: "...removed...",
        },
      },
    }),
  ] as Provider[],

  callbacks: {
    async session({ session, token }) {
      if (token) {
        session.access_token = token.access_token;
      }
      return session;
    },
    async jwt({ token, user, account, profile, isNewUser }) {
      if (account) {
        token.access_token = account.access_token;
      }
      return token;
    },
  },
};

If I then check session via .../api/auth/session it returns an empty object.

If I comment out token.access_token = account.access_token; in the JWT callback the default session data is returned.

Same issue occurs using both JS and TS projects.

Please help 😀

Discord provider is missing user.id in the session object

If I log the session, I only get this JSON Object back and the user.id is missing for some reason

Session Object :

{
  user: {
    name: 'staku',
    email: '[email protected]',
    image: 'https://cdn.discordapp.com/avatars/444560731300429844/28ef1f92c9bc92f919fa2ea5182ecb16.png'
  },
  expires: '2024-03-11T01:46:51.264Z'
}

auth.config.ts :

import Discord from '@auth/core/providers/discord';

import { defineConfig } from 'auth-astro';

export default defineConfig({
	providers: [
		Discord({
			clientId: import.meta.env.DISCORD_CLIENT_ID,
			clientSecret: import.meta.env.DISCORD_CLIENT_SECRET,
		}),
	],
});

Credentials Provider: Redirect false option response

Greetings,

Thank you for writing up this great package.
Currently, I am using this package to handle user auth using email and password implementation (Credentials provider), with the redirect option set to false.

I've setup my config like this:

auth-astro.d.ts

import NextAuth, { DefaultSession } from '@auth/core';
import { JWT } from '@auth/core/jwt';

declare module '@auth/core/types' {
  interface Session {
    accessToken: string;
  }
  interface User {
    accessToken: string;
  }
}

declare module '@auth/core/jwt' {
  interface JWT {
    accessToken: string;
  }
}

pages/api/auth/[...astroAuth].ts

import Credentials from '@auth/core/providers/credentials';
import { AstroAuth, type AstroAuthConfig } from 'auth-astro';

import { logIn } from '../../../apis';

// Issue with `cookie` package with `pnpm`.
// https://github.com/nowaythatworked/auth-astro/issues/9
export const authOpts: AstroAuthConfig = {
  providers: [
    Credentials({
      name: 'Credentials',
      credentials: {
        email: {
          label: 'Email',
          type: 'text',
          placeholder: '[email protected]',
        },
        password: { label: 'Password', type: 'password' },
      },
      async authorize(credentials) {
        const { success, message, token, user } = await logIn(
          credentials.email as string,
          credentials.password as string,
        );
        if (!success) {
          throw new Error(message); // I expect this to be propagated to the UI, but it did not.
        }
        return { ...user, accessToken: token };
      },
    }),
  ],
  callbacks: {
    async jwt({ token, user }) {
      // We forward the access token retrieve from API to the JWT token.
      if (user) {
        token.accessToken = user.accessToken;
      }
      return token;
    },
    async session({ session, token }) {
      // We forward the access token to the client.
      session.accessToken = token.accessToken;
      return session;
    },
  },
  secret: import.meta.env.SECRET,
};

export const { get, post } = AstroAuth(authOpts);

In my client code, I have a simple login button to test the feature.

index.astro

<button id="login">Login Now!</button>

<script>
  const { signIn } = await import('auth-astro/client');
  document.getElementById('login')?.addEventListener('click', async () => {
    const resp = await signIn('credentials', {
      redirect: false,
      email: '[email protected]',
      password: 'MyPassword',
    });
    console.log(resp); // I expect this to follow the shape based on the documentation https://next-auth.js.org/getting-started/client#using-the-redirect-false-option, to handle errors like incorrect password and etc.
  });
</script>

It seems like the response is not according to the documentation. As a side note, I am also getting typescript error:

Argument of type '{ redirect: boolean; email: string; password: string; }' is not assignable to parameter of type 'AstroSignInOptions'.
  Object literal may only specify known properties, and 'redirect' does not exist in type 'AstroSignInOptions'.ts(2345)

Thank you.

"astro add auth-astro" result in Cannot find module '\C:\projects\test\node_modules\auth-astro\src\api\[...auth].ts'

Using astro add auth-astro to add the auth to my project on Windows using the recommended process and base settings straight out of the box, then I get the following error.

npm run dev

> [email protected] dev
> astro dev

 error   Cannot find module '\C:\projects\test\node_modules\auth-astro\src\api\[...auth].ts'
  Require stack:
  - C:\projects\test\node_modules\astro\dist\core\routing\manifest\create.js
Error: Cannot find module '\C:\projects\test\node_modules\auth-astro\src\api\[...auth].ts'
Require stack:
- C:\projects\test\node_modules\astro\dist\core\routing\manifest\create.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1075:15)
    at Function.resolve (node:internal/modules/cjs/helpers:116:19)
    at injectedRouteToItem (file:///C:/projects/test/node_modules/astro/dist/core/routing/manifest/create.js:123:29)
    at file:///C:/projects/test/node_modules/astro/dist/core/routing/manifest/create.js:272:18
    at Array.sort (<anonymous>)
    at createRouteManifest (file:///C:/projects/test/node_modules/astro/dist/core/routing/manifest/create.js:269:56)
    at configureServer (file:///C:/projects/test/node_modules/astro/dist/vite-plugin-astro-server/plugin.js:18:22)
    at _createServer (file:///C:/projects/test/node_modules/vite/dist/node/chunks/dep-e8f070e8.js:63461:30)
    at async createContainer (file:///C:/projects/test/node_modules/astro/dist/core/dev/container.js:49:22)

I presume it's the initial \ as if I follow the path it does exist.

I've tried to do some digging to figure out the root cause but I have been unable to get to figure it out.

My Package.json

{
  "name": "astro-cactus",
  "version": "2.0.2",
  "private": false,
  "type": "module",
  "scripts": {
  	"setup": "npx vite-node --config setup.vite.config.js setup.ts",
  	"dev": "astro dev",
  	"start": "astro dev",
  	"sync": "astro sync",
  	"build": "prisma generate && astro build",
  	"preview": "astro preview",
  	"format": "prettier -w ./src ./src/**/*.astro"
  },
  "devDependencies": {
  	"@astrojs/image": "0.13.0",
  	"@astrojs/mdx": "^0.15.1",
  	"@astrojs/sitemap": "^1.0.0",
  	"@astrojs/tailwind": "3.0.0",
  	"@import-meta-env/unplugin": "^0.4.7",
  	"@tailwindcss/aspect-ratio": "^0.4.2",
  	"@tailwindcss/line-clamp": "^0.4.2",
  	"@tailwindcss/typography": "^0.5.8",
  	"@types/eslint": "^8.4.10",
  	"@types/prettier": "^2.7.2",
  	"@types/sharp": "^0.31.1",
  	"@typescript-eslint/eslint-plugin": "^5.48.0",
  	"@typescript-eslint/parser": "^5.48.0",
  	"astro-eslint-parser": "^0.11.0",
  	"autoprefixer": "^10.4.13",
  	"eslint": "^8.32.0",
  	"eslint-config-prettier": "^8.6.0",
  	"eslint-import-resolver-typescript": "^3.5.2",
  	"eslint-plugin-astro": "^0.23.0",
  	"eslint-plugin-import": "^2.26.0",
  	"eslint-plugin-jsx-a11y": "^6.7.1",
  	"eslint-plugin-prettier": "^4.2.1",
  	"nodemailer": "^6.9.3",
  	"postcss": "^8.4.21",
  	"postcss-html": "^1.5.0",
  	"prettier": "^2.8.3",
  	"prettier-plugin-astro": "0.8.0",
  	"prettier-plugin-tailwindcss": "^0.2.2",
  	"stylelint": "^14.16.1",
  	"stylelint-config-prettier": "^9.0.4",
  	"stylelint-config-standard": "^29.0.0",
  	"tailwindcss": "^3.2.4",
  	"typescript": "^4.9.4"
  },
  "dependencies": {
  	"@astrojs/netlify": "^2.1.2",
  	"@astrojs/prefetch": "^0.1.1",
  	"@astrojs/react": "^2.0.2",
  	"@astrojs/rss": "^2.0.0",
  	"@auth/core": "^0.5.1",
  	"@netlify/planetscale": "^1.0.0",
  	"@planetscale/database": "^1.6.0",
  	"@prisma/client": "^4.15.0",
  	"@resvg/resvg-js": "^2.4.1",
  	"@types/jsonwebtoken": "^9.0.2",
  	"@types/react": "^18.0.27",
  	"@types/react-dom": "^18.0.10",
  	"@types/spotify-api": "^0.0.20",
  	"astro": "^2.6.3",
  	"auth-astro": "^3.0.1",
  	"dotenv": "^16.0.3",
  	"emoji-unicode-map": "^1.1.11",
  	"jsdom": "^22.0.0",
  	"jsonwebtoken": "^9.0.0",
  	"node-fetch": "^3.3.1",
  	"prisma": "^4.15.0",
  	"react": "^18.2.0",
  	"react-dom": "^18.2.0",
  	"reflect-metadata": "^0.1.13",
  	"satori": "0.1.2",
  	"satori-html": "^0.3.2",
  	"sharp": "^0.31.3",
  	"swr": "^2.0.3"
  }
}

Please let me know any other information you'd require and I'll get them to you asap

Typo in README

Note: If you´re using pnpm you must also install cookie: pnpm i cookie

That ´ should be a . Also, pnpm should be pnpm.

Note: If you’re using pnpm you must also install cookie: pnpm i cookie

Not that big a deal, just thought I'd let you know

Cloudflare deployment fails on 2.0.1

When using [email protected] the build fails on Cloudflare with the following error:

11:00:48.524 | 10:00:48 AM [build] Rearranging server assets...
-- | --
11:00:48.578 | ✘ [ERROR] Could not resolve "node:crypto"
11:00:48.578 |  
11:00:48.579 | dist/$server_build/_worker.mjs:12:62:
11:00:48.579 | 12 │ ...ss                                         */import 'node:crypto';
11:00:48.579 | ╵                                                        ~~~~~~~~~~~~~
11:00:48.579 |  
11:00:48.579 | The package "node:crypto" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
11:00:48.580 |  
11:00:48.593 | ✘ [ERROR] Could not resolve "node:crypto"
11:00:48.593 |  
11:00:48.593 | dist/$server_build/chunks/pages/all.874714f0.mjs:6:68:
11:00:48.593 | 6 │ ...                                */import crypto from 'node:crypto';
11:00:48.593 | ╵                                                         ~~~~~~~~~~~~~
11:00:48.594 |  
11:00:48.594 | The package "node:crypto" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
11:00:48.594 |  
11:00:48.822 | error   Could not resolve "node:crypto"
11:00:48.822 | File:
11:00:48.823 | dist/$server_build/_worker.mjs:12:62
11:00:48.823 | Code:
11:00:48.823 | 11 \| import 'set-cookie-parser';
11:00:48.823 | > 12 \| /* empty css                                         */import 'node:crypto';
11:00:48.823 | \|                                                              ^
11:00:48.824 | 14 \| const isNode = typeof process === "object" && Object.prototype.toString.call(process) === "[object process]";
11:00:48.824 | 15 \| function getProcessEnvProxy() {
11:00:48.847 | Failed: build command exited with code: 1
11:00:52.798 | Failed: error occurred while running build command

2.0.0 builds just fine. I've added some logging and indeed the NODE_ENV = 'production'.

Cannot find module '[node_modules path]/auth-astro/src/api/[...auth].ts'

When following the examples doc I get this error:

 error   Cannot find module 'file:[my dev path]/node_modules/auth-astro/src/api/[...auth].ts'
  Require stack:
  - [my dev path]/node_modules/astro/dist/core/routing/manifest/create.js

Deleted node_modules and reinstalled with npm i, hasn't seemed to work. Strange error, the file is definitely there, can't work out what the issue is. With Astro 2.1.9.

Endpoints that should set multiple cookies only set one, causing e.g. callbackUrl to be dropped

I ran into this issue while attempting to hook up Discord auth using auth-astro (v4.1.0). I found that the callback-url cookie was never set - and thus callbackUrl was not honored, even for its default behavior. Ordinarily it would be set in the provider endpoint response, which also sets the pkce.code_verifier cookie.

This package has code in server.ts specifically designed to prioritize returning the pkce.code_verifier or session-token cookie. The exact reason for this code is unclear (it vaguely references an issue in @auth/solid-js but does not specify an exact issue id or URL), but I suspect it exists for this same underlying reason, since IIRC when I removed that code while debugging, the provider endpoint instead properly set the callback-url cookie but then didn't set the pkce.code_verifier cookie, which prevented sign-in from working. So I'm guessing that code was added to ensure that auth endpoints would work, at the possible expense of peripheral features such as redirecting to the desired URL.

The underlying problem is that @auth/core relies on the fetch Response and Headers APIs, and the Headers API provides no way of correctly setting multiple separate Set-Cookie headers (which I guess is arguably beyond its scope as a client-side API). There is an append API, but that concatenates multiple values together within a single header, comma-delimited, which is not valid for Set-Cookie, and browsers end up either incorrectly munging its value or dropping all but the first cookie.

Instead of preferring one cookie over another, we should rely directly on Astro's own cookie APIs, which allow setting multiple separate Set-Cookie headers. I have a patch and branch for this; I'll open a PR shortly.

How to setup with multiple providers?

https://blog.otterlord.dev/post/authjs-astro/

I did simply one based on the above link, and it looks like setting up an additional provider overwrites the SignIn component with the last one.

---
import Layout from '../layouts/Layout.astro';
import type { Session } from '@auth/core/types';
import { Auth, SignIn, SignOut } from 'auth-astro/components';
import { authOpts } from './api/auth/[...astroAuth]';
---

<Layout title="Welcome to Astro Auth">
  <Auth authOpts={authOpts}>
    {
      (session: Session | null) => 
      <main>
        <h1>Astro + AuthJS</h1>
        <p>
          <a href="/protected">Protected Route</a>
        </p>
        {
          session === null
          ? <>
              <SignIn provider="github">Login</SignIn> // when it click, it's working with kakao provider
              <SignIn provider="kakao">Login with Kakao</SignIn> // not working
            </>
          : <SignOut>Logout</SignOut>
        }
        <p>
          {session ? `Logged in as ${session.user?.name}` : 'Not logged in'}
        </p>
      </main>
    }
  </Auth>
</Layout>

I haven't tested it with other providers yet, could it be a problem that it's imported from the next-auth library?
like below,

...
import KakaoProvider from "next-auth/providers/kakao"
...

Should support `output=hybrid` + `prerender=false`?

Of course the page that uses getSession should be SSR. But it seems that output=hybrid with export const prerender=false on the every page that uses auth-astro still leads to the following error (when you login or logout - i.e. when you use auth endpoints):

image

Which I guess I understand why - auth-astro need to inject those auth endpoints but in hybrid mode then are by default SSG which they shouldn't. Putting export const prerender=false on the app pages do not really change anything as they don't affect the endpoint pages - at least that's my understanding.

It is annoying, because the majority of my pages are SSG and only a few pages are SSR and they needs user to login and view. I am doing ok by switching output=server and putting export const prerender=true to all SSG pages (opt in instead of opt out) but I wonder if there is a better workaround / built-in support.

Can't use getSession inside Vercel edge middleware

Whenever I reference the package inside the edge middleware and I try to build I get this error:

You can mark the path "auth:config"
  as external to exclude it from the
  bundle, which will remove this
  error and leave the unresolved path
  in the bundle.

Could not resolve "auth:config"

Error on cancel login

I'm using Google provider, but when i click on cancel login i return to my site but to a inexistent url, this is a video for another site when use twitch provider but with the same error access_denied

202406061147.mp4

Lower case endpoint names are deprecated and will not be supported in Astro 4.0

Hi, nice work and thanks for this integration.
Not really an issue, just to let you know that this alert message appears on new Astro v3 :

[astro] Lower case endpoint names are deprecated and will not be supported in Astro 4.0. Rename the endpoint get to GET.

  • server.ts

(line 111) async get(event: any) {} async GET(event: any) {}
(line 114) async post(event: any) {} async POST(event: any) {}

  • ./src/api/[...auth].ts

(line 3) export const { get, post } = AstroAuth() export const { GET, POST } = AstroAuth()

The message no longer appears after these modifications
Thanks again

"Provider "auth0" is missing both `issuer` and `authorization` endpoint config. At least one of them is required.. Read more at https://errors.authjs.dev#invalidendpoints"

I already spoke with @TheOtterlord about this problem in his discord server but wants to open an issue for remainder and progress. For who doesn't know about it:

When ı first tried to use auth-astro , as an early package ı had some problems but somehow worked. I got some information about my user. After 3-4 day, ı want to tried to use for my project and wants to build an mini project for learn set up correctly. Added with astro add and configured for usage. Problem is, this time gave me this error:

Provider "auth0" is missing both issuer and authorization endpoint config. At least one of them is required.. Read more at https://errors.authjs.dev#invalidendpoints

I spoke with @TheOtterlord and we tried to work around with issuer: "" but didn't worked. Tried to give auth endpoint with authorization endpoint prop but still same. Idk this happened right now and didn't throw error when ı first tried. Auth-astro didn't merged any commit in this time, ı think it's about authjs changes.


Going to add some schreenshots for my really mini setup:

astro.config.mjs
Screenshot from 2023-04-17 10-38-11

index.astro
Screenshot from 2023-04-17 11-08-37

Make server origin configurable

We have a problem with the server origin: When we run our astro application in aws with cloudfront, auth.js always gets the "inner origin" (api gateway url or lambda function url) and not the cloudfront url.

Looking at the nuxt auth middlewares, they make the server origin configurable. See for example nuxt-auth: getServerOrigin.

We need something similar to make astro work with auth-astro in aws. Any suggestions on where to integrate this? I'm willing to look into this if requested.

GetToken() from auth-core returns null (with fix that works on my machine at least)

I see there is a mismatch between the session token name for auth-astro and the expected token name in auth-core.

the getToken() is expecting either: __Secure-auth.session-token or auth.session-token, if you are running on https or http. But the actually default token names with auth-astro is __Secure-authjs.session-token or authjs.session-token

Got it working by overriding the cookieName to the default naming of cookies in auth-astro when calling getToken()

export async function getJwtToken(req: Request) {
    const secret = import.meta.env.AUTH_SECRET
    const salt = import.meta.env.AUTH_COOKIE

    const decoded = getToken({
        req: req,
        // defaults to:
        // cookieName = secureCookie ? "__Secure-auth.session-token" : "auth.session-token",
        // Override, as naming should be __Secure-authjs.session-token for prod, authjs.session-token for dev
        cookieName: import.meta.env.AUTH_COOKIE,
        secret: secret,
        salt: salt // If you have a salt, provide it here
    })

    return decoded
}

Reference from auth-core (getToken())

export async function getToken<R extends boolean = false>(
  params: GetTokenParams<R>
): Promise<R extends true ? string : JWT | null>
export async function getToken(
  params: GetTokenParams
): Promise<string | JWT | null> {
  const {
    secureCookie,
   cookieName = secureCookie
      ? "__Secure-auth.session-token"
      : "auth.session-token",
    decode: _decode = decode,
    salt = cookieName,
    secret,
    logger = console,
    raw,
    req,
  } = params

  if (!req) throw new Error("Must pass `req` to JWT getToken()")
  if (!secret)
    throw new MissingSecret("Must pass `secret` if not set to JWT getToken()")

  const headers =
    req.headers instanceof Headers ? req.headers : new Headers(req.headers)

  const sessionStore = new SessionStore(
    { name: cookieName, options: { secure: secureCookie } },
    parse(headers.get("cookie") ?? ""),
    logger
  )

  let token = sessionStore.value

  const authorizationHeader = headers.get("authorization")

  if (!token && authorizationHeader?.split(" ")[0] === "Bearer") {
    const urlEncodedToken = authorizationHeader.split(" ")[1]
    token = decodeURIComponent(urlEncodedToken)
  }

  if (!token) return null

  if (raw) return token

  try {
    return await _decode({ token, secret, salt })
  } catch {
    return null
  }
}

AstroAuthHandler attempts to modify immutable headers

Using Credentials Provider with auth-astro along with the default signin page to handle authentication against an existing API that returns a cookie. This invokes AstroAuthHandler in server.ts, which attempts to extract cookies from the included with the response provided by the call to Auth. This causes a CredentialsSignin error because the attempt to delete the set-cookie header fails due to the headers being immutable.

I think this can be fixed by extracting the headers into a new object, extracting the cookies and removing the set-cookie header, and then creating a new response with the returned body and modified headers.

I patched the module in my local environment and it seems to work:

function AstroAuthHandler(prefix: string, options = authConfig) {
	return async ({ cookies, request }: APIContext) => {
		const url = new URL(request.url)
		const action = url.pathname.slice(prefix.length + 1).split('/')[0] as AuthAction

		if (!actions.includes(action) || !url.pathname.startsWith(prefix + '/')) return

		const res = await Auth(request, options)
		if (['callback', 'signin', 'signout'].includes(action)) {
			// Properly handle multiple Set-Cookie headers (they can't be concatenated in one)
			const headers = new Headers(res.headers)
			headers.getSetCookie().forEach((cookie) => {
				const { name, value, ...options } = parseString(cookie)
				// Astro's typings are more explicit than @types/set-cookie-parser for sameSite
				cookies.set(name, value, options as Parameters<(typeof cookies)['set']>[2])
			})
			headers.delete('Set-Cookie')
			return new Response(res.body, { headers })
		}
		return res
	}
}

I hope to submit a PR with this fix as soon as I get the module built in my environment so I can run tests.

auth-astro components not being found

I'm getting some errors when trying to access the SignIn and SignOut components.

The code

---
import { SignIn, SignOut } from 'auth-astro/components';
---

<section>
  <h1 class="text-h1">Login</h1>
  <SignIn provider="google" />
  <SignOut />
</section>

The errors

Server Error (running on dev): 404 /h-astro/src/components/SignIn.astro

Client Error: GET p://localhost:3000/h-astro/src/components/SignIn.astro?astro&type=script&index=0&lang.ts net::ERR_ABORTED 404 (Not Found)

The Config

import { defineConfig } from 'astro/config';
import solid from '@astrojs/solid-js';
import react from '@astrojs/react';
import partytown from '@astrojs/partytown';
import sitemap from '@astrojs/sitemap';
import tailwind from '@astrojs/tailwind';
import cloudflare from '@astrojs/cloudflare';
import Google from '@auth/core/providers/google';
import auth from 'auth-astro';
import { loadEnv } from 'vite';

const env = loadEnv('production', process.cwd(), '');

export default defineConfig({
  outDir: '...',
  integrations: [
    react(),
    solid(),
    partytown(),
    sitemap(),
    tailwind(),
    auth({
      providers: [
        Google({
          clientId: env.GOOGLE_CLIENT_ID,
          clientSecret: env.GOOGLE_CLIENT_SECRET,
        }),
      ],
    }),
  ],
  output: 'server',
  adapter: cloudflare({ mode: 'advanced' }),
});

Using pages/api instead of astro plugin

Hi there,

I recently installed this package at version 1.0.5 and set it up using the manual API route approach, similar to NextAuth. However, it seems that the recommended method now is to use the Astro plugin system.

I was wondering if it is still possible to use the manual API route setup instead of the Astro plugin system? I prefer the manual approach and would like to continue using it if possible.

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.