W
Wasp4mo ago
NEROX

Adding sign up extra fields

[ Wasp ] src/auth/SignupPage.tsx(26,13): error TS2353: Object literal may only specify known properties, and 'recaptchaToken' does not exist in type 'AdditionalSignupFields'. [ Wasp ] src/auth/signup.ts(17,3): error TS2322: Type '(data: SignupData) => Promise<string>' is not assignable to type 'FieldGetter<string | null | undefined>'. [ Wasp ] Types of parameters 'data' and 'data' are incompatible. [ Wasp ] Type '{ [key: string]: unknown; }' is missing the following properties from type 'SignupData': email, password
main.wasp: userSignupFields: import { userSignupFields } from "@src/auth/signup", }, signup: import { defineUserSignupFields } from 'wasp/server/auth'; type RecaptchaResponse = { success: boolean; challenge_ts: string; hostname: string; 'error-codes'?: string[]; } type SignupData = { email: string; password: string; recaptchaToken?: string; } export const userSignupFields = defineUserSignupFields({ email: async (data: SignupData) => { if (!data.email) { throw new Error('Email is required'); } return data.email; }, password: async (data: SignupData) => { if (!data.password) { //some logic } return data.password; }, recaptchaToken: async (data: { [key: string]: unknown }) => { const token = data.recaptchaToken as string | undefined; if (!token) { throw new Error('reCAPTCHA verification is required'); } try { const verifyUrl = 'https://www.google.com/recaptcha/api/siteverify'; const params = new URLSearchParams({ secret: process.env.GOOGLE_RECAPTCHA_SECRET_KEY!, response: token }); const response = await fetch(${verifyUrl}?${params.toString()}, { method: 'POST } });
13 Replies
kapa.ai
kapa.ai4mo ago
Hi @NEROX. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- The errors you are seeing are due to two main issues: 1. You should not include email and password in userSignupFields. - Wasp handles email and password fields internally. The documentation explicitly states that you should exclude the password field (and by extension, email for email-based auth) from userSignupFields to prevent them from being saved as plain text in the database. Only extra fields (like address, phone, or your custom fields) should be included in userSignupFields—not the core auth fields like email and passwordDocs: Defining Extra Fields. 2. Type mismatch for the data parameter. - The function you provide for each field in userSignupFields receives a generic data object containing all signup form data, but the type should match what Wasp expects. You do not need to define a custom SignupData type; just use the data object as-is. How to fix: - Remove email and password from your userSignupFields definition. - Only include your extra fields, such as recaptchaToken. - The function for each field should accept a single data parameter (an object with all signup form data). Example:
import { defineUserSignupFields } from 'wasp/server/auth';

export const userSignupFields = defineUserSignupFields({
recaptchaToken: async (data) => {
const token = data.recaptchaToken as string | undefined;
if (!token) {
throw new Error('reCAPTCHA verification is required');
}

// Your verification logic here...
// For example, call Google's reCAPTCHA API

return token;
},
});
import { defineUserSignupFields } from 'wasp/server/auth';

export const userSignupFields = defineUserSignupFields({
recaptchaToken: async (data) => {
const token = data.recaptchaToken as string | undefined;
if (!token) {
throw new Error('reCAPTCHA verification is required');
}

// Your verification logic here...
// For example, call Google's reCAPTCHA API

return token;
},
});
In your main.wasp:
auth: {
userEntity: User,
methods: {
email: {
userSignupFields: import { userSignupFields } from "@src/auth/signup",
},
},
onAuthFailedRedirectTo: "/login",
}
auth: {
userEntity: User,
methods: {
email: {
userSignupFields: import { userSignupFields } from "@src/auth/signup",
},
},
onAuthFailedRedirectTo: "/login",
}
Summary:
- Do not include email or password in userSignupFields. - Only add extra fields you want to save (like recaptchaToken). - The function receives all signup data as an object. For more details, see the official docs on defining extra fields and signup fields customization. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @NEROX, 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?
NEROX
NEROXOP4mo ago
@kapa.ai [ Wasp ] src/auth/SignupPage.tsx(28,13): error TS2353: Object literal may only specify known properties, and 'recaptchaToken' does not exist in type 'AdditionalSignupFields'. [ Wasp ] src/auth/signup.ts(4,3): error TS2353: Object literal may only specify known properties, and 'recaptchaToken' does not exist in type 'UserSignupFields' signuppage.tsx: <SignupForm additionalFields={{ recaptchaToken: { //line 28 label: 'Verify you are human', type: 'custom', render: ({ setField }: { setField: SetFieldFunction }) => ( <ReCAPTCHA ref={recaptchaRef} sitekey={process.env.GOOGLE_RECAPTCHA_SITE_KEY!} onChange={(token) => setField('recaptchaToken', token)} onExpired={() => setField('recaptchaToken', null)} onError={() => setField('recaptchaToken', null)} /> signup.ts: import { defineUserSignupFields } from 'wasp/server/auth'; export const userSignupFields = defineUserSignupFields({ recaptchaToken: async (data: { [key: string]: unknown }) => { //line 4 const token = data.recaptchaToken as string | undefined; if (!token) { throw new Error('reCAPTCHA verification is required'); }
kapa.ai
kapa.ai4mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- The errors you are seeing:
error TS2353: Object literal may only specify known properties, and 'recaptchaToken' does not exist in type 'AdditionalSignupFields'.
error TS2353: Object literal may only specify known properties, and 'recaptchaToken' does not exist in type 'UserSignupFields'
error TS2353: Object literal may only specify known properties, and 'recaptchaToken' does not exist in type 'AdditionalSignupFields'.
error TS2353: Object literal may only specify known properties, and 'recaptchaToken' does not exist in type 'UserSignupFields'
indicate that Wasp does not recognize recaptchaToken as a valid field for either additionalFields in <SignupForm /> or for userSignupFields in your backend. What the docs say: - The extra fields you add to the signup process must also exist as fields on your User entity in your Prisma schema, as defined in your main.wasp file. For example, if you want to add an address field, you must add address to your User entity in main.wasp and your database schema. The same applies to any other field you want to collect and store during signup, such as phone or address Defining Extra Fields. - The additionalFields prop for <SignupForm /> expects either a list of field objects or render functions, but the field names must correspond to fields that exist on the User entity SignupForm Customization. Why your code fails: - recaptchaToken is not a field on your User entity. Wasp expects all fields in userSignupFields and additionalFields to be actual fields on the User entity, because it will try to save them to the database. - recaptchaToken is a transient field used for verification, not for storage. How to fix: - Do not add recaptchaToken to userSignupFields or additionalFields unless you also add it to your User entity (which is not recommended, since you don't want to store the token). - Instead, handle reCAPTCHA verification separately in your signup flow, outside of Wasp's built-in extra fields mechanism. Summary:
Wasp's current extra fields system is designed for fields that are stored on the User entity. There is no documented way to add transient, non-persistent fields (like recaptchaToken) to the signup process using userSignupFields or additionalFields. You will need to handle reCAPTCHA verification outside of these mechanisms, such as in a custom signup action or by extending the backend logic. If you need to collect and process a field that should not be stored on the user, the knowledge sources do not provide a supported way to do this directly with userSignupFields or additionalFields at this time. For more, see the docs on defining extra fields and customizing the signup form. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @NEROX, 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?
NEROX
NEROXOP4mo ago
Thx @kapa.ai , next: SignupPage.tsx:49 RECAPTCHA_SITE_KEY is not configured Why? main.wasp: envValidationSchema: import { envValidationSchema } from "@src/env", }, Signuppage.tsx: <div className='flex flex-col items-center gap-4'> <div className='flex justify-center'> <ReCAPTCHA ref={recaptchaRef} sitekey={import.meta.env.RECAPTCHA_SITE_KEY} onChange={handleRecaptchaChange} /> </div> {error && ( <p className='text-sm text-red-600'>{error}</p> )} </div> export function SignupPage() { const recaptchaRef = useRef<ReCAPTCHA>(null); const [isVerified, setIsVerified] = useState(false); const [error, setError] = useState<string | null>(null); const handleRecaptchaChange = async (token: string | null) => { if (!token) { setIsVerified(false); setError('Please verify that you are human'); return; } try { const response = await fetch(${API_URL}/api/verify-recaptcha, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ token }) }); const result = await response.json();
if (result.success) { setIsVerified(true); setError(null); } else { setIsVerified(false); setError('reCAPTCHA verification failed'); recaptchaRef.current?.reset(); } } catch (err) { setIsVerified(false); setError('Error verifying reCAPTCHA'); recaptchaRef.current?.reset(); } }; if (!import.meta.env.RECAPTCHA_SITE_KEY) { console.error('RECAPTCHA_SITE_KEY is not configured'); return null; } .env.server: RECAPTCHA_SECRET_KEY=XXX .env.client: REACT_APP_RECAPTCHA_SITE_KEY=XXX
kapa.ai
kapa.ai4mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- The error RECAPTCHA_SITE_KEY is not configured occurs because you are trying to access import.meta.env.RECAPTCHA_SITE_KEY, but in your .env.client file, the variable is named REACT_APP_RECAPTCHA_SITE_KEY. Wasp requires all client environment variables to be prefixed with REACT_APP_. When you access them in your client code, you must use the full prefixed name:
import.meta.env.REACT_APP_RECAPTCHA_SITE_KEY
import.meta.env.REACT_APP_RECAPTCHA_SITE_KEY
not
import.meta.env.RECAPTCHA_SITE_KEY
import.meta.env.RECAPTCHA_SITE_KEY
So, update your code in SignupPage.tsx to:
sitekey={import.meta.env.REACT_APP_RECAPTCHA_SITE_KEY}
sitekey={import.meta.env.REACT_APP_RECAPTCHA_SITE_KEY}
and
if (!import.meta.env.REACT_APP_RECAPTCHA_SITE_KEY) {
console.error('RECAPTCHA_SITE_KEY is not configured');
return null;
}
if (!import.meta.env.REACT_APP_RECAPTCHA_SITE_KEY) {
console.error('RECAPTCHA_SITE_KEY is not configured');
return null;
}
This matches how Wasp exposes client env vars, as described in the docs:
To enable Wasp to pick them up, client environment variables must be prefixed with REACT_APP_, for example: REACT_APP_SOME_VAR_NAME=.... You can read them from the client code like this:
console.log(import.meta.env.REACT_APP_SOME_VAR_NAME)
console.log(import.meta.env.REACT_APP_SOME_VAR_NAME)
Docs: Env Variables Summary:
- Use REACT_APP_RECAPTCHA_SITE_KEY in both your .env.client and your code. - Access it as import.meta.env.REACT_APP_RECAPTCHA_SITE_KEY in your React components. This should resolve the configuration error. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @NEROX, 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?
NEROX
NEROXOP4mo ago
thx! @kapa.ai what info do you have about implement captcha in wasp? for forms or signup
kapa.ai
kapa.ai4mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I'm sorry, but the knowledge sources do not contain any official documentation or examples about implementing CAPTCHA (such as reCAPTCHA) in Wasp for forms or signup flows. There is no mention of built-in support or recommended patterns for adding CAPTCHA to Wasp authentication or custom forms. If you need to add CAPTCHA, you would likely need to implement it manually, as you have been attempting, but the official docs do not provide guidance or best practices for this use case at this time. If you need more help, you might consider reaching out to the Wasp community for advice or checking for updates in the official documentation in the future. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @NEROX, 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?
Zeke
Zeke4mo ago
Wasp captcha support would be cool. Preferably supporting multiple captcha types, like turnstile and hcaptcha, in addition to b recaptcha
sachdva
sachdva4mo ago
I mean you can implement it yourself, don't know if it's a wasp issue!
Zeke
Zeke4mo ago
yeah, but it does handle stuff like auth so it would be cool if it did captchas too
MEE6
MEE64mo ago
Wohooo @Zeke, you just became a Waspeteer level 3!
Zeke
Zeke4mo ago
but yeah implementing it manually isn't that bad, it would just be a cool feature
toticozeni
toticozeni4mo ago
Hey @NEROX, only additional fields defined on User enttiy in schema.prisma can be used with userSignupFields. This is because they are intended to be passed to User object and saved to the database.

Did you find this page helpful?