ESLint: Enable @typescript-eslint/return-await rule

This ensures stack traces are helpful at the cost of a slightly
lower performance (one more tick in the event loop).

Fixes #838

Signed-off-by: David Mehren <git@herrmehren.de>
This commit is contained in:
David Mehren 2021-02-20 20:14:36 +01:00
parent 2ba824d9e2
commit 9485597e6f
No known key found for this signature in database
GPG key ID: 185982BA4C42B7C3
8 changed files with 26 additions and 20 deletions

View file

@ -27,5 +27,7 @@ module.exports = {
{ argsIgnorePattern: '^_+$' }, { argsIgnorePattern: '^_+$' },
], ],
'@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off',
'no-return-await': 'off',
'@typescript-eslint/return-await': ['error', 'always'],
}, },
}; };

View file

@ -44,12 +44,16 @@ export class TokensController {
@Body('validUntil') validUntil: TimestampMillis, @Body('validUntil') validUntil: TimestampMillis,
): Promise<AuthTokenWithSecretDto> { ): Promise<AuthTokenWithSecretDto> {
// ToDo: Get real userName // ToDo: Get real userName
return this.authService.createTokenForUser('hardcoded', label, validUntil); return await this.authService.createTokenForUser(
'hardcoded',
label,
validUntil,
);
} }
@Delete('/:keyId') @Delete('/:keyId')
@HttpCode(204) @HttpCode(204)
async deleteToken(@Param('keyId') keyId: string) { async deleteToken(@Param('keyId') keyId: string) {
return this.authService.removeToken(keyId); return await this.authService.removeToken(keyId);
} }
} }

View file

@ -53,7 +53,7 @@ export class MeController {
@Get('history') @Get('history')
async getUserHistory(@Request() req): Promise<HistoryEntryDto[]> { async getUserHistory(@Request() req): Promise<HistoryEntryDto[]> {
const foundEntries = await this.historyService.getEntriesByUser(req.user); const foundEntries = await this.historyService.getEntriesByUser(req.user);
return Promise.all( return await Promise.all(
foundEntries.map( foundEntries.map(
async (entry) => await this.historyService.toHistoryEntryDto(entry), async (entry) => await this.historyService.toHistoryEntryDto(entry),
), ),
@ -69,7 +69,7 @@ export class MeController {
): Promise<HistoryEntryDto> { ): Promise<HistoryEntryDto> {
// ToDo: Check if user is allowed to pin this history entry // ToDo: Check if user is allowed to pin this history entry
try { try {
return this.historyService.toHistoryEntryDto( return await this.historyService.toHistoryEntryDto(
await this.historyService.updateHistoryEntry( await this.historyService.updateHistoryEntry(
note, note,
req.user, req.user,
@ -103,7 +103,7 @@ export class MeController {
@Get('notes') @Get('notes')
async getMyNotes(@Request() req): Promise<NoteMetadataDto[]> { async getMyNotes(@Request() req): Promise<NoteMetadataDto[]> {
const notes = await this.notesService.getUserNotes(req.user); const notes = await this.notesService.getUserNotes(req.user);
return Promise.all( return await Promise.all(
notes.map((note) => this.notesService.toNoteMetadataDto(note)), notes.map((note) => this.notesService.toNoteMetadataDto(note)),
); );
} }

View file

@ -67,7 +67,7 @@ export class NotesController {
throw new UnauthorizedException('Creating note denied!'); throw new UnauthorizedException('Creating note denied!');
} }
this.logger.debug('Got raw markdown:\n' + text); this.logger.debug('Got raw markdown:\n' + text);
return this.noteService.toNoteDto( return await this.noteService.toNoteDto(
await this.noteService.createNote(text, undefined, req.user), await this.noteService.createNote(text, undefined, req.user),
); );
} }
@ -91,7 +91,7 @@ export class NotesController {
throw new UnauthorizedException('Reading note denied!'); throw new UnauthorizedException('Reading note denied!');
} }
await this.historyService.createOrUpdateHistoryEntry(note, req.user); await this.historyService.createOrUpdateHistoryEntry(note, req.user);
return this.noteService.toNoteDto(note); return await this.noteService.toNoteDto(note);
} }
@UseGuards(TokenAuthGuard) @UseGuards(TokenAuthGuard)
@ -106,7 +106,7 @@ export class NotesController {
} }
this.logger.debug('Got raw markdown:\n' + text, 'createNamedNote'); this.logger.debug('Got raw markdown:\n' + text, 'createNamedNote');
try { try {
return this.noteService.toNoteDto( return await this.noteService.toNoteDto(
await this.noteService.createNote(text, noteAlias, req.user), await this.noteService.createNote(text, noteAlias, req.user),
); );
} catch (e) { } catch (e) {
@ -153,7 +153,7 @@ export class NotesController {
throw new UnauthorizedException('Updating note denied!'); throw new UnauthorizedException('Updating note denied!');
} }
this.logger.debug('Got raw markdown:\n' + text, 'updateNote'); this.logger.debug('Got raw markdown:\n' + text, 'updateNote');
return this.noteService.toNoteDto( return await this.noteService.toNoteDto(
await this.noteService.updateNote(note, text), await this.noteService.updateNote(note, text),
); );
} catch (e) { } catch (e) {
@ -196,7 +196,7 @@ export class NotesController {
if (!this.permissionsService.mayRead(req.user, note)) { if (!this.permissionsService.mayRead(req.user, note)) {
throw new UnauthorizedException('Reading note denied!'); throw new UnauthorizedException('Reading note denied!');
} }
return this.noteService.toNoteMetadataDto(note); return await this.noteService.toNoteMetadataDto(note);
} catch (e) { } catch (e) {
if (e instanceof NotInDBError) { if (e instanceof NotInDBError) {
throw new NotFoundException(e.message); throw new NotFoundException(e.message);
@ -220,7 +220,7 @@ export class NotesController {
if (!this.permissionsService.isOwner(req.user, note)) { if (!this.permissionsService.isOwner(req.user, note)) {
throw new UnauthorizedException('Updating note denied!'); throw new UnauthorizedException('Updating note denied!');
} }
return this.noteService.toNotePermissionsDto( return await this.noteService.toNotePermissionsDto(
await this.noteService.updateNotePermissions(note, updateDto), await this.noteService.updateNotePermissions(note, updateDto),
); );
} catch (e) { } catch (e) {
@ -243,7 +243,7 @@ export class NotesController {
throw new UnauthorizedException('Reading note denied!'); throw new UnauthorizedException('Reading note denied!');
} }
const revisions = await this.revisionsService.getAllRevisions(note); const revisions = await this.revisionsService.getAllRevisions(note);
return Promise.all( return await Promise.all(
revisions.map((revision) => revisions.map((revision) =>
this.revisionsService.toRevisionMetadataDto(revision), this.revisionsService.toRevisionMetadataDto(revision),
), ),

View file

@ -49,17 +49,17 @@ export class AuthService {
} }
const accessToken = await this.getAuthTokenAndValidate(keyId, secret); const accessToken = await this.getAuthTokenAndValidate(keyId, secret);
await this.setLastUsedToken(keyId); await this.setLastUsedToken(keyId);
return this.usersService.getUserByUsername(accessToken.user.userName); return await this.usersService.getUserByUsername(accessToken.user.userName);
} }
async hashPassword(cleartext: string): Promise<string> { async hashPassword(cleartext: string): Promise<string> {
// hash the password with bcrypt and 2^12 iterations // hash the password with bcrypt and 2^12 iterations
// this was decided on the basis of https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#bcrypt // this was decided on the basis of https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#bcrypt
return hash(cleartext, 12); return await hash(cleartext, 12);
} }
async checkPassword(cleartext: string, password: string): Promise<boolean> { async checkPassword(cleartext: string, password: string): Promise<boolean> {
return compare(cleartext, password); return await compare(cleartext, password);
} }
async randomString(length: number): Promise<Buffer> { async randomString(length: number): Promise<Buffer> {
@ -209,13 +209,13 @@ export class AuthService {
// Delete all non valid tokens every sunday on 3:00 AM // Delete all non valid tokens every sunday on 3:00 AM
@Cron('0 0 3 * * 0') @Cron('0 0 3 * * 0')
async handleCron() { async handleCron() {
return this.removeInvalidTokens(); return await this.removeInvalidTokens();
} }
// Delete all non valid tokens 5 sec after startup // Delete all non valid tokens 5 sec after startup
@Timeout(5000) @Timeout(5000)
async handleTimeout() { async handleTimeout() {
return this.removeInvalidTokens(); return await this.removeInvalidTokens();
} }
async removeInvalidTokens() { async removeInvalidTokens() {

View file

@ -79,7 +79,7 @@ export class HistoryService {
); );
} }
entry.pinStatus = updateDto.pinStatus; entry.pinStatus = updateDto.pinStatus;
return this.historyEntryRepository.save(entry); return await this.historyEntryRepository.save(entry);
} }
async deleteHistoryEntry(noteIdOrAlias: string, user: User): Promise<void> { async deleteHistoryEntry(noteIdOrAlias: string, user: User): Promise<void> {

View file

@ -46,7 +46,7 @@ export class FilesystemBackend implements MediaBackend {
async deleteFile(fileName: string, _: BackendData): Promise<void> { async deleteFile(fileName: string, _: BackendData): Promise<void> {
const filePath = this.getFilePath(fileName); const filePath = this.getFilePath(fileName);
try { try {
return fs.unlink(filePath); return await fs.unlink(filePath);
} catch (e) { } catch (e) {
this.logger.error(e.message, e.stack, 'deleteFile'); this.logger.error(e.message, e.stack, 'deleteFile');
throw new MediaBackendError(`Could not delete '${filePath}'`); throw new MediaBackendError(`Could not delete '${filePath}'`);

View file

@ -202,7 +202,7 @@ export class NotesService {
//TODO: Calculate patch //TODO: Calculate patch
revisions.push(Revision.create(noteContent, noteContent)); revisions.push(Revision.create(noteContent, noteContent));
note.revisions = Promise.resolve(revisions); note.revisions = Promise.resolve(revisions);
return this.noteRepository.save(note); return await this.noteRepository.save(note);
} }
/** /**