import { EbacPassportManagerSettingsInterface } from '../../interfaces/ebac-passport-manager-settings.interface'; import * as session from 'express-session'; import { DynamoDB } from 'aws-sdk'; import { ConfigService } from '@nestjs/config'; import { AWS_EBAC_PASSPORT_REGION, AWS_EBAC_PASSPORT_USER_ACCESS_KEY, AWS_EBAC_PASSPORT_USER_SECRET_KEY, DEFAULT_AWS_REGION, DEFAULT_SESSION_TABLE_NAME, SESSION_SECRET, SESSION_TABLE_NAME, } from '../../constants'; import { Store } from 'express-session'; import { SessionManagerInterface } from './session-manager.interface'; import { SessionPassportInterface } from './interfaces/session-passport.interface'; import { MiddlewareInterface } from '../../interfaces/middleware.interface'; const DynamoDBStore = require('connect-dynamodb')({ session }); export class SessionManager implements SessionManagerInterface { configService: ConfigService; constructor(params: EbacPassportManagerSettingsInterface) { this.configService = params.configService; this.init(params); } init(params: EbacPassportManagerSettingsInterface): void { if (!params.app) { throw new Error('App not set'); } const secret: string = this.getSecret(params); const store: Store = this.initDynamoDbStore(params); params.app.use( session({ ...params.sessionSettings, store, secret, }), ); } getSessionPassport(params: MiddlewareInterface): SessionPassportInterface { const req = params.req; let passport: SessionPassportInterface = req?.session?.passport; if (passport) { return passport; } passport = this.initSessionPassportData(req); return passport; } clearSession(params: MiddlewareInterface): void { const req = params.req; const passport: SessionPassportInterface = req?.session?.passport; passport.users = []; delete passport.activeUser; delete passport.auth; } destroySession(params: MiddlewareInterface): void { const session = params?.req?.session; if(session) { session.destroy(); } } private initSessionPassportData(req): SessionPassportInterface { req.session.passport = {}; return req.session.passport; } private initDynamoDbStore( params: EbacPassportManagerSettingsInterface, ): Store { const table: string = this.getTableName(params); const region: string = this.getAwsRegion(); const accessKeyId: string = this.getAwsAccessKeyId(); const secretAccessKey: string = this.getAwsSecretAccessKey(); const client: DynamoDB = this.getDynamoDbClient(params); const dynamoDbStore: Store = new DynamoDBStore({ table, AWSConfigJSON: { region, accessKeyId, secretAccessKey, }, client, }); return dynamoDbStore; } private getDynamoDbClient( params: EbacPassportManagerSettingsInterface, ): DynamoDB { const region: string = this.getAwsRegion(); const accessKeyId: string = this.getAwsAccessKeyId(); const secretAccessKey: string = this.getAwsSecretAccessKey(); const client: DynamoDB = new DynamoDB({ region, credentials: { accessKeyId, secretAccessKey, }, }); return client; } private getSecret(params: EbacPassportManagerSettingsInterface): string { const secret: string = params?.sessionSettings?.secret || this.configService.get(SESSION_SECRET); if (!secret) { throw new Error(`${SESSION_SECRET} not set`); } return secret; } private getTableName(params: EbacPassportManagerSettingsInterface): string { const tableName: string = params?.sessionSettings?.tableName || this.configService.get(SESSION_TABLE_NAME) || DEFAULT_SESSION_TABLE_NAME; return tableName; } private getAwsRegion(): string { const region: string = this.configService.get(AWS_EBAC_PASSPORT_REGION) || DEFAULT_AWS_REGION; return region; } private getAwsSecretAccessKey(): string { const secretAccessKey: string = this.configService.get( AWS_EBAC_PASSPORT_USER_SECRET_KEY, ); return secretAccessKey; } private getAwsAccessKeyId(): string { const accessKeyId: string = this.configService.get( AWS_EBAC_PASSPORT_USER_ACCESS_KEY, ); return accessKeyId; } }