qwik icon indicating copy to clipboard operation
qwik copied to clipboard

[๐Ÿž] Cannot use environment variables in Auth plugin on Vercel Edge Functions

Open samijaber opened this issue 1 year ago โ€ข 9 comments

Which component is affected?

Qwik City (routing)

Describe the bug

env.get() is not able to read enviroment variables set in Vercel's UI. I only tested this in serverAuth$, the qwik-auth helper method. Not sure what the scope is exactly.

I also tested process.env while I was at it and it prints nothing in Vercel, but loads of stuff in my local machine (although that might be intended by Vercel and/or QwikCity).

Reproduction

https://github.com/samijaber/qwik-env-var-vercel

Steps to reproduce

  • npm create qwik@latest
  • pnpm install
  • pnpm qwik add auth
  • pnpm qwik add vercel-edge
  • add if (!env.get("AUTH_SECRET")) throw new Error("Missing AUTH_SECRET"); to [email protected]
import { serverAuth$ } from "@builder.io/qwik-auth";
import GitHub from "@auth/core/providers/github";
import type { Provider } from "@auth/core/providers";

export const { onRequest, useAuthSession, useAuthSignin, useAuthSignout } =
  serverAuth$(({ env }) => {
+    if (!env.get("AUTH_SECRET")) throw new Error("Missing AUTH_SECRET");
    return {
      secret: env.get("AUTH_SECRET"),
      trustHost: true,
      providers: [
        GitHub({
          clientId: env.get("GITHUB_ID")!,
          clientSecret: env.get("GITHUB_SECRET")!,
        }),
      ] as Provider[],
    };
  });
  • deploy project to Vercel and add the Environment Variable: CleanShot 2023-04-28 at 16 20 41@2x

  • go to project URL. In my case it's https://qwik-env-var-vercel.vercel.app/ CleanShot 2023-04-28 at 16 23 36@2x CleanShot 2023-04-28 at 16 23 52@2x

env.get() is returning undefined

System Info

System:
    OS: macOS 12.1
    CPU: (10) arm64 Apple M1 Max
    Memory: 4.16 GB / 32.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 18.13.0 - ~/.asdf/installs/nodejs/18.13.0/bin/node
    Yarn: 1.22.19 - ~/.asdf/installs/nodejs/18.13.0/bin/yarn
    npm: 8.19.3 - ~/.asdf/plugins/nodejs/shims/npm
    Watchman: 2022.02.28.00 - /opt/homebrew/bin/watchman
  Browsers:
    Brave Browser: 112.1.50.121
    Chrome: 112.0.5615.137
    Firefox: 109.0.1
    Safari: 15.2
  npmPackages:
    @builder.io/qwik: 0.105.0 => 0.105.0 
    @builder.io/qwik-auth: ~0.1.0 => 0.1.0 
    @builder.io/qwik-city: ~0.104.0 => 0.104.0 
    undici: 5.22.0 => 5.22.0 
    vite: 4.3.3 => 4.3.3

Additional Information

No response

samijaber avatar Apr 28 '23 19:04 samijaber

I find vercel env variables super buggy, might need to take a look, i beat it's a vercel bug

manucorporat avatar Apr 29 '23 15:04 manucorporat

It's also not likely an auth integration issue specifically.

ulic75 avatar Apr 30 '23 19:04 ulic75

I am having an identical error with env.get. Spent some time debugging and also found that process.env did not work. Same exact code worked fine on Cloudflare pages, so probably a problem with the Vercel integration.

joshdchang avatar May 04 '23 09:05 joshdchang

I have very similar issues trying to connect @vercel/kv with Qwik as env variables just don't pop out in neither process.env nor import.meta.env in server side code

stepaniukm avatar May 04 '23 12:05 stepaniukm

@samijaber @manucorporat

Hello, a solution to this problem is the following:


define: {
       'process.env': JSON.stringify(process.env)
     }

import { defineConfig } from 'vite';
import { qwikVite } from '@builder.io/qwik/optimizer';
import { qwikCity } from '@builder.io/qwik-city/vite';
import tsconfigPaths from 'vite-tsconfig-paths';

export default defineConfig(({mode}) => {
   return {
     plugins: [qwikCity(), qwikVite(), tsconfigPaths()],
     define: {
       'process.env': JSON.stringify(process.env)
     },
     preview: {
       headers: {
         'Cache-Control': 'public, max-age=600',
       },
     },
   };
});

I had the same problem with this solution it works.

I don't know if this brings any security problem with the environment variables

With this solution the authentication works fine in vercel @ulic75

Author: https://discord.com/channels/842438759945601056/1082474458599657473

gabriiels avatar May 04 '23 17:05 gabriiels

Fyi, I posted the above link (https://discord.com/channels/842438759945601056/1082474458599657473) as quick and dirty to get me going, but, as mentioned, it would be best for somebody on @builder team to take a look because I cannot attest to security implications w/ this approach -- one way or the other, and it's something I'll take a closer look at should I decide to take app to production. This is an issue @builder team should prioritize IMHO since Vercel edge adapter is one of the supported/featured adapters and w/o env vars, real-world apps aren't going to get very far.

rolanday avatar May 12 '23 06:05 rolanday

Just letting you know, cause I yesterday revisited the problem and suddenly code worked on a Vercel with me changing nothing at all, only thing Iโ€™ve done was redeploying my code.

stepaniukm avatar May 12 '23 08:05 stepaniukm

Doesn't instill a lot of confidence to hear suddenly working -- need to understand why. I can confirm from an unrelated test performed earlier this evening that simply deploying to Vercel edge using Qwik Vercel Edge adapter results in no env vars being set on process. IMO, this is something the adapter should ideally handle "out-of-box" w/ no add'l configuration required, or at least blessed guidance on how to set so we're not needing to guess how to set something as fundamental as environment vars (or just say Vercel edge adapter not supported).

rolanday avatar May 12 '23 09:05 rolanday

Wish I had time to dig in and confirm it, but I suspect this issue isn't directly related to qwik-auth (auth plugin) that just happens to be how it was discovered.

ulic75 avatar May 12 '23 14:05 ulic75

This is confusing, because the vercel runtime is not doing what's expected

manucorporat avatar May 14 '23 12:05 manucorporat

Just letting you know, cause I yesterday revisited the problem and suddenly code worked on a Vercel with me changing nothing at all, only thing Iโ€™ve done was redeploying my code.

I have the same experience, their env system is buggy, not sure why it works sometimes and sometimes it doesnt, without changing anything

manucorporat avatar May 14 '23 12:05 manucorporat

i have no idea how to solve this issue, we are implementing the adapter exactly how described by vercel documentation. their runtime is not setting the environment variables (sometimes).

manucorporat avatar May 14 '23 12:05 manucorporat

Curious how are you setting the environment variables?

manucorporat avatar May 14 '23 12:05 manucorporat

I use 2 ways, one was using connect with storages which auto-injected envs into my project, second was adding manually some test envs via Vercel UI. The result was basically the same, all variables were present in the dashboard, but back then code didn't work and now it works.

stepaniukm avatar May 15 '23 13:05 stepaniukm

CCing @Schniz maybe he could help with this

shairez avatar May 18 '23 09:05 shairez

Yeah, I don't know what he did on the Vercel site, but now the behavior is actually predictable, as when logging process.env I consistently get all needed env variables.

stepaniukm avatar May 19 '23 20:05 stepaniukm

@stepaniukm we will soon release a changelog :)

Schniz avatar May 19 '23 20:05 Schniz

https://vercel.com/changelog/more-flexible-environment-variables-in-edge-functions-and-middleware

I think this issue can be closed now ๐Ÿ™

Schniz avatar May 25 '23 05:05 Schniz

@manucorporat can we confirm that this issue is fixed?

hamatoyogi avatar May 29 '23 07:05 hamatoyogi

env.get("AUTH") will work, process.env depends on #4361 (or similar approaches)

Schniz avatar May 29 '23 08:05 Schniz

I spent an entire evening pulling my hair on this issue but with vercel postgres. @vercel/postgres uses process.env.POSTGRES_URL (which is undefined in production). This worked for me (explicitly setting the connection string instead of relying on implicit behavior):

import { drizzle } from "drizzle-orm/vercel-postgres";
import { createPool } from "@vercel/postgres";
import * as schema from "./schema";

const pool = createPool({
  connectionString: process.env["POSTGRES_URL"],  // Use bracket syntax, not dot notation! 
});

export const db = drizzle(pool, { schema, });

jesperp avatar Aug 22 '23 12:08 jesperp

Thanks @jesperp So it's something related to Vercel environment. I found this useful change log, I saw this post was mentioned by @Schniz few message ago.

TLDR: Accessing process.env is no longer restricted to be statically analyzable. This means that, for example, you can now compute variable names such as process.env[${PREFIX}_SECRET]

gioboa avatar Aug 22 '23 14:08 gioboa

I cerated a new fresh Qwik 1.2.7 application and I deployed it with Vercel Edge. I can confirm that only with process.env['<env_name>'] works.

gioboa avatar Aug 22 '23 17:08 gioboa

As mentioned previously, itโ€™s probably related to the Qwik Vercel Edge adapter. Internally at Vercel we do not distinct between process.env.VAR and process.env[โ€˜VARโ€™], they are the same because we simply populate process.env as an object. As mentioned a while ago, I believe that the compiler configurations happening at Vite (configured by the adapter) are misconfigured

Schniz avatar Aug 22 '23 18:08 Schniz

Having the ability to use env vars like that process.env['<env_name>'] is good enough to close this issue. I will create a PR to add this information in the Qwik docs.

gioboa avatar Aug 23 '23 17:08 gioboa