Skip to content

Commit

Permalink
feat(env): delete env after start container
Browse files Browse the repository at this point in the history
  • Loading branch information
anteqkois committed May 25, 2024
1 parent 5243b19 commit ba3d03a
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 24 deletions.
1 change: 1 addition & 0 deletions apps/api-gateway/docker-compose.prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ services:
- redis
volumes:
- ./.env:/app/.env
- ./.cache:/app/.cache
redis:
image: redis:alpine
container_name: redis
Expand Down
29 changes: 27 additions & 2 deletions libs/nest-core/src/core.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ThrottlerGuard, ThrottlerModule } from '@nestjs/throttler'
// import * as basicAuth from '@fastify/basic-auth';
// import { RedisModule, RedisModuleOptions } from '@liaoliaots/nestjs-redis'
import { BullModule } from '@nestjs/bullmq'
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common'
import { MiddlewareConsumer, Module, NestModule, OnApplicationBootstrap } from '@nestjs/common'
import { ConfigModule, ConfigService } from '@nestjs/config'
import { APP_FILTER, APP_GUARD } from '@nestjs/core'
import { MongodbModule } from './lib/mongodb'
Expand Down Expand Up @@ -88,7 +88,32 @@ import { QUEUES } from './modules/workers/flow-worker/queues/types'
],
exports: [],
})
export class CoreModule implements NestModule {
export class CoreModule implements NestModule, OnApplicationBootstrap {
async onApplicationBootstrap() {

// Clear env
setTimeout(() => {
delete process.env['LINKERRY_API_KEY']
delete process.env['APPS_SECRET']
delete process.env['MONGO_PROTOCOL']
delete process.env['MONGO_USERNAME']
delete process.env['MONGO_PASSWORD']
delete process.env['MONGO_HOST']
delete process.env['MONGO_DATABASE']
delete process.env['APP_WEBHOOK_SECRETS']
delete process.env['TAWK_API_KEY']
delete process.env['STRIPE_WEBHOOK_SECRET']
delete process.env['STRIPE_API_KEY']
delete process.env['REDIS_PASSWORD']
delete process.env['JWT_SECRET']
delete process.env['COOKIES_SIGNATURE']
delete process.env['ENCRYPTION_KEY']
delete process.env['ENCRYPTION_ALG']
delete process.env['IV_LENGTH']

console.log('CLEARED')
}, 15_000)
}
// Add a middleware on all routes
configure(consumer: MiddlewareConsumer) {
consumer.apply(RequestLoggerMiddleware).forRoutes('*')
Expand Down
11 changes: 8 additions & 3 deletions libs/nest-core/src/lib/auth/guards/admin.guard.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LINKERRY_API_KEY_HEADER } from '@linkerry/shared'
import { CustomError, ErrorCode, LINKERRY_API_KEY_HEADER, isEmpty } from '@linkerry/shared'
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
import { Reflector } from '@nestjs/core'
Expand All @@ -7,14 +7,19 @@ import { Observable } from 'rxjs'

@Injectable()
export class AdminGuard implements CanActivate {
constructor(private readonly reflector: Reflector, private readonly configService: ConfigService) {}
private LINKERRY_API_KEY: string

constructor(private readonly reflector: Reflector, private readonly configService: ConfigService) {
this.LINKERRY_API_KEY = this.configService.getOrThrow('LINKERRY_API_KEY')
if (isEmpty(this.LINKERRY_API_KEY)) throw new CustomError(`LINKERRY_API_KEY is empty`, ErrorCode.SYSTEM_ENV_INVALID)
}

canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest() as FastifyRequest
const apiKey = request.headers[LINKERRY_API_KEY_HEADER]

if (!apiKey) return false
if (apiKey !== this.configService.getOrThrow('LINKERRY_API_KEY')) return false
if (apiKey !== this.LINKERRY_API_KEY) return false
return true
}
}
16 changes: 12 additions & 4 deletions libs/nest-core/src/lib/auth/jwt-custom.service.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import { JwtTokenPayload } from '@linkerry/shared'
import { CustomError, ErrorCode, JwtTokenPayload, isEmpty } from '@linkerry/shared'
import { Injectable } from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
import { JwtService } from '@nestjs/jwt'
import dayjs from 'dayjs'

@Injectable()
export class JWTCustomService {
constructor(private readonly configService: ConfigService, private readonly jwtService: JwtService) {}
private JWT_SECRET: string
private JWT_ACCES_TOKEN_EXPIRE_SSECONDS: string

constructor(private readonly configService: ConfigService, private readonly jwtService: JwtService) {
this.JWT_SECRET = this.configService.getOrThrow('JWT_SECRET')
if (isEmpty(this.JWT_SECRET)) throw new CustomError(`JWT_SECRET is empty`, ErrorCode.SYSTEM_ENV_INVALID)
this.JWT_ACCES_TOKEN_EXPIRE_SSECONDS = this.configService.getOrThrow('JWT_ACCES_TOKEN_EXPIRE_SSECONDS')
if (isEmpty(this.JWT_ACCES_TOKEN_EXPIRE_SSECONDS)) throw new CustomError(`JWT_ACCES_TOKEN_EXPIRE_SSECONDS is empty`, ErrorCode.SYSTEM_ENV_INVALID)
}

generateToken({ payload }: { payload: Omit<JwtTokenPayload, 'iss' | 'exp'> }) {
const secret = this.configService.get('JWT_SECRET')
const expireUnix = dayjs().unix() + Number(this.configService.get<number>('JWT_ACCES_TOKEN_EXPIRE_SSECONDS', 3600))
const secret = this.JWT_SECRET
const expireUnix = dayjs().unix() + Number(this.JWT_ACCES_TOKEN_EXPIRE_SSECONDS)

return this.jwtService.sign({ ...payload, iss: 'linkerry', exp: expireUnix }, { secret })
}
Expand Down
32 changes: 20 additions & 12 deletions libs/nest-core/src/lib/crypto/crypto.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,27 @@ import { createCipheriv, createDecipheriv, randomBytes } from 'crypto'

@Injectable()
export class CryptoService {
private readonly ivLength = 16
private readonly algorithm = 'aes-256-cbc'
SECRET: string
private IV_LENGTH: number
private ENCRYPTION_ALG: string
private ENCRYPTION_KEY: string

constructor(private readonly configService: ConfigService) {
this.SECRET = this.configService.getOrThrow<string>('ENCRYPTION_KEY')
if (isEmpty(this.SECRET)) throw new CustomError(`ENCRYPTION_KEY is empty`, ErrorCode.SYSTEM_ENV_INVALID)
this.ENCRYPTION_KEY = this.configService.getOrThrow<string>('ENCRYPTION_KEY')
if (isEmpty(this.ENCRYPTION_KEY)) throw new CustomError(`ENCRYPTION_KEY is empty`, ErrorCode.SYSTEM_ENV_INVALID)

this.ENCRYPTION_ALG = this.configService.getOrThrow<string>('ENCRYPTION_ALG')
console.log('this.ENCRYPTION_ALG');
console.log(this.ENCRYPTION_ALG);
if (isEmpty(this.ENCRYPTION_ALG)) throw new CustomError(`ENCRYPTION_ALG is empty`, ErrorCode.SYSTEM_ENV_INVALID)

this.IV_LENGTH = +this.configService.getOrThrow<string>('IV_LENGTH')
if (isEmpty(this.IV_LENGTH)) throw new CustomError(`IV_LENGTH is empty`, ErrorCode.SYSTEM_ENV_INVALID)
}

encryptString(inputString: string, customSecret?: string): EncryptedObject {
const iv = randomBytes(this.ivLength) // Generate a random initialization vector
const key = Buffer.from(customSecret ?? this.SECRET, 'binary')
const cipher = createCipheriv(this.algorithm, key, iv) // Create a cipher with the key and initialization vector
const iv = randomBytes(this.IV_LENGTH) // Generate a random initialization vector
const key = Buffer.from(customSecret ?? this.ENCRYPTION_KEY, 'binary')
const cipher = createCipheriv(this.ENCRYPTION_ALG, key, iv) // Create a cipher with the key and initialization vector
let encrypted = cipher.update(inputString, 'utf8', 'hex')
encrypted += cipher.final('hex')
return {
Expand All @@ -33,17 +41,17 @@ export class CryptoService {

decryptObject<T>(encryptedObject: EncryptedObject, customSecret?: string): T {
const iv = Buffer.from(encryptedObject.iv, 'hex')
const key = Buffer.from(customSecret ?? this.SECRET, 'binary')
const decipher = createDecipheriv(this.algorithm, key, iv)
const key = Buffer.from(customSecret ?? this.ENCRYPTION_KEY, 'binary')
const decipher = createDecipheriv(this.ENCRYPTION_ALG, key, iv)
let decrypted = decipher.update(encryptedObject.data, 'hex', 'utf8')
decrypted += decipher.final('utf8')
return JSON.parse(decrypted)
}

decryptString(encryptedObject: EncryptedObject, customSecret?: string): string {
const iv = Buffer.from(encryptedObject.iv, 'hex')
const key = Buffer.from(customSecret ?? this.SECRET, 'binary')
const decipher = createDecipheriv(this.algorithm, key, iv)
const key = Buffer.from(customSecret ?? this.ENCRYPTION_KEY, 'binary')
const decipher = createDecipheriv(this.ENCRYPTION_ALG, key, iv)
let decrypted = decipher.update(encryptedObject.data, 'hex', 'utf8')
decrypted += decipher.final('utf8')
return decrypted
Expand Down
10 changes: 7 additions & 3 deletions libs/nest-core/src/modules/users/users.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Id, User, assertNotNullOrUndefined } from '@linkerry/shared'
import { CustomError, ErrorCode, Id, User, assertNotNullOrUndefined, isEmpty } from '@linkerry/shared'
import { Injectable, Logger } from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
import { InjectModel } from '@nestjs/mongoose'
Expand All @@ -10,8 +10,12 @@ import { UserDocument, UserModel } from './schemas/user.schema'
@Injectable()
export class UsersService {
private readonly logger = new Logger(UsersService.name)
private TAWK_API_KEY: string

constructor(@InjectModel(UserModel.name) private userModel: Model<UserDocument>, private readonly configService: ConfigService) {}
constructor(@InjectModel(UserModel.name) private userModel: Model<UserDocument>, private readonly configService: ConfigService) {
this.TAWK_API_KEY = this.configService.getOrThrow('TAWK_API_KEY')
if (isEmpty(this.TAWK_API_KEY)) throw new CustomError(`TAWK_API_KEY is empty`, ErrorCode.SYSTEM_ENV_INVALID)
}

async findOne(filter: FilterQuery<User>) {
return this.userModel.findOne(filter)
Expand All @@ -26,7 +30,7 @@ export class UsersService {
_id: userId,
})
assertNotNullOrUndefined(user, 'user')
const hmac = createHmac('sha256', this.configService.getOrThrow('TAWK_API_KEY'))
const hmac = createHmac('sha256', this.TAWK_API_KEY)
hmac.update(user.email)
const hash = hmac.digest('hex')
return hash
Expand Down

0 comments on commit ba3d03a

Please sign in to comment.