@@ -11,6 +11,7 @@ import {
1111 Query ,
1212 Patch ,
1313 Delete ,
14+ UnauthorizedException ,
1415} from '@nestjs/common' ;
1516import { ConfigService } from '@nestjs/config' ;
1617
@@ -124,20 +125,33 @@ export class AuthController {
124125 @Req ( ) req : Request ,
125126 @Res ( ) res : Response ,
126127 ) : Promise < void > {
127- const profile = req . user as unknown as OAuthProfile ;
128- const result = await this . authService . validateOAuthLogin (
129- AuthProvider . GOOGLE ,
130- profile ,
131- ) ;
132128 const frontendUrl = this . configService . get < string > ( 'FRONTEND_URL' ) ;
133129
134- // Set HTTP-only cookie - in monorepo deployment, this cookie works directly
135- // since frontend and API are on the same domain
136- res . cookie ( 'access_token' , result . access_token , COOKIE_OPTIONS ) ;
137-
138- // Redirect to frontend callback page
139- // Token in URL is kept for backward compatibility and as fallback
140- res . redirect ( `${ frontendUrl } /auth/callback?token=${ result . access_token } ` ) ;
130+ try {
131+ const profile = req . user as unknown as OAuthProfile ;
132+ const result = await this . authService . validateOAuthLogin (
133+ AuthProvider . GOOGLE ,
134+ profile ,
135+ ) ;
136+
137+ // Set HTTP-only cookie - in monorepo deployment, this cookie works directly
138+ // since frontend and API are on the same domain
139+ res . cookie ( 'access_token' , result . access_token , COOKIE_OPTIONS ) ;
140+
141+ // Redirect to frontend callback page
142+ // Token in URL is kept for backward compatibility and as fallback
143+ res . redirect ( `${ frontendUrl } /auth/callback?token=${ result . access_token } ` ) ;
144+ } catch ( error ) {
145+ if (
146+ error instanceof UnauthorizedException &&
147+ error . message . includes ( 'blocked' )
148+ ) {
149+ res . redirect ( `${ frontendUrl } /blocked` ) ;
150+ } else {
151+ // Redirect to login with generic error for other issues
152+ res . redirect ( `${ frontendUrl } /login?error=oauth_failed` ) ;
153+ }
154+ }
141155 }
142156
143157 @Get ( 'github' )
@@ -152,24 +166,42 @@ export class AuthController {
152166 @Req ( ) req : Request ,
153167 @Res ( ) res : Response ,
154168 ) : Promise < void > {
155- const result = await this . authService . validateOAuthLogin (
156- AuthProvider . GITHUB ,
157- req . user as unknown as OAuthProfile ,
158- ) ;
159169 const frontendUrl = this . configService . get < string > ( 'FRONTEND_URL' ) ;
160170
161- // Set HTTP-only cookie - in monorepo deployment, this cookie works directly
162- res . cookie ( 'access_token' , result . access_token , COOKIE_OPTIONS ) ;
163-
164- // Redirect to frontend callback page
165- res . redirect ( `${ frontendUrl } /auth/callback?token=${ result . access_token } ` ) ;
171+ try {
172+ const result = await this . authService . validateOAuthLogin (
173+ AuthProvider . GITHUB ,
174+ req . user as unknown as OAuthProfile ,
175+ ) ;
176+
177+ // Set HTTP-only cookie - in monorepo deployment, this cookie works directly
178+ res . cookie ( 'access_token' , result . access_token , COOKIE_OPTIONS ) ;
179+
180+ // Redirect to frontend callback page
181+ res . redirect ( `${ frontendUrl } /auth/callback?token=${ result . access_token } ` ) ;
182+ } catch ( error ) {
183+ if (
184+ error instanceof UnauthorizedException &&
185+ error . message . includes ( 'blocked' )
186+ ) {
187+ res . redirect ( `${ frontendUrl } /blocked` ) ;
188+ } else {
189+ // Redirect to login with generic error for other issues
190+ res . redirect ( `${ frontendUrl } /login?error=oauth_failed` ) ;
191+ }
192+ }
166193 }
167194
168195 @Get ( 'me' )
169196 @UseGuards ( JwtAuthGuard )
170197 async getProfile ( @CurrentUser ( ) user : User ) : Promise < User > {
171198 // Fetch fresh user data from database to get updated role
172199 const freshUser = await this . authService . getUserById ( user . id ) ;
200+
201+ if ( ! freshUser . isActive ) {
202+ throw new UnauthorizedException ( 'Your account has been blocked.' ) ;
203+ }
204+
173205 return freshUser ;
174206 }
175207
@@ -309,12 +341,15 @@ export class AuthController {
309341 user . id ,
310342 UserRole . INSTRUCTOR ,
311343 ) ;
312- // eslint-disable-next-line @typescript-eslint/no-unused-vars
313- const { password, activationToken, passwordResetToken, ...safeUser } =
314- updatedUser ;
344+ const {
345+ password : _p ,
346+ activationToken : _at ,
347+ passwordResetToken : _prt ,
348+ ...safeUser
349+ } = updatedUser ;
315350 return {
316351 message : 'Successfully promoted to Instructor. Please return to the app.' ,
317- user : safeUser ,
352+ user : safeUser as SafeUser ,
318353 } ;
319354 }
320355}
0 commit comments