11import { Request , Response , NextFunction } from 'express' ;
22import { logger } from '../../utils/logger' ;
3- import { registerSchema , phoneSchema } from './auth.schema' ;
3+ import { registerSchema , phoneSchema , loginSchema } from './auth.schema' ;
44import { sendOtpSms } from '../../Services/sms.service' ;
55import { generateotp } from '../../utils/otp' ;
66import { appDataSouce } from '../../data-source' ;
77import { Otp } from '../../entities/opt' ;
88import { User } from '../../entities/User' ;
99import { signAccessToken } from '../../Services/jwt.service' ;
1010import { createRefreshTokenSession } from '../../Services/authToken' ;
11+ import bcrypt from 'bcrypt' ;
1112
1213export const sendOtp = async (
1314 req : Request ,
@@ -16,26 +17,54 @@ export const sendOtp = async (
1617) => {
1718 try {
1819 logger . info ( 'reached' ) ;
20+
1921 const result = phoneSchema . safeParse ( req . body ) ;
2022 if ( ! result . success ) {
21- return res
22- . status ( 400 )
23- . json ( { message : 'validation vailed' , error : result . error ?. format ( ) } ) ;
23+ return res . status ( 400 ) . json ( {
24+ message : 'validation failed' ,
25+ error : result . error . format ( ) ,
26+ } ) ;
27+ }
28+
29+ const phoneNumber = result . data . phoneNumber ;
30+
31+ const userRepo = appDataSouce . getRepository ( User ) ;
32+ const otpRepo = appDataSouce . getRepository ( Otp ) ;
33+
34+ const existingUser = await userRepo . findOne ( {
35+ where : { phoneNumber } ,
36+ } ) ;
37+
38+ if (
39+ existingUser &&
40+ existingUser . isPhoneVerified === true &&
41+ existingUser . passwordHash
42+ ) {
43+ return res . status ( 409 ) . json ( {
44+ success : false ,
45+ next : 'login' ,
46+ message : 'Account already exists. Please login with password.' ,
47+ } ) ;
2448 }
25- const otpRep = appDataSouce . getRepository ( Otp ) ;
26- const otpcode = generateotp ( ) ;
27- logger . debug ( { otpcode } , 'otp is' ) ;
28- const phoneNumber = result . data ?. phoneNumber ;
29- await sendOtpSms ( phoneNumber , otpcode . toString ( ) ) ;
30- await otpRep . delete ( { phoneNumber } ) ;
31- await otpRep . save ( {
49+
50+ const otpCode = generateotp ( ) ;
51+ logger . debug ( { otpCode } , 'otp is' ) ;
52+
53+ await sendOtpSms ( phoneNumber , otpCode . toString ( ) ) ;
54+
55+ await otpRepo . delete ( { phoneNumber } ) ;
56+ await otpRepo . save ( {
3257 phoneNumber,
33- otp : otpcode . toString ( ) ,
58+ otp : otpCode . toString ( ) ,
3459 expiresAt : new Date ( Date . now ( ) + 5 * 60 * 1000 ) ,
3560 } ) ;
36- res . status ( 200 ) . json ( { message : 'otp sent success fully ' , success : true } ) ;
61+
62+ return res . status ( 200 ) . json ( {
63+ success : true ,
64+ message : 'OTP sent successfully' ,
65+ } ) ;
3766 } catch ( err ) {
38- logger . error ( 'error in register ' ) ;
67+ logger . error ( { err } , 'error in sendOtp ' ) ;
3968 next ( err ) ;
4069 }
4170} ;
@@ -54,9 +83,7 @@ export const verifyotp = async (
5483 . status ( 400 )
5584 . json ( { message : ' otp and phoneNumber are required' } ) ;
5685 }
57-
5886 const otpRepo = appDataSouce . getRepository ( Otp ) ;
59- const userRepo = appDataSouce . getRepository ( User ) ;
6087 const otpRecord = await otpRepo . findOne ( {
6188 where : {
6289 phoneNumber,
@@ -79,26 +106,7 @@ export const verifyotp = async (
79106 return res . status ( 400 ) . json ( { message : 'Invalid OTP' } ) ;
80107 }
81108 otpRecord . verified = true ;
82- const existingUser = await userRepo . findOne ( {
83- where : { phoneNumber } ,
84- } ) ;
85109 await otpRepo . save ( otpRecord ) ;
86- console . log ( 'ACCESS_TOKEN_SECRET:' , process . env . ACCESS_TOKEN_SECRET ) ;
87-
88- if ( existingUser ) {
89- const accessToken = signAccessToken ( {
90- userId : existingUser . id ,
91- } ) ;
92-
93- const refreshToken = await createRefreshTokenSession ( existingUser ) ;
94-
95- return res . status ( 200 ) . json ( {
96- success : true ,
97- userExists : true ,
98- accessToken,
99- refreshToken,
100- } ) ;
101- }
102110
103111 return res . status ( 200 ) . json ( {
104112 success : true ,
@@ -121,26 +129,42 @@ export const register = async (
121129 const result = registerSchema . safeParse ( req . body ) ;
122130 if ( ! result . success ) {
123131 return res . status ( 400 ) . json ( {
124- message : 'invalid registation data' ,
132+ message : 'invalid registration data' ,
125133 errors : result . error . format ( ) ,
126134 } ) ;
127135 }
128- const { otpId, name, age, gender, interests, email } = result . data ;
136+
137+ const {
138+ otpId,
139+ name,
140+ age,
141+ gender,
142+ interests,
143+ email,
144+ password,
145+ confirmPassword,
146+ } = result . data ;
147+
129148 if ( ! otpId ) {
130- return res . status ( 400 ) . json ( { message : 'otpid requuired' } ) ;
149+ return res . status ( 400 ) . json ( { message : 'otpId required' } ) ;
150+ }
151+
152+ if ( password !== confirmPassword ) {
153+ return res . status ( 400 ) . json ( {
154+ message : 'Passwords do not match' ,
155+ } ) ;
131156 }
157+
132158 const otpRepo = appDataSouce . getRepository ( Otp ) ;
133159 const userRepo = appDataSouce . getRepository ( User ) ;
134160
135161 const otpRecord = await otpRepo . findOne ( {
136162 where : { id : otpId } ,
137163 } ) ;
138- if ( ! otpRecord ) {
139- return res . status ( 400 ) . json ( { message : 'invalid registration ' } ) ;
140- }
141- if ( ! otpRecord . verified ) {
164+
165+ if ( ! otpRecord || ! otpRecord . verified ) {
142166 return res . status ( 400 ) . json ( {
143- message : 'OTP not verified' ,
167+ message : 'OTP not verified or invalid ' ,
144168 } ) ;
145169 }
146170
@@ -150,10 +174,13 @@ export const register = async (
150174 where : { phoneNumber } ,
151175 } ) ;
152176
153- if ( existingUser ) {
154- return res . status ( 409 ) . json ( { message : 'User already exists' } ) ;
177+ if ( existingUser && existingUser . passwordHash ) {
178+ return res . status ( 409 ) . json ( {
179+ message : 'User already exists' ,
180+ } ) ;
155181 }
156- // const hashedPassword = await bcrypt.hash(password,10)
182+
183+ const passwordHash = await bcrypt . hash ( password , 10 ) ;
157184
158185 const user = userRepo . create ( {
159186 phoneNumber,
@@ -162,9 +189,12 @@ export const register = async (
162189 gender,
163190 interests,
164191 email,
192+ passwordHash,
193+ isPhoneVerified : true ,
165194 } ) ;
166195
167196 await userRepo . save ( user ) ;
197+
168198 await otpRepo . delete ( { id : otpId } ) ;
169199
170200 const accessToken = signAccessToken ( {
@@ -184,3 +214,66 @@ export const register = async (
184214 next ( err ) ;
185215 }
186216} ;
217+
218+ export const login = async (
219+ req : Request ,
220+ res : Response ,
221+ next : NextFunction ,
222+ ) => {
223+ try {
224+ const result = loginSchema . safeParse ( req . body ) ;
225+ if ( ! result . success ) {
226+ return res . status ( 400 ) . json ( {
227+ message : 'Invalid login data' ,
228+ errors : result . error . format ( ) ,
229+ } ) ;
230+ }
231+
232+ const { phoneNumber, password } = result . data ;
233+
234+ const userRepo = appDataSouce . getRepository ( User ) ;
235+
236+ // 2️⃣ find user
237+ const user = await userRepo . findOne ( {
238+ where : { phoneNumber } ,
239+ } ) ;
240+
241+ if ( ! user ) {
242+ return res . status ( 401 ) . json ( {
243+ message : 'Invalid phone number or password' ,
244+ } ) ;
245+ }
246+
247+ // 3️⃣ block incomplete registration
248+ if ( ! user . passwordHash || ! user . isPhoneVerified ) {
249+ return res . status ( 403 ) . json ( {
250+ message : 'Account not fully registered' ,
251+ } ) ;
252+ }
253+
254+ // 4️⃣ compare password
255+ const isPasswordValid = await bcrypt . compare ( password , user . passwordHash ) ;
256+
257+ if ( ! isPasswordValid ) {
258+ return res . status ( 401 ) . json ( {
259+ message : 'Invalid phone number or password' ,
260+ } ) ;
261+ }
262+
263+ // 5️⃣ issue tokens
264+ const accessToken = signAccessToken ( {
265+ userId : user . id ,
266+ } ) ;
267+
268+ const refreshToken = await createRefreshTokenSession ( user ) ;
269+
270+ return res . status ( 200 ) . json ( {
271+ success : true ,
272+ accessToken,
273+ refreshToken,
274+ } ) ;
275+ } catch ( err ) {
276+ logger . error ( { err } , 'error in login' ) ;
277+ next ( err ) ;
278+ }
279+ } ;
0 commit comments