I'd like to implement a custom auth for my users collection, where a custom code will be sent to the users email and once they enter it they are authed.
Any simple way to achieve this ?
@kris Good morning kris - I've done something like this!
This is similar to a "verify email" token in a way
It would sort of work like this
1.) User is created, a hook fires and sends an email to the user. The custom email can be easily defiend on your collection and it should include a URL to your frontend with a unique id (could be the created collection id). For instance...
example.com?token=MYUSERID
2.) Create a custom endpoint on your auth collection that will be used to authorize the user. You want to check a property on the request, probably "token" and then update the verified property on the user.
3.) On your frontend, make sure the link you sent in the email will function. The frontend app needs to get the query parameter value from the URL (or allow them to enter a token), and then make an API request to your custom endpoint.
That's a quick overview of how I did it, happy to share examples.
Hey thanks for response. I see what you mean. My usecase though is that I don't want my users to enter passwords at all.
They would enter email and then they would receive a 6 digit code or link that they can click that would auth them
https://payloadcms.com/docs/authentication/config#strategies
do I need this for this ?
Found this here
@kris If you don't want to use passwords for auth, then you could create a non-auth collection and deal with data using a token
I really like auth capacities of payload (cookie etc)
@notchris I would love to see how you done what you did, I’ve tried going down the verification token route to no avail
Ah I've done it in really hacky way. Probably there are better ways
@Moudi Baqir [moudi] Happy to answer any questions!
@notchris Thanks man, appreciate it, just wanna know what did you add or what did you configure to the user collection?
because, im sure im doing everything the docs are saying to do but nothings working
Can you describe what your goal is?
So I can suggest the best route
I want a verification email to be sent to the users email they signed up with in order to be bable to login to their account
so they gotta verify before they're able to login and if they try to login, an error will be thrown saying "You have to verify your account before login in" not too worried about that part, its the email being sent is what my goal is
That seems like the default functionallity though, no?
Are you saying, you don't want the user to have a password?
@Moudi Baqir [moudi]
nah, so upon registering, iwant the user to get an email sent to click a link or button or whatever to verify their account in order to login, but i cant even get the email to send
Ah so the issue is the email
Lets check out your payload.config file and your server.ts file
sure
ill send the code
Mainly jsut your server.ts file
You should have configured your email transport options, correct?
oh wait... lol
const start = async () => {
// Initialize Payload
await payload.init({
secret: process.env.PAYLOAD_SECRET,
express: app,
email: {
transportOptions: {
host: 'my.host.com',
port: 25,
},
fromName: 'Your Name',
fromAddress: 'noreply@my.host.com',
logMockCredentials: true, // Optional
},
onInit: async () => {
payload.logger.info(`Payload Admin URL: ${payload.getAdminURL()}`);
},
});
you gotta do that within the server.ts?
😛
Yes its required otherwise, it's going to use an ethereal setup
ethereal, so you dont even see it right
well, it create an 'ethereal email account', basically a temporary one for testing emails
yeah gotcha
cant believe ive been scratching my head wondering why it wasnt woring
working
It happens, at least you know now!
and for the email template i can configure that within the user collection itself?
or is it beetter to seperate that?
Correct, you should be able to pass an html file with variables
or HTML string
however you want
have you tested to see if it goes with react email?
you're a legend mate
I've used an exported template from react email, but you need to plugin your own variables obviously
lol no worries @Moudi Baqir [moudi]
lmk if you get stuck
actually while i got you here
sure
idk if this is normal but ive been getting this error in the terminal lately
ERROR (payload): MongoServerError: Caused by :: Write conflict during plan execution and yielding is disabled. :: Please retry your operation or multi-document transaction.
at Connection.onMessage (B:\VSCode Projects\personal-projects\web-dev\official-nyla\node_modules\mongodb\src\cmap\connection.ts:449:20)
at MessageStream.<anonymous> (B:\VSCode Projects\personal-projects\web-dev\official-nyla\node_modules\mongodb\src\cmap\connection.ts:241:56)
at MessageStream.emit (node:events:514:28)
at MessageStream.emit (node:domain:488:12)
at processIncomingData (B:\VSCode Projects\personal-projects\web-dev\official-nyla\node_modules\mongodb\src\cmap\message_stream.ts:188:12)
at MessageStream._write (B:\VSCode Projects\personal-projects\web-dev\official-nyla\node_modules\mongodb\src\cmap\message_stream.ts:69:5)
at writeOrBuffer (node:internal/streams/writable:556:12)
at _write (node:internal/streams/writable:490:10)
at MessageStream.Writable.write (node:internal/streams/writable:494:10)
at TLSSocket.ondata (node:internal/streams/readable:985:22)
at TLSSocket.emit (node:events:514:28)
at TLSSocket.emit (node:domain:488:12)
at addChunk (node:internal/streams/readable:545:12)
at readableAddChunkPushByteMode (node:internal/streams/readable:495:3)
at TLSSocket.Readable.push (node:internal/streams/readable:375:5)
at TLSWrap.onStreamRead (node:internal/stream_base_commons:190:23)
at TLSWrap.callbackTrampoline (node:internal/async_hooks:130:17)
now i havent seen anything being affect atm
but its got me paranoid
That's not a normal error
Any idea what action causes it to fire?
nah man
not a clue
i havent really pinpointed it yet
As far as I know, that's not a common error so I'm not sure what to recommend
You could try to re-build your mongodb
its happening everytime im refreshing lol
Yeah that's not ideal, I would probably make another issue about that specifically
for the host what would i use?
Your email host
heres hoping it goes well
idk if you were having the same issue but, when adding the verify object to the auth in user collection, were you able to login at all? with the user you first signed up with
auth: {
verify: {
generateEmailHTML: ({ req, token, user }) => {
const url =
https://nyla.payloadcms.app/verify?token=${token}
return
<p>Hi ${user.name},</p>
<p>Thanks for signing up to Nyla!</p>
<p>Click the link below to verify your email address:</p>
<a href="${url}">${url}</a>
<p>If you didn't sign up to Nyla, you can ignore this email.</p>
},
},
},
const start = async (): Promise<void> => {
const transport = await nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.GMAIL_USER,
pass: process.env.GMAIL_PASS,
},
})
await payload.init({
secret: process.env.PAYLOAD_SECRET || '',
express: app,
email: {
fromName: 'Nyla',
fromAddress: process.env.GMAIL_USER,
transport,
logMockCredentials: true,
},
onInit: () => {
payload.logger.info(
Payload Admin URL: ${payload.getAdminURL()}
)
},
})
done all this and now im getting unhandledRejection InvalidConfiguration: Email fromName and fromAddress must be configured when transport is configured
[2024-03-04T15:38:22]
│ at ensureConfigHasFrom (/workspace/node_modules/payload/dist/email/build.js:33:15)
[2024-03-04T15:38:22]
│ at buildEmail (/workspace/node_modules/payload/dist/email/build.js:60:9)
[2024-03-04T15:38:22]
│ at BasePayload.init (/workspace/node_modules/payload/dist/payload.js:226:41)
[2024-03-04T15:38:22]
│ at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
[2024-03-04T15:38:22]
│ at async getPayload (/workspace/node_modules/payload/dist/payload.js:259:26)
[2024-03-04T15:38:22]
│ at async initHTTP (/workspace/node_modules/payload/dist/initHTTP.js:39:21)
[2024-03-04T15:38:22]
│ at async Payload.init (/workspace/node_modules/payload/dist/index.js:27:25)
[2024-03-04T15:38:22]
│ at async start (/workspace/dist/server.js:27:5) {
[2024-03-04T15:38:22]
│ data: null,
[2024-03-04T15:38:22]
│ isOperational: true,
[2024-03-04T15:38:22]
│ isPublic: false,
[2024-03-04T15:38:22]
│ status: 500
[2024-03-04T15:38:22]
│ }
The first user may need to be marked as authorized
How would I be able to do that? Cause I can’t even sign up
Do I have to setup the transport config inside the server.ts or?
Can I just create my own configuration inside the api folder inside the app folder?
I’m so confused lol
so i got it to work but its a bit weird lol, i see the emails being sent from the email im sending them from BUT theyre not getting sent to the email thats signing up
used a temp email, and it shows in the temp email inbox but not my other gmail accounts odd
nvm its showing now
Star
Discord
online
Get help straight from the Payload team with an Enterprise License.