Extending verifyEmail function

Hi, is it possible at all to extend some of the Auth functions? E.g verifyEmail, signup, etc.. I’m looking to add some additional logic after user has verified their email. I know I can create my custom verifyEmail component, however I don’t want to expose out a new Action that is visible to the user. Is there anything I can do on the server?
4 Replies
kapa.ai
kapa.ai5mo ago
Hi @crunchyTaco. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Yes, it is possible to extend the Auth functions in Wasp. You can create a custom sign-up action where you can add your additional logic after the user has verified their email. Here is an example of how you can create a custom sign-up action:
import {
ensurePasswordIsPresent,
ensureValidPassword,
ensureValidEmail,
createProviderId,
sanitizeAndSerializeProviderData,
deserializeAndSanitizeProviderData,
findAuthIdentity,
createUser,
createEmailVerificationLink,
sendEmailVerificationEmail,
} from 'wasp/server/auth'

export const signup = async (args, _context) => {
ensureValidEmail(args)
ensurePasswordIsPresent(args)
ensureValidPassword(args)

try {
const providerId = createProviderId('email', args.email)
const existingAuthIdentity = await findAuthIdentity(providerId)

if (existingAuthIdentity) {
const providerData = deserializeAndSanitizeProviderData(existingAuthIdentity.providerData)
// Your custom code here
} else {
// sanitizeAndSerializeProviderData will hash the user's password
const newUserProviderData = await sanitizeAndSerializeProviderData({
hashedPassword: args.password,
isEmailVerified: false,
emailVerificationSentAt: null,
passwordResetSentAt: null,
})
await createUser(
providerId,
providerData,
// Any additional data you want to store on the User entity
{},
)

// Verification link links to a client route e.g. /email-verification
const verificationLink = await createEmailVerificationLink(args.email, '/email-verification');
try {
await sendEmailVerificationEmail(
args.email,
{
from: {
name: "My App Postman",
email: "**[email protected]** (<https://wasp-lang.dev/cdn-cgi/l/email-protection>)",
},
to: args.email,
subject: "Verify your email",
text: `Click the link below to verify your email: ${verificationLink}`,
html: `
<p>Click the link below to verify your email</p>
<a href="${verificationLink}">Verify email</a>
`,
}
);
} catch (e: unknown) {
console.error("Failed to send email verification email:", e);
throw new HttpError(500, "Failed to send email verification email.");
}
}
}
import {
ensurePasswordIsPresent,
ensureValidPassword,
ensureValidEmail,
createProviderId,
sanitizeAndSerializeProviderData,
deserializeAndSanitizeProviderData,
findAuthIdentity,
createUser,
createEmailVerificationLink,
sendEmailVerificationEmail,
} from 'wasp/server/auth'

export const signup = async (args, _context) => {
ensureValidEmail(args)
ensurePasswordIsPresent(args)
ensureValidPassword(args)

try {
const providerId = createProviderId('email', args.email)
const existingAuthIdentity = await findAuthIdentity(providerId)

if (existingAuthIdentity) {
const providerData = deserializeAndSanitizeProviderData(existingAuthIdentity.providerData)
// Your custom code here
} else {
// sanitizeAndSerializeProviderData will hash the user's password
const newUserProviderData = await sanitizeAndSerializeProviderData({
hashedPassword: args.password,
isEmailVerified: false,
emailVerificationSentAt: null,
passwordResetSentAt: null,
})
await createUser(
providerId,
providerData,
// Any additional data you want to store on the User entity
{},
)

// Verification link links to a client route e.g. /email-verification
const verificationLink = await createEmailVerificationLink(args.email, '/email-verification');
try {
await sendEmailVerificationEmail(
args.email,
{
from: {
name: "My App Postman",
email: "**[email protected]** (<https://wasp-lang.dev/cdn-cgi/l/email-protection>)",
},
to: args.email,
subject: "Verify your email",
text: `Click the link below to verify your email: ${verificationLink}`,
html: `
<p>Click the link below to verify your email</p>
<a href="${verificationLink}">Verify email</a>
`,
}
);
} catch (e: unknown) {
console.error("Failed to send email verification email:", e);
throw new HttpError(500, "Failed to send email verification email.");
}
}
}
You can add your custom code after the sign-up action. However, please note that this will expose a new action that is visible to the user. For more information, you can refer to the Wasp documentation (https://wasp-lang.dev/docs/auth/email#creating-a-custom-sign-up-action). In the future, Wasp plans to add hooks where you will be able to run code after/before signup/login. This feature is expected to be released in the next 1-2 months according to a Discord support thread (https://discord.com/channels/686873244791210014/1217452914503585902). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @crunchyTaco, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
miho
miho5mo ago
Hey, we are releasing auth hooks soon with Wasp 0.14.0 which would enable you to run code onBeforeSignup, onAfterSignup and onBeforeOAuthRedirect. Here's the PR: https://github.com/wasp-lang/wasp/pull/1993 Would that solve your issue? Outside of using the auth hooks, you'd have to write your own custom signup function. Also, regarding customisation of signup data validation, we have it planned here: https://github.com/wasp-lang/wasp/issues/1571
crunchyTaco
crunchyTacoOP5mo ago
@miho that’s exactly what I am looking for! Is there a concrete date on when 0.14 will be released?
miho
miho5mo ago
Can't make any promises, but soon 🙃
Want results from more Discord servers?
Add your server