Locally, when I run my Payload environment in dev mode, all URLs work perfectly fine.
When I build payload on my server and start it, many actions are coming back as unauthorized.
I am able to log-in fine, but for instance the following requests 401:
- /api/_preferences/locale
- /api/pages?locale=en&depth=0&draft=true&invoke=949a1387-f616-4c8b-a5c0-458aca5bfec6
- /api/_preferences/pages-list
- /api/_preferences/categories-list
- /api/_preferences/media-list
Another detail that I see is that the message response holds a message of "Unauthorized, you must be logged in to make this request.".
Also, I don't see these requests actually being made in dev mode. I see the GET request versions of these requests, which succeed in both environments; but on the server there are also POST versions of these requests which are 401'ing.
hey
@1049775120559898725, just fyi, I figured it'd be better to split this off into its own post since it seems its a bit different from the post I was adding onto. I really appreciate the help you've provided thus far. ๐โโ๏ธ
Can you pull up burpsuite and remake your API request?
never heard of burpsuite
or anyway you can check the values/cookies being used while calling for the endpoint(s)?
sure, I'll check those out
Yeah network tab inside devtools will do wonders here
one of my favorite tools lol
here's the request headers for one of the requests btw:
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 14
Content-Type: application/json
Cookie: payload-token=<redacted>
Host: <redacted>
Origin: https://<redacted>
Pragma: no-cache
Referer: https://<redacted>/admin
sec-ch-ua: "Chromium";v="112", "Google Chrome";v="112", "Not:A-Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36
in case it's helpful
i see a
payload-token
cookie as well
yeah it's there if you're logged in
so that's your request. Did that request 401?
it did, the response body was
{"errors":[{"message":"Unauthorized, you must be logged in to make this request."}]}
response headers
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, Content-Encoding, x-apollo-tracing
Access-Control-Allow-Methods: PUT, PATCH, POST, GET, DELETE, OPTIONS
Connection: keep-alive
Content-Language: en
Content-Length: 84
Content-Type: application/json; charset=utf-8
Date: Tue, 18 Apr 2023 13:04:08 GMT
ETag: W/"54-VwIDOKGPAda99KAJF2yRyy4FL7I"
Server: nginx
Vary: X-HTTP-Method-Override, Accept-Encoding
X-Powered-By: Express
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 472
X-RateLimit-Reset: 1681823061
Are you using any kind of auth right now?
aside from the default login portal that is
i ended up following the example of adding roles to users, but this was an issue prior to that
was hoping following the guide would do it for me. again, works locally though
I wonder if it's a CORS issue somewhere.
I set CORS to
cors: "*",
to rule that out
this is the last thing I'll pitch before running out of ideas. Can you compare /api/access on dev and prod?
sure
let's see...
๐
both respond with 200 OK...
the server one has these headers in addition to the normal ones dev has:
Cache-Control: max-age=2592000
Cache-Control: public
Request headers don't appear to have a relevant difference...
The response bodies are identical. All permission values are set to true.
So there's cache control headers set somewhere. This shouldn't impact you, but just in case, can you log out, clear cookie/cache for your prod in the browser, then log in? I'm sure you've done it but I just wanted to check ๐
It's the IT guy in me
totally understand. trying that out
ok.. cleared cache.. cookies... also went ahead and cleared host cache (that sometimes bites me too)..
logged back in
still 401'ing
like, the dashboard loads but when it attempts to make those POST requests, that's when it fails
still can't create or save anything
๐ค
one thing i did notice is that the auth cookie didn't go away when I logged out. not sure if that's normal
Are the PATCH requests coming through 200?
these are your save requests
attempted to enable api keys on my user to test a save. got a 403 Forbidden this time
I'd reset all of the RBAC just to test by default if you're doing okay on prod
but you did mention you had problems even before implementing rbac right?
yeah. I think at one point it was all working fine when I tried allowing everything on the user collection.. but that obviously didn't seem like a good idea
but that might be a hint i assume
i'll try that again just to confirm
interesting
I set all the access values to
() => true
, and it allows me to save, however I still get a bunch of 401's in my network requests like I've been seeing
still can't add to another collection
makes me wonder if I need to be setting access control to all collections because in prod-mode it's required or something?
not sure how you deal with a request like
/api/_preferences/locale
though
feels like something fundamental is off
guess i could try just removing the cache headers to make it more like dev
yeah, removing the cache headers didn't change anything ๐ค
any ideas? ๐ฆ
just for sanity, i'm going ahead and running just a fresh installation of payload on the server
just an update:
- npx create-payload-app w/ blog template
- yarn build
- yarn serve
- updated vhost to point to payload app
- hanging on cors due to domain not matching server url
- changed server url, rebuilt and reserved
- no permissions issues witnessed
- added locales
- no permissions issues witnessed
- added webpack overrides
- no permissions issues witnessed
- installed @payloadcms/plugin-form-builder
- no permissions issues witnessed
- installed @payloadcms/plugin-cloud-storage
- no permissions issues witnessed
based on that, I'm now just simplifying our active repo's configs to see if something in our collection definitions are the problem
ok, think i'm finally getting somewhere
it looks like the _preferences document in the control test is populated with details, while in my server instance, it is empty
trying to figure out how to get it to populate appropriately..
matching up my dependency versions to the control-test i made...
Hey all!
Sorry, i have two accounts (work/personal)
So i didn't see the ping
all good
Hmmm
Did you confirm that your CSRF / CORS settings are active?
I forget where we left off but
I think when I had these issues, it boiled down to my access control
i have a working fresh install with just the stuff i listed above done to it
ultimately, i'm not sure why the _preferences document isn't being populated
the 401 unauthorized request seems to be a side-effect of that document not having what it needs
Lets check out the status in detail
To see if like, your cookie is being rejected
We should be able to pinpoint the cause of the 401
Any context on the cause?
Also, Payload discord has the voice channels now
Happy to check out your setup if you want to share
sorry, fell into a rabbit hole
the primary difference between a fresh install (that works) and the repo I'm getting to work is that the _preferences document is not being populated.
And I don't understand what would cause that. Trying to look at the source code to see where that's supposed to happen
i've cleared the db completely on the problem repo and reinstalled and it still doesn't like me ๐ฆ
matched up the package versions too
for additional context, what I'm seeing is
- on page load a GET request is made for a preference (
/api/_preferences/locale
for example)
- That request returns a 200, but the body of its response is
{"message":"Not Found","value":null}
- Then the admin client makes a subsequent POST request for that preference at the same path.
- That request returns a 401.
Normally, the initial GET request just works and the subsequent request is never made.
in comparing the data of the fresh install vs the current repo, i see that _preferences is either empty or non-existant; which would explain why the initial get request would just fail (and the subsequent).
So my thought atm is, if I can understand why that document isn't getting updated, then the rest of the errors will probably make sense too.
What payload version are you using? Can you check if the _preferences collection has any dangling indexes in the database?
Good thought
1.7.0 payload version
what's a dangling index?
i'm not the most well-versed in mongo..
Remnants of old fields/indexes
Sometimes when you re-use a db
if you use
mongosh
or a visual editor to get a direct connection to the mongodb you can see the indexes using db._preferences.getIndexes()
^
these are roughly equivalent to mysql constraints
ok
(very roughly, please never quote me on that lol)
i'm using Compass atm
ah i never used compass, this is like a visual explorer for mongo right?
yeah, the mongoDB website provides it
there is a tab for indexes when i select a document
yes that sounds good ๐
but it should be on the collection rather, I think
This overall problem rings a bell for me
i selected the collection and filtered by indexes
I have seen something like that some time ago, give me some time to figure it out, ill get back to it asap ๐
ah yes see
indexes 2
any way you can show them?
mhmmm
_id_
should be
_id
I think
what can you see in the validation tab_
Here's with the indexes expanded
validations is empty
Ah I found the issue that I was remembering
https://github.com/payloadcms/payload/issues/1309Ah I remember I got that error
I was logging out users without sending credentials
might be a jwt/csrf problem, after login you do receive the cookie, right? Did you validate it with a tool like
https://jwt.io/i do receive a cookie. i'll try the tool there
Also, I think you may have done this prior, but it would be helpful to see your
payload config
server.ts file
and an example collection
Just so we can rule out oddities
I have a feeling the cookie issuer url might not be correct, you said you are changing the vhost at some point and then resolved CORS issues, right?
i just have it set as "*" atm
to rule that out
I don't think wildcard is allowed though
Right?
Doesn't it need to be explicit
Also, if you're going through a proxy, make sure
trustProxy
is enabled in csrf
via the warning on this page:
https://payloadcms.com/docs/production/preventing-abuse#cross-site-request-forgery-csrfimport { buildConfig } from "payload/config"
import formBuilder from "@payloadcms/plugin-form-builder"
import { cloudStorage } from "@payloadcms/plugin-cloud-storage"
import { s3Adapter } from "@payloadcms/plugin-cloud-storage/s3"
import path from "path"
import Users from "./collections/Users"
import Pages from "./collections/Pages"
import Categories from "./collections/Categories"
import Media from "./collections/Media"
import Nav from "./globals/Nav"
export default buildConfig({
serverURL: "https://<redacted>",
csrf: [
"https://<redacted>",
],
cors: "*",
admin: {
user: Users.slug,
webpack: (config) => {
return {
...config,
resolve: {
...config.resolve,
alias: {
...config.resolve.alias,
fs: path.resolve(__dirname, "mocks/emptyObject.js"),
},
},
}
},
},
collections:[Users],
plugins: [
cloudStorage({/** <redacted to save past space */}),
formBuilder({/** <redacted to save past space */}),
],
typescript: {
outputFile: path.resolve(__dirname, "payload-types.ts"),
},
graphQL: {
schemaOutputFile: path.resolve(__dirname, "generated-schema.graphql"),
},
localization: {
locales: ["en", "es", "de"],
defaultLocale: "en",
fallback: true,
},
})
Can you pass an array to cors as well matching csrf?
yes
Ah actually, * should be fine according to Payload
Either a whitelist array of URLS to allow CORS requests from, or a wildcard string ('*') to accept incoming requests from any domain.
Not sure if it will do anything, but I do have my rateLimit configured to allow proxy
rateLimit: {
trustProxy: true,
window: 2 * 60 * 1000, // 2 minutes
max: 2400, // limit each IP per windowMs
},
ok
ah I would be careful with that, chances are rate limiting is handled by your reverse proxy or provider
True, maybe as a last resort if nothing else works then
We are on a balancer at work, but I'm off today so I can't look at our config atm
oh for context on that, i'm on a digitalocean droplet using nginx to handle the proxy
another odd behavior i noticed that different from the fresh install is that when i log out, the token isn't removed
but I still think the cookie might have the wrong domain, I would take a look at the
server.ts
(not payload-config) and see if the express setup is funny, another try would be to include/exclude the used ports, depending on your setup. If nothing works, try to log out the access control step, that would maybe provide more insight, you might even use a custom express middleware to log all incoming requests and confirm the cookies are looking good
Logging out through the admin panel, right?
yeah, that is another pointer to the cookie having a wrong domain
yeah
Isn't the domain on the cookie?
in dev tools
yeah, it matches the domain i'm on
Can you share the details of the 401 error
or a SS
what's an SS?
lets also check out your nginx config for this domain
sorry, screenshot
this is my server.ts btw. it's very lightly modified from the default
import express from 'express'
import payload from 'payload'
import path from 'path'
require('dotenv').config()
const app = express()
const port = process.env.PORT || 3000
// Redirect root to Admin panel
app.get('/', (_, res) => {
res.redirect('/admin')
})
const start = async () => {
// Initialize Payload
await payload.init({
secret: process.env.PAYLOAD_SECRET,
mongoURL: process.env.MONGODB_URI,
express: app,
onInit: async () => {
payload.logger.info(`Payload Admin URL: ${payload.getAdminURL()}`)
},
})
// Add your own express routes here
app.listen(port)
}
start()
mainly just make the port configurable
Thank you, can we also see the nginx redirect for the port?
should be something like
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
atm it's
location / {
proxy_pass http://localhost:3001;
# expires 30d;
# add_header Pragma public;
# add_header Cache-Control "public";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
well one simple test to check if it is a csrf related problem is to disable it and try again, unless your site is in production already
i've removed the csrf already and it had no effect on the outcome
3001 is the correct port as per process.env ?
it is
i did mess that up in this process and fixed it ๐
Ah sorry, copied it from an example
mhmm i still feel that 0 preferences is odd, if we can rule out the cookie
but I think the best approach at this point is to log the requests
Response Headers:
HTTP/1.1 401 Unauthorized
Server: nginx
Date: Tue, 18 Apr 2023 17:44:12 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 84
Connection: keep-alive
X-Powered-By: Express
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 494
X-RateLimit-Reset: 1681839934
Content-Language: en
Vary: X-HTTP-Method-Override, Accept-Encoding
Access-Control-Allow-Methods: PUT, PATCH, POST, GET, DELETE, OPTIONS
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, Content-Encoding, x-apollo-tracing
ETag: W/"54-VwIDOKGPAda99KAJF2yRyy4FL7I"
Request Headers:
POST /api/_preferences/locale HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 14
Content-Type: application/json
Cookie: payload-token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Iml0LXJlZ2lzdHJhdGlvbnMrYWNhZGVteS1xYUBwYXJhZG93c2tpLmNvbSIsImlkIjoiNjQzZWNhZjgxMGQxMmRjZGEwM2Q5YWRjIiwiY29sbGVjdGlvbiI6InVzZXJzIiwiaWF0IjoxNjgxODM5ODUyLCJleHAiOjE2ODE4NDcwNTJ9.3qwWjaX_xCTopAx1sRa33sFfBrzVYAgOzz6GWLrxq40
Host: <redacted>
Origin: https://<redacted>
Pragma: no-cache
Referer: https://<redacted>/admin
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36
sec-ch-ua: "Chromium";v="112", "Google Chrome";v="112", "Not:A-Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
here's an example of a 401'ing request i'm getting
and you already dropped users/_preferences collections?
i dropped the whole collection multiple times to replicate a fresh install
i've never seen an email with a + symbol before ๐ฎ
which is an alias i guess
oh, it's a little gmail trick. it ignores the stuff after the +
no way that's related right?
could you try dropping preferences and users again? Just to make sure it is no payload validation conflict here
sure
the email-field comes with it's own validation afaik
do i have the naming wrong btw... a document has collections?
oh and then create first user with a simpler mail ๐
sure ๐
yeah, a collection has documents ๐ but nobody is judging
preferences and users dropped...
new user created (just my normal work email). preferences doesnt' seem to be repopulating
can u change the payload admin locale or switch to dark mode for the new user?
i can read the user, but can't change preferences
unable to switch to dark mode
interesting
whats your user collection look like?
well at least we narrowed the problem then ๐
import { CollectionConfig } from 'payload/types'
const Users: CollectionConfig = {
slug: 'users',
auth: true,
admin: {
useAsTitle: 'email',
},
access: {
// Only admins can create users
read: () => true,
},
fields: [
{
name: 'name',
type: 'text',
}
],
}
export default Users
are there any afterCreate or afterLogin or beforeOperation hooks?
is create and delete true by default?
can you set all operation types and then try
(and update)
import { CollectionConfig } from 'payload/types';
const Users: CollectionConfig = {
slug: 'users',
auth: true,
admin: {
useAsTitle: 'email',
},
access: {
read: () => true,
},
fields: [
// Email added by default
{
name: 'name',
type: 'text',
}
],
};
export default Users;
this is what is in my fresh install
and Users.slug is in your admin settings in payload config?
yeppers
what is going on lol
I wonder why you include the mockObject in the webpack conf ๐ค
other than that it looks fairly simple/normal
i ported that stuff to the fresh install and it works fine there
id take it out if you're not using it
it fixes a build problem with the cloud plugin
did you run generate-types and have that in your tsconfig?
i don't think i did
will do
I have a feeling that
Users.slug
is not working well since the payload update for better ts support, I find myself having to change it a bit for the compiler to be happy, that's seeming odd to me
generating doesn't seem to have affected anything
What if you
remove your serverUrl
leave it null
aight
[18:14:51] ERROR (payload): 1: "serverURL" must be a string
or just not set it
like remove the prop
leave csrf though
ok
do you have access to the mongo logs? I think it fails to create the preferences when it needs to
hm, i think so
I'll have to grab some dinner, gonna check back on this later if it is not resolved then ๐
i really appreciate your guys' help on this ๐โโ๏ธ
Hey no problem! We'll get to the bottom of this
๐
here's what i could get from the DO logs for the mongo db server:
client metadata
Authentication failed
No SSL certificate provided by peer
Connection accepted
client metadata
No SSL certificate provided by peer
client metadata
No SSL certificate provided by peer
Connection accepted
Connection accepted
Connection ended
Connection ended
Connection ended
Connection ended
Interrupted operation as its client disconnected
Connection ended
Interrupted operation as its client disconnected
Connection ended
Connection ended
Connection ended
Interrupted operation as its client disconnected
Authentication succeeded
Authentication succeeded
Authentication succeeded
client metadata
Authentication failed
client metadata
Authentication failed
Authentication failed
client metadata
No SSL certificate provided by peer
No SSL certificate provided by peer
No SSL certificate provided by peer
client metadata
Connection accepted
Connection accepted
Connection accepted
client metadata
client metadata
client metadata
client metadata
client metadata
No SSL certificate provided by peer
No SSL certificate provided by peer
No SSL certificate provided by peer
No SSL certificate provided by peer
No SSL certificate provided by peer
No SSL certificate provided by peer
Connection accepted
Connection accepted
Connection accepted
Connection accepted
Connection accepted
Connection accepted
i've no context for if this is normal or not
if it helps, I'm also using DO's mongoDB cluster feature for this
though if it works for the fresh install... seems the code has to be the differing point
i'm half tempted to just reset this repo from scratch to just use the fresh install and slowly add from there lol
well this is really frustrating
I am sorry, I won't pretend to be helpful if I can't do anything more. I feel like I know where the error is coming from, but for me it is unclear how to finally fix it. You tried anything I would try and anything beyond this point from my side would be guessing in the dark :/
oh it's alright. I ended up just starting fresh and slowly adding the changes back in. I'm hoping it'll be obvious here soon
I hope they don't mind the tag, but maybe
@364124941832159242,
@967118574445547650or
@1054360511380201493can help you with this.
As this thread is almost 230 messages long let me give them a summary:
It seems that no
_preferences
for the auth enabled session is created. All requests result in 401, csrf and token are looking good, user and preference table were dropped multiple times, mongo logs seem normal. There was a related issue in github which was resolved long ago (payload 1.2)
Jakey is using current payload version with a fairly standard config.
Sorry to bother you, but this thread is getting hard to follow and I am all out of ideas :/
woah
ok
let me review a bit
huh... yeah it works now that I've started from a fresh installation and added my stuff in piece by piece...
wtf, lol
sure enough, the _preferences collection is populated... and everything seems to be working fine.. I'm not sure what might've happened in this process that kicked it into doing that. Def still welcome any thoughts
wat
haha
hmmmm
one theory.... maybe the fresh install works fine and a plugin introduced breaks the initial _preferences collection setup
doesn't appear to be the case... i dropped the document and remade the initial user... no 401's still
ok, I think I see the issue
or at least it seems to make sense.
I had run into issues getting environment variables working in payload.config.ts
so the work-around I went with was to create separate payload.configs.ts's for each environment ( I pulled in and merged over the differences i needed from the default )
then i added npm scripts to handle the qa/prod versions of those configs
so i was building for QA for instance, but serving using the default config
and i suspect that caused some sort of mismatch in the final build
testing that theory now...
ahhhh yes that'd do it
well
i showed up late
haha
lol, still appreciated! That's actually probably the better question though
how
shouldi be handling environment variables in payload.config.ts. it seems like in some spots it's fine but for the
cors
property it bugs out because it's also used on the payload client
generally we just use
dotenv
and make sure to call it in the payload config itself if you use variables within the config
it's ok to call it twice (once in your server, once in your config)
I did try doing that and it caused a build error... but I cannot recall what it was.. I'll have to check try again when my brain recovers lol
I'll start up another post for that if i run into it again
thanks for helping me out
@486710146651652106@245330411570331648
@1019667378960863293
@364124941832159242
!
Anytime!
Did anybody found a way to solve this issue?
Got a customer that is not able to edit the content anymore and i really don't know where to look
I read all the thread and tried some fresh installs that worked the first time but the stopped to work
Start up another thread and describe your current situation. Feel free to tag me in it.
@594252568054726656If someone else encounter this problem, make sure that your
serverURL
has the protocol and the host in production
i do not want to necropost but just want to say i had the same issue, had to include straight up strings in my CORS and CSRF array, one for my prod custom domain and another for localhost, couldn't include a process.env.PAYLOAD_URL in there cause for some reason it doesnt evaluate to a string and causes a build error, payload complains it's not a string. Also make sure the serverURL has protocol and host as franknoel said.
this is also related to another problem but I wasn't able to edit any content at all while I was having the 401 errors with the role based access control as seen here
https://payloadcms.com/blog/build-your-own-rbacjust like Jakey described. For whatever reason my custom isAdmin method wasn't working and i didnt really know why until now
i think the same problem that the 401 error is caused by also causes the issue of not having access controls working correctly
when i checked my local server, in my isAdmin function given to the access object, i could see the user object and admin condition evaluate to true so it works, but in prod, req.user was undefined, and so the admin check was undefined as a result, therefore it would fail
when i was testing i noticed that it worked if i replaced my method with an arrow function that evaluates to true. so I knew something was up
i think it has something to do with the CSRF and CORS stuff, cause if a user can't authenticate correctly on the site or they're having issues, then req.user would evaluate to 'undefined' which means all access control operations end up failing
and even worse is that, because user.role === "admin" evaluates to undefined which im assuming is falsey, that means when you try and update content it just says you dont have permissions for it and gives a 403
when in fact the true problem is that users cant correctly authenticate to the admin dashboard
I only managed to fix both the 401 and 403 via the correct CSRF and CORS settings
obviously replace <domain>. with your domain
AND i couldnt put process.env.PAYLOAD_URL in those arrays either, not sure why exactly
hope this helps
In terms of the environment variable issue, I've since found that if I use the
import
form of including the
dotenv
package (instead of
require
), it pulls the values from my
.env
just fine.
// payload.config.ts
import dotenv from 'dotenv'
dotenv.config()
I'll look at this in more depth in the morning. Managed to catch me doing a late-nighter. ๐ด Hope this helps though!
oh wow that's quite surprising
il try this out and see where i go with it, thanks!
i had just joined the server cause i was having an exactly identical issue, read through this post, realised my CSRF and CORS props weren't configured, and boom it just worked and hit two birds with one stone
could be something silly like the wildflag not working properly or env variables being weird yeah
but yeah, no worries
i think dotenv.config() is actually quite dangerous depending on where it's used. if you want public environemnt variables that can be used on the frontend they have to be prefixed with PAYLOAD
PUBLIChttps://payloadcms.com/docs/admin/webpack#admin-environment-vars
i accidentally added them to the client side because of a misbehaving oauth plugin
ahh good call. I'd forgotten about that
Star
Discord
online
Get dedicated engineering support directly from the Payload team.