@@ -6,7 +6,7 @@ import { OutboundEmail } from '../models/outboundEmail.entity';
66import { User } from '../models/user.entity' ;
77import { validateUserRegistration } from '../middleware/validation' ;
88import { hashPassword , comparePassword } from '../utils/password' ;
9- import { canRegister , getGeoBlockLevel } from '../utils/eu' ;
9+ import { canRegister , getGeoBlockLevel , getMinimumAgeForCountry } from '../utils/eu' ;
1010import { authenticate } from '../middleware/auth' ;
1111import { UserLog } from '../models/userLog.entity' ;
1212import { ParentLinkRequest } from '../models/parentLinkRequest.entity' ;
@@ -208,6 +208,7 @@ export async function userRoutes(app: any, prefix = '') {
208208 : undefined ;
209209
210210 const inviteRepo = AppDataSource . getRepository ( ParentRegistrationInvite ) ;
211+ const userRepo = AppDataSource . getRepository ( User ) ;
211212 let parentRegistrationInvite : ParentRegistrationInvite | null = null ;
212213 if ( parentRegistrationToken ) {
213214 parentRegistrationInvite = await inviteRepo . findOneBy ( { token : parentRegistrationToken , used : false } ) ;
@@ -221,6 +222,18 @@ export async function userRoutes(app: any, prefix = '') {
221222 return { error : 'email_mismatch' , message : 'The child email does not match the parent registration invite.' } ;
222223 }
223224 body . parentId = parentRegistrationInvite . parentId ;
225+
226+ const parentUser = await userRepo . findOneBy ( { id : parentRegistrationInvite . parentId } ) ;
227+ if ( parentUser ) {
228+ if ( ! body . phone && parentUser . phone ) body . phone = parentUser . phone ;
229+ if ( ! body . address && parentUser . address ) body . address = parentUser . address ;
230+ if ( ! body . address2 && parentUser . address2 ) body . address2 = parentUser . address2 ;
231+ if ( ! body . billingCompany && parentUser . billingCompany ) body . billingCompany = parentUser . billingCompany ;
232+ if ( ! body . billingCity && parentUser . billingCity ) body . billingCity = parentUser . billingCity ;
233+ if ( ! body . billingState && parentUser . billingState ) body . billingState = parentUser . billingState ;
234+ if ( ! body . billingZip && parentUser . billingZip ) body . billingZip = parentUser . billingZip ;
235+ if ( ! body . billingCountry && parentUser . billingCountry ) body . billingCountry = parentUser . billingCountry ;
236+ }
224237 }
225238
226239 const valid = await validateUserRegistration ( ctx , ctx , { skipMinimumAge : ! ! parentRegistrationInvite } ) ;
@@ -243,7 +256,6 @@ export async function userRoutes(app: any, prefix = '') {
243256 ctx . set . status = 400 ;
244257 return { error : 'registration_email_reserved' , message : 'That email is reserved by the panel and cannot be used for registration.' } ;
245258 }
246- const userRepo = AppDataSource . getRepository ( User ) ;
247259
248260 if ( body . parentId != null ) {
249261 const parentId = Number ( body . parentId ) ;
@@ -568,7 +580,7 @@ export async function userRoutes(app: any, prefix = '') {
568580 } , {
569581 beforeHandle : authenticate ,
570582 body : t . Object ( { childEmail : t . Optional ( t . String ( ) ) } ) ,
571- response : { 200 : t . Object ( { success : t . Boolean ( ) , invite : t . Object ( { id : t . Number ( ) , token : t . String ( ) , childEmail : t . Optional ( t . String ( ) ) , link : t . String ( ) , createdAt : t . String ( ) , used : t . Boolean ( ) } ) } ) , 400 : t . Object ( { error : t . String ( ) } ) , 401 : t . Object ( { error : t . String ( ) } ) , 403 : t . Object ( { error : t . String ( ) } ) } ,
583+ response : { 200 : t . Object ( { success : t . Boolean ( ) , invite : t . Object ( { id : t . Number ( ) , token : t . String ( ) , childEmail : t . Union ( [ t . String ( ) , t . Null ( ) ] ) , link : t . String ( ) , createdAt : t . String ( ) , used : t . Boolean ( ) } ) } ) , 400 : t . Object ( { error : t . String ( ) } ) , 401 : t . Object ( { error : t . String ( ) } ) , 403 : t . Object ( { error : t . String ( ) } ) } ,
572584 detail : { summary : 'Create a parent registration invite for a child account' , tags : [ 'Users' ] }
573585 } ) ;
574586
@@ -599,7 +611,7 @@ export async function userRoutes(app: any, prefix = '') {
599611 } ;
600612 } , {
601613 beforeHandle : authenticate ,
602- response : { 200 : t . Object ( { success : t . Boolean ( ) , invites : t . Array ( t . Object ( { id : t . Number ( ) , token : t . String ( ) , childEmail : t . Optional ( t . String ( ) ) , link : t . String ( ) , createdAt : t . String ( ) , used : t . Boolean ( ) , usedAt : t . Optional ( t . Union ( [ t . String ( ) , t . Null ( ) ] ) ) , expiresAt : t . Optional ( t . Union ( [ t . String ( ) , t . Null ( ) ] ) ) } ) ) } ) , 401 : t . Object ( { error : t . String ( ) } ) } ,
614+ response : { 200 : t . Object ( { success : t . Boolean ( ) , invites : t . Array ( t . Object ( { id : t . Number ( ) , token : t . String ( ) , childEmail : t . Union ( [ t . String ( ) , t . Null ( ) ] ) , link : t . String ( ) , createdAt : t . String ( ) , used : t . Boolean ( ) , usedAt : t . Optional ( t . Union ( [ t . String ( ) , t . Null ( ) ] ) ) , expiresAt : t . Optional ( t . Union ( [ t . String ( ) , t . Null ( ) ] ) ) } ) ) } ) , 401 : t . Object ( { error : t . String ( ) } ) } ,
603615 detail : { summary : 'List parent registration invites for the current parent' , tags : [ 'Users' ] }
604616 } ) ;
605617
@@ -1991,14 +2003,16 @@ export async function userRoutes(app: any, prefix = '') {
19912003 return { error : 'invalid_date_of_birth' , message : 'dateOfBirth must be a valid date string in YYYY-MM-DD format.' } ;
19922004 }
19932005 const updatedAge = getAgeFromDate ( dateOfBirth ) ;
1994- if ( updatedAge !== null && updatedAge < 14 ) {
2006+ const effectiveCountry = typeof payload . billingCountry === 'string' ? payload . billingCountry : user . billingCountry ;
2007+ const minimumAge = await getMinimumAgeForCountry ( effectiveCountry ) ;
2008+ if ( updatedAge !== null && updatedAge < minimumAge ) {
19952009 if ( ! isAdmin ) {
19962010 ctx . set . status = 400 ;
1997- return { error : 'minimum_age' , message : ' Users must be at least 14 years old.' } ;
2011+ return { error : 'minimum_age' , message : ` Users must be at least ${ minimumAge } years old.` } ;
19982012 }
19992013 user . suspended = true ;
20002014 user . fraudFlag = true ;
2001- user . fraudReason = ' Underage account (<14 years)' ;
2015+ user . fraudReason = ` Underage account (<${ minimumAge } years)` ;
20022016 }
20032017 user . dateOfBirth = dateOfBirth ;
20042018 delete payload . dateOfBirth ;
0 commit comments