diff --git a/dictation_server/.env.local.example b/dictation_server/.env.local.example index 679d57e..1acdf09 100644 --- a/dictation_server/.env.local.example +++ b/dictation_server/.env.local.example @@ -24,4 +24,7 @@ STORAGE_ACCOUNT_KEY_AU=XXXXXXXXXXXXXXXXXXXXXXX STORAGE_ACCOUNT_KEY_EU=XXXXXXXXXXXXXXXXXXXXXXX STORAGE_ACCOUNT_ENDPOINT_US=https://AAAAAAAAAAAAA STORAGE_ACCOUNT_ENDPOINT_AU=https://AAAAAAAAAAAAA -STORAGE_ACCOUNT_ENDPOINT_EU=https://AAAAAAAAAAAAA \ No newline at end of file +STORAGE_ACCOUNT_ENDPOINT_EU=https://AAAAAAAAAAAAA +REDIS_HOST=redis-cache +REDIS_PORT=6379 +REDIS_PASSWORD=omdsredispass \ No newline at end of file diff --git a/dictation_server/src/app.module.ts b/dictation_server/src/app.module.ts index e8b4375..a7f613a 100644 --- a/dictation_server/src/app.module.ts +++ b/dictation_server/src/app.module.ts @@ -42,6 +42,7 @@ import { SortCriteriaRepositoryModule } from './repositories/sort_criteria/sort_ import { TemplateFilesRepositoryModule } from './repositories/template_files/template_files.repository.module'; import { WorktypesRepositoryModule } from './repositories/worktypes/worktypes.repository.module'; import { OptionItemsRepositoryModule } from './repositories/option_items/option_items.repository.module'; +import { RedisModule } from './gateways/redis/redis.module'; @Module({ imports: [ @@ -98,6 +99,7 @@ import { OptionItemsRepositoryModule } from './repositories/option_items/option_ SortCriteriaRepositoryModule, WorktypesRepositoryModule, OptionItemsRepositoryModule, + RedisModule, ], controllers: [ HealthController, diff --git a/dictation_server/src/features/auth/auth.controller.ts b/dictation_server/src/features/auth/auth.controller.ts index 83b75de..52bfe8d 100644 --- a/dictation_server/src/features/auth/auth.controller.ts +++ b/dictation_server/src/features/auth/auth.controller.ts @@ -23,13 +23,14 @@ import { import { retrieveAuthorizationToken } from '../../common/http/helper'; import { makeContext } from '../../common/log'; import { v4 as uuidv4 } from 'uuid'; +import { RedisService } from '../../gateways/redis/redis.service'; @ApiTags('auth') @Controller('auth') export class AuthController { constructor( // TODO「タスク 1828: IDトークンを一度しか使えないようにする」で使用する予定 - // private readonly redisService: RedisService, + private readonly redisService: RedisService, private readonly authService: AuthService, ) {} @@ -64,6 +65,8 @@ export class AuthController { HttpStatus.BAD_REQUEST, ); } + console.log('Storing ID tokens in redis'); + await this.redisService.set(body.idToken, 'used'); const context = makeContext(uuidv4()); @@ -77,6 +80,9 @@ export class AuthController { context, refreshToken, ); + const res = await this.redisService.get(body.idToken); + console.log('Obtaining an ID token from redis'); + console.log(res); return { accessToken, diff --git a/dictation_server/src/features/auth/auth.module.ts b/dictation_server/src/features/auth/auth.module.ts index 6db0c3f..00fae6e 100644 --- a/dictation_server/src/features/auth/auth.module.ts +++ b/dictation_server/src/features/auth/auth.module.ts @@ -4,8 +4,9 @@ import { AdB2cModule } from '../../gateways/adb2c/adb2c.module'; import { UsersRepositoryModule } from '../../repositories/users/users.repository.module'; import { AuthController } from './auth.controller'; import { AuthService } from './auth.service'; +import { RedisModule } from '../../gateways/redis/redis.module'; @Module({ - imports: [ConfigModule, AdB2cModule, UsersRepositoryModule], + imports: [ConfigModule, AdB2cModule, UsersRepositoryModule, RedisModule], controllers: [AuthController], providers: [AuthService], }) diff --git a/dictation_server/src/gateways/redis/redis.module.ts b/dictation_server/src/gateways/redis/redis.module.ts new file mode 100644 index 0000000..e222aa1 --- /dev/null +++ b/dictation_server/src/gateways/redis/redis.module.ts @@ -0,0 +1,36 @@ +import { CacheModule, Module } from '@nestjs/common'; +import { ConfigModule, ConfigService } from '@nestjs/config'; +import * as redisStore from 'cache-manager-redis-store'; +import { RedisService } from './redis.service'; + +@Module({ + imports: [ + CacheModule.registerAsync({ + imports: [ConfigModule], + useFactory: async (configService: ConfigService) => { + if (process.env.STAGE === 'local') { + return { + store: redisStore, + host: configService.get('REDIS_HOST'), + port: configService.get('REDIS_PORT'), + password: configService.get('REDIS_PASSWORD'), + ttl: configService.get('REDIS_TTL'), + }; + } + return { + store: redisStore, + url: `rediss://${configService.get('REDIS_HOST')}:${configService.get( + 'REDIS_PORT', + )}`, + password: configService.get('REDIS_PASSWORD'), + ttl: configService.get('REDIS_TTL'), + tls: {}, + }; + }, + inject: [ConfigService], + }), + ], + providers: [RedisService], + exports: [RedisService], +}) +export class RedisModule {} diff --git a/dictation_server/src/gateways/redis/redis.service.ts b/dictation_server/src/gateways/redis/redis.service.ts new file mode 100644 index 0000000..330a9bc --- /dev/null +++ b/dictation_server/src/gateways/redis/redis.service.ts @@ -0,0 +1,30 @@ +import { + CACHE_MANAGER, + Inject, + Injectable, + InternalServerErrorException, +} from '@nestjs/common'; +import { Cache } from 'cache-manager'; + +// TODO「タスク 1828: IDトークンを一度しか使えないようにする」で本実装する予定 +@Injectable() +export class RedisService { + constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {} + + async set(key: string, value: string): Promise { + try { + await this.cacheManager.set(key, value); + } catch (error) { + throw new InternalServerErrorException(); + } + } + + async get(key: string): Promise { + try { + const value = await this.cacheManager.get(key); + return value; + } catch (error) { + throw new InternalServerErrorException(); + } + } +}