@@ -22,10 +22,12 @@ import { addShortTimeSpan } from 'src/lib/lang/time';
2222import { NamespaceService } from 'src/namespace' ;
2323import { ErrorCodes as SessionErrorCodes , SessionService } from 'src/session' ;
2424import { SmsRecordService } from 'src/sms' ;
25+ import { ThirdPartyService , ThirdPartySource } from 'src/third-party' ;
2526import { User , UserDocument , ErrorCodes as UserErrorCodes , UserService } from 'src/user' ;
2627
2728import { AuthService } from './auth.service' ;
2829import { ErrorCodes } from './constants' ;
30+ import { GithubDto } from './dto/github.dto' ;
2931import { LoginByEmailDto , LoginByPhoneDto , LoginDto , LogoutDto } from './dto/login.dto' ;
3032import { RefreshTokenDto } from './dto/refresh-token.dto' ;
3133import { RegisterByEmailDto , RegisterbyPhoneDto , RegisterDto } from './dto/register.dto' ;
@@ -47,20 +49,24 @@ export class AuthController {
4749 private readonly captchaService : CaptchaService ,
4850 private readonly emailRecordService : EmailRecordService ,
4951 private readonly smsRecordService : SmsRecordService ,
50- private readonly authService : AuthService
52+ private readonly authService : AuthService ,
53+ private readonly thirdPartyService : ThirdPartyService
5154 ) { }
5255
5356 _login = async ( user : UserDocument ) : Promise < SessionWithToken > => {
5457 const session = await this . sessionService . create ( {
5558 uid : user . id ,
56- expireAt : addShortTimeSpan ( SESSION_EXPIRES_IN ) , // session 先固定 7 天过期吧
59+ ns : user . ns ,
60+ type : user . type ,
61+ permissions : user . permissions ,
62+ refreshTokenExpireAt : addShortTimeSpan ( SESSION_EXPIRES_IN ) , // session 先固定 7 天过期吧
5763 } ) ;
5864
5965 const jwtpayload : JwtPayload = {
6066 uid : user . id ,
61- roles : user . roles ,
6267 ns : user . ns ,
63- super : user . super ,
68+ type : user . type ,
69+ permissions : user . permissions ,
6470 } ;
6571
6672 const tokenExpireAt = addShortTimeSpan ( TOKEN_EXPIRES_IN ) ;
@@ -119,7 +125,74 @@ export class AuthController {
119125 }
120126
121127 /**
122- * login with email and code
128+ * login by Github
129+ */
130+ @ApiOperation ( { operationId : 'loginByGithub' } )
131+ @HttpCode ( HttpStatus . OK )
132+ @ApiOkResponse ( {
133+ description : 'The session with token has been successfully created.' ,
134+ type : SessionWithToken ,
135+ } )
136+ @Post ( '@loginByGithub' )
137+ async loginByGithub ( @Body ( ) githubDto : GithubDto ) : Promise < SessionWithToken > {
138+ const { code } = githubDto ;
139+ const githubAccessToken = await this . authService . getGithubAccessToken ( code ) ;
140+ if ( ! githubAccessToken ) {
141+ throw new UnauthorizedException ( {
142+ code : ErrorCodes . AUTH_FAILED ,
143+ message : `github access token not found.` ,
144+ } ) ;
145+ }
146+ const githubUser = await this . authService . getGithubUser ( code ) ;
147+ if ( ! githubUser ) {
148+ throw new UnauthorizedException ( {
149+ code : ErrorCodes . AUTH_FAILED ,
150+ message : `github user not found.` ,
151+ } ) ;
152+ }
153+
154+ // github 已绑定用户
155+ if ( githubUser . uid ) {
156+ const user = await this . userService . get ( githubUser . uid ) ;
157+ if ( ! user ) {
158+ throw new UnauthorizedException ( {
159+ code : ErrorCodes . AUTH_FAILED ,
160+ message : `user not found.` ,
161+ } ) ;
162+ }
163+
164+ return this . _login ( user ) ;
165+ }
166+
167+ // github 未绑定用户
168+ const session = await this . sessionService . create ( {
169+ uid : githubUser . login ,
170+ source : ThirdPartySource . GITHUB ,
171+ refreshTokenExpireAt : addShortTimeSpan ( SESSION_EXPIRES_IN ) , // session 先固定 7 天过期吧
172+ } ) ;
173+
174+ const jwtpayload : JwtPayload = {
175+ uid : githubUser . login ,
176+ source : ThirdPartySource . GITHUB ,
177+ } ;
178+
179+ const tokenExpireAt = addShortTimeSpan ( TOKEN_EXPIRES_IN ) ;
180+ const token = this . jwtService . sign ( jwtpayload , {
181+ expiresIn : TOKEN_EXPIRES_IN ,
182+ subject : githubUser . login ,
183+ } ) ;
184+
185+ const res : SessionWithToken = {
186+ ...session . toJSON ( ) ,
187+ token,
188+ tokenExpireAt,
189+ } ;
190+
191+ return res ;
192+ }
193+
194+ /**
195+ * login by email and code
123196 */
124197 @ApiOperation ( { operationId : 'loginByEmail' } )
125198 @HttpCode ( HttpStatus . OK )
@@ -289,10 +362,9 @@ export class AuthController {
289362
290363 const jwtpayload : JwtPayload = {
291364 uid : user . id ,
292- acl : dto . acl ,
293- roles : user . roles ,
294365 ns : user . ns ,
295- super : user . super ,
366+ type : user . type ,
367+ permissions : user . permissions ,
296368 } ;
297369
298370 const token = this . jwtService . sign ( jwtpayload , {
@@ -326,7 +398,9 @@ export class AuthController {
326398 } ) ;
327399 }
328400
329- if ( session . expireAt . getTime ( ) < Date . now ( ) ) {
401+ const user = await this . userService . get ( session . uid ) ;
402+
403+ if ( session . refreshTokenExpireAt . getTime ( ) < Date . now ( ) ) {
330404 throw new UnauthorizedException ( {
331405 code : SessionErrorCodes . SESSION_EXPIRED ,
332406 message : 'Session has been expired.' ,
@@ -335,24 +409,25 @@ export class AuthController {
335409
336410 if ( session . shouldRotate ( ) ) {
337411 session = await this . sessionService . create ( {
338- uid : session . user . id ,
339- expireAt : addShortTimeSpan ( SESSION_EXPIRES_IN ) ,
340- acl : session . acl ,
412+ uid : user . id ,
413+ ns : user . ns ,
414+ type : user . type ,
415+ permissions : user . permissions ,
416+ refreshTokenExpireAt : addShortTimeSpan ( SESSION_EXPIRES_IN ) ,
341417 } ) ;
342418 }
343419
344420 const jwtpayload : JwtPayload = {
345- uid : session . user . id ,
346- acl : session . acl ,
347- roles : session . user . roles ,
348- ns : session . user . ns ,
349- super : session . user . super ,
421+ uid : user . id ,
422+ ns : user . ns ,
423+ type : user . type ,
424+ permissions : user . permissions ,
350425 } ;
351426
352427 const tokenExpireAt = addShortTimeSpan ( TOKEN_EXPIRES_IN ) ;
353428 const token = this . jwtService . sign ( jwtpayload , {
354429 expiresIn : TOKEN_EXPIRES_IN ,
355- subject : session . user . id ,
430+ subject : user . id ,
356431 } ) ;
357432
358433 return {
0 commit comments