-
Notifications
You must be signed in to change notification settings - Fork 0
Refactor/service token #101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 15 commits
3579359
2b34cfa
f3c3919
f01d74b
1c10f22
1f06596
e474ff0
dfe6891
5acf882
bbfce79
3a4a9c6
c3a98fd
549d5b5
2123ec8
2fcdc1d
92e7325
8de9607
36b01aa
4d65839
c9df95b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,6 +22,7 @@ import * as url from 'url'; | |
| import { SupportedServiceService } from 'src/supported-service/services/supported-service.service'; | ||
| import { | ||
| APP_ENVIRONMENT, | ||
| Context, | ||
| SERVICE_TYPES, | ||
| } from 'src/supported-service/services/iServiceList'; | ||
| import { UserRepository } from 'src/user/repository/user.repository'; | ||
|
|
@@ -35,6 +36,8 @@ import { CustomerOnboarding } from 'src/customer-onboarding/schemas/customer-onb | |
| import { Model } from 'mongoose'; | ||
| import { getAccessListForModule } from 'src/utils/utils'; | ||
| import { TokenModule } from 'src/config/access-matrix'; | ||
| import { redisClient } from 'src/utils/redis.provider'; | ||
| import { TIME } from 'src/utils/time-constant'; | ||
|
|
||
| export enum GRANT_TYPES { | ||
| access_service_kyc = 'access_service_kyc', | ||
|
|
@@ -61,7 +64,7 @@ export class AppAuthService { | |
| @InjectModel(CustomerOnboarding.name) | ||
| private readonly onboardModel: Model<CustomerOnboarding>, | ||
| private readonly webpageConfigRepo: WebPageConfigRepository, | ||
| ) {} | ||
| ) { } | ||
|
|
||
| async createAnApp( | ||
| createAppDto: CreateAppDto, | ||
|
|
@@ -541,7 +544,49 @@ export class AppAuthService { | |
| { appId, userId }, | ||
| updataAppDto, | ||
| ); | ||
| return this.getAppResponse(app); | ||
| const updatedapp = await this.getAppResponse(app); | ||
| // update redis | ||
|
|
||
| const baseKey = appId; | ||
| const dashboardRedisKey = `${appId}_${Context.idDashboard}`; | ||
|
|
||
| const updatedFields = { | ||
| whitelistedCors: updatedapp.whitelistedCors, | ||
| env: updatedapp.env ?? APP_ENVIRONMENT.dev, | ||
| appName: updatedapp.appName, | ||
| }; | ||
|
|
||
| const [baseDataString, dashboardDataString] = await Promise.all([ | ||
| redisClient.get(baseKey), | ||
| redisClient.get(dashboardRedisKey), | ||
| ]); | ||
|
|
||
| const updatePromises = []; | ||
|
|
||
| if (baseDataString) { | ||
| const baseData = JSON.parse(baseDataString); | ||
| const updatedBase = { ...baseData, ...updatedFields }; | ||
| updatePromises.push( | ||
| redisClient.set(baseKey, JSON.stringify(updatedBase), 'KEEPTTL'), | ||
| ); | ||
| } | ||
|
|
||
| if (dashboardDataString) { | ||
| const dashboardData = JSON.parse(dashboardDataString); | ||
| const updatedDashboard = { ...dashboardData, ...updatedFields }; | ||
| updatePromises.push( | ||
| redisClient.set( | ||
| dashboardRedisKey, | ||
| JSON.stringify(updatedDashboard), | ||
| 'KEEPTTL', | ||
| ), | ||
| ); | ||
| } | ||
|
|
||
| if (updatePromises.length > 0) { | ||
| await Promise.all(updatePromises); | ||
| } | ||
| return updatedapp; | ||
| } | ||
|
|
||
| async deleteApp(appId: string, userId: string): Promise<DeleteAppResponse> { | ||
|
|
@@ -619,6 +664,12 @@ export class AppAuthService { | |
| } | ||
| this.authzCreditRepository.deleteAuthzDetail({ appId }); | ||
| appDetail = await this.appRepository.findOneAndDelete({ appId, userId }); | ||
| // delete from redis | ||
| await Promise.all([ | ||
| redisClient.del(appId), | ||
| redisClient.del(`${appId}_${Context.idDashboard}`), | ||
| ]); | ||
| Logger.debug(`Redis cache cleaned for appId: ${appId}`); | ||
| return { appId: appDetail.appId }; | ||
| } | ||
|
|
||
|
|
@@ -643,7 +694,6 @@ export class AppAuthService { | |
| grantType, | ||
| ): Promise<{ access_token; expiresIn; tokenType }> { | ||
| Logger.log('generateAccessToken() method: starts....', 'AppAuthService'); | ||
|
|
||
| const apikeyIndex = appSecreatKey.split('.')[0]; | ||
| const appDetail = await this.appRepository.findOne({ | ||
| apiKeyPrefix: apikeyIndex, | ||
|
|
@@ -682,11 +732,25 @@ export class AppAuthService { | |
| const serviceType = appDetail.services[0]?.id; // TODO: remove this later | ||
| let grant_type = ''; | ||
| let accessList = []; | ||
| const redisKey = appDetail.appId; | ||
| const savedSession = await redisClient.get(redisKey); | ||
| if (savedSession) { | ||
| Logger.log('Using redis cached session', 'AppAuthService'); | ||
| const sessionJson = JSON.parse(savedSession); | ||
| const jwtPayload = { | ||
| appId: sessionJson.appId, | ||
| appName: sessionJson.appName, | ||
| grantType: sessionJson.grantType, | ||
| subdomain: sessionJson.subdomain, | ||
| sessionId: redisKey, | ||
| }; | ||
| return this.getAccessToken(jwtPayload, expiresin); | ||
| } | ||
| switch (serviceType) { | ||
| case SERVICE_TYPES.SSI_API: { | ||
| grant_type = GRANT_TYPES.access_service_ssi; | ||
| accessList = getAccessListForModule( | ||
| TokenModule.VERIFIER, | ||
| TokenModule.APP_AUTH, | ||
| SERVICE_TYPES.SSI_API, | ||
| ); | ||
| break; | ||
|
|
@@ -703,15 +767,15 @@ export class AppAuthService { | |
| } | ||
| grant_type = grantType || GRANT_TYPES.access_service_kyc; | ||
| accessList = getAccessListForModule( | ||
| TokenModule.VERIFIER, | ||
| TokenModule.APP_AUTH, | ||
| SERVICE_TYPES.CAVACH_API, | ||
| ); | ||
| break; | ||
| } | ||
| case SERVICE_TYPES.QUEST: { | ||
| grant_type = GRANT_TYPES.access_service_quest; | ||
| accessList = getAccessListForModule( | ||
| TokenModule.VERIFIER, | ||
| TokenModule.APP_AUTH, | ||
| SERVICE_TYPES.QUEST, | ||
| ); | ||
| break; | ||
|
|
@@ -726,15 +790,33 @@ export class AppAuthService { | |
| `You are not authorized to access service of type ${serviceType}`, | ||
| ]); | ||
| } | ||
|
|
||
| return this.getAccessToken(grant_type, appDetail, expiresin, accessList); | ||
| const jwtPayload = { | ||
| appId: appDetail.appId, | ||
| appName: appDetail.appName, | ||
| grantType: grant_type, | ||
| subdomain: appDetail.subdomain, | ||
| sessionId: redisKey, | ||
| }; | ||
| await this.storeDataInRedis(grant_type, appDetail, accessList, redisKey); | ||
| return this.getAccessToken(jwtPayload, expiresin); | ||
| } | ||
|
|
||
| public async getAccessToken( | ||
| public async getAccessToken(data, expiresin = 4) { | ||
| const secret = this.config.get('JWT_SECRET'); | ||
| const token = await this.jwt.signAsync(data, { | ||
| expiresIn: expiresin.toString() + 'h', | ||
| secret, | ||
| }); | ||
| const expiresIn = (expiresin * 1 * 60 * 60 * 1000) / 1000; | ||
| Logger.log('generateAccessToken() method: ends....', 'AppAuthService'); | ||
|
|
||
| return { access_token: token, expiresIn, tokenType: 'Bearer' }; | ||
| } | ||
| public async storeDataInRedis( | ||
| grantType, | ||
| appDetail, | ||
| expiresin = 4, | ||
| accessList = [], | ||
| sessionId, | ||
| ) { | ||
| const payload = { | ||
| appId: appDetail.appId, | ||
|
|
@@ -763,27 +845,18 @@ export class AppAuthService { | |
| ) { | ||
| payload['dependentServices'] = appDetail.dependentServices; | ||
| } | ||
|
|
||
| const secret = this.config.get('JWT_SECRET'); | ||
|
|
||
| const token = await this.jwt.signAsync(payload, { | ||
| expiresIn: expiresin.toString() + 'h', | ||
| secret, | ||
| }); | ||
| const expiresIn = (expiresin * 1 * 60 * 60 * 1000) / 1000; | ||
| Logger.log('generateAccessToken() method: ends....', 'AppAuthService'); | ||
|
|
||
| return { access_token: token, expiresIn, tokenType: 'Bearer' }; | ||
| redisClient.set(sessionId, JSON.stringify(payload), 'EX', TIME.WEEK); | ||
|
||
| } | ||
|
|
||
| //access_service_ssi | ||
| //access_service_kyc | ||
|
|
||
| async grantPermission( | ||
| grantType: string, | ||
| appId: string, | ||
| user, | ||
| ): Promise<{ access_token; expiresIn; tokenType }> { | ||
| const context = Context.idDashboard; | ||
|
||
| const sessionId = `${appId}_${context}`; | ||
| const savedSession = await redisClient.get(sessionId); | ||
| switch (grantType) { | ||
| case GRANT_TYPES.access_service_ssi: | ||
| break; | ||
|
|
@@ -803,13 +876,23 @@ export class AppAuthService { | |
| } | ||
| } | ||
|
|
||
| if (savedSession) { | ||
| const app = JSON.parse(savedSession); | ||
| const dataToStore = { | ||
| appId, | ||
| appName: app.appName, | ||
| grantType, | ||
| subdomain: app.subdomain, | ||
| sessionId, | ||
| }; | ||
| return this.getAccessToken(dataToStore, 12); | ||
|
||
| } | ||
| const app = await this.getAppById(appId, user.userId); | ||
| if (!app) { | ||
| throw new BadRequestException([ | ||
| 'Invalid service id or you do not have access of this service', | ||
| ]); | ||
| } | ||
|
|
||
| const userDetails = user; | ||
| if (!userDetails) { | ||
| throw new UnauthorizedException([ | ||
|
|
@@ -868,7 +951,14 @@ export class AppAuthService { | |
| `You are not authorized to access service of type ${serviceType}`, | ||
| ]); | ||
| } | ||
|
|
||
| return this.getAccessToken(grantType, app, 12, accessList); | ||
| const tokenPayload = { | ||
| appId, | ||
| appName: app.appName, | ||
| grantType, | ||
| subdomain: app.subdomain, | ||
| sessionId, | ||
| }; | ||
| await this.storeDataInRedis(grantType, app, accessList, sessionId); | ||
| return this.getAccessToken(tokenPayload, 12); | ||
|
||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if I want to issue tokens in like min , I can not do becuae the expiry is always in hour
h?