fix(session-service): properly handle session store results

Previously, an undefined result in fetchUsernameForSessionId
was handled the same way as an error, rejecting the promise.

This fixes the behavior, only rejecting the promise if an error
is returned from the session store and properly returning
undefined if the session store returns that.

Signed-off-by: David Mehren <git@herrmehren.de>
This commit is contained in:
David Mehren 2023-10-07 18:30:42 +02:00
parent 4426d6f51a
commit 56e2270736
4 changed files with 27 additions and 6 deletions

View file

@ -128,10 +128,14 @@ export class WebsocketGateway implements OnGatewayConnection {
): Promise<User | null> {
const sessionId = this.sessionService.extractSessionIdFromRequest(request);
this.logger.debug(
'Checking if sessionId is empty',
'findUserByRequestSession',
);
if (sessionId.isEmpty()) {
return null;
}
this.logger.debug('sessionId is not empty', 'findUserByRequestSession');
const username = await this.sessionService.fetchUsernameForSessionId(
sessionId.get(),
);

View file

@ -6,11 +6,12 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { LoggerModule } from '../logger/logger.module';
import { Session } from './session.entity';
import { SessionService } from './session.service';
@Module({
imports: [TypeOrmModule.forFeature([Session])],
imports: [TypeOrmModule.forFeature([Session]), LoggerModule],
exports: [SessionService],
providers: [SessionService],
})

View file

@ -11,9 +11,12 @@ import { IncomingMessage } from 'http';
import { Mock } from 'ts-mockery';
import { Repository } from 'typeorm';
import { AppConfig } from '../config/app.config';
import { AuthConfig } from '../config/auth.config';
import { DatabaseType } from '../config/database-type.enum';
import { DatabaseConfig } from '../config/database.config';
import { Loglevel } from '../config/loglevel.enum';
import { ConsoleLoggerService } from '../logger/console-logger.service';
import { HEDGEDOC_SESSION } from '../utils/session';
import { Session } from './session.entity';
import { SessionService, SessionState } from './session.service';
@ -63,6 +66,7 @@ describe('SessionService', () => {
.mockReturnValue(mockedTypeormStore);
sessionService = new SessionService(
new ConsoleLoggerService({ loglevel: Loglevel.DEBUG } as AppConfig),
mockedSessionRepository,
databaseConfigMock,
authConfigMock,

View file

@ -17,6 +17,7 @@ import { DatabaseType } from '../config/database-type.enum';
import databaseConfiguration, {
DatabaseConfig,
} from '../config/database.config';
import { ConsoleLoggerService } from '../logger/console-logger.service';
import { HEDGEDOC_SESSION } from '../utils/session';
import { Username } from '../utils/username';
import { Session } from './session.entity';
@ -36,12 +37,14 @@ export class SessionService {
private readonly typeormStore: TypeormStore;
constructor(
private readonly logger: ConsoleLoggerService,
@InjectRepository(Session) private sessionRepository: Repository<Session>,
@Inject(databaseConfiguration.KEY)
private dbConfig: DatabaseConfig,
@Inject(authConfiguration.KEY)
private authConfig: AuthConfig,
) {
this.logger.setContext(SessionService.name);
this.typeormStore = new TypeormStore({
cleanupLimit: 2,
limitSubquery: dbConfig.type !== DatabaseType.MARIADB,
@ -61,12 +64,21 @@ export class SessionService {
*/
fetchUsernameForSessionId(sessionId: string): Promise<Username | undefined> {
return new Promise((resolve, reject) => {
this.logger.debug(
`Fetching username for sessionId ${sessionId}`,
'fetchUsernameForSessionId',
);
this.typeormStore.get(
sessionId,
(error?: Error, result?: SessionState) =>
error || !result
? reject(error)
: resolve(result.username as Username),
(error?: Error, result?: SessionState) => {
this.logger.debug(
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`Got error ${error}, result ${result?.username} for sessionId ${sessionId}`,
'fetchUsernameForSessionId',
);
if (error) return reject(error);
return resolve(result?.username as Username);
},
);
});
}