diff --git a/backend/src/auth/auth-token.dto.ts b/backend/src/auth/auth-token.dto.ts index 07859dd9a..d86d31ad6 100644 --- a/backend/src/auth/auth-token.dto.ts +++ b/backend/src/auth/auth-token.dto.ts @@ -40,5 +40,6 @@ export class AuthTokenCreateDto extends BaseDto { label: string; @IsNumber() + @Type(() => Number) validUntil: TimestampMillis; } diff --git a/backend/src/auth/auth.module.ts b/backend/src/auth/auth.module.ts index d47d6a812..874805b5a 100644 --- a/backend/src/auth/auth.module.ts +++ b/backend/src/auth/auth.module.ts @@ -11,7 +11,8 @@ import { LoggerModule } from '../logger/logger.module'; import { UsersModule } from '../users/users.module'; import { AuthToken } from './auth-token.entity'; import { AuthService } from './auth.service'; -import { TokenStrategy } from './token.strategy'; +import { MockAuthGuard } from './mock-auth.guard'; +import { TokenAuthGuard, TokenStrategy } from './token.strategy'; @Module({ imports: [ @@ -20,7 +21,7 @@ import { TokenStrategy } from './token.strategy'; LoggerModule, TypeOrmModule.forFeature([AuthToken]), ], - providers: [AuthService, TokenStrategy], + providers: [AuthService, TokenStrategy, MockAuthGuard, TokenAuthGuard], exports: [AuthService], }) export class AuthModule {} diff --git a/backend/src/frontend-config/frontend-config.dto.ts b/backend/src/frontend-config/frontend-config.dto.ts index 223af14f3..3cfe29b5c 100644 --- a/backend/src/frontend-config/frontend-config.dto.ts +++ b/backend/src/frontend-config/frontend-config.dto.ts @@ -3,6 +3,7 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ +import { Type } from 'class-transformer'; import { IsArray, IsBoolean, @@ -50,6 +51,7 @@ export class AuthProviderWithoutCustomNameDto extends BaseDto { * The type of the auth provider. */ @IsString() + @Type(() => String) type: AuthProviderTypeWithoutCustomName; } @@ -58,6 +60,7 @@ export class AuthProviderWithCustomNameDto extends BaseDto { * The type of the auth provider. */ @IsString() + @Type(() => String) type: AuthProviderTypeWithCustomName; /** @@ -94,6 +97,7 @@ export class BrandingDto extends BaseDto { */ @IsUrl() @IsOptional() + @Type(() => URL) logo?: URL; } @@ -104,6 +108,7 @@ export class SpecialUrlsDto extends BaseDto { */ @IsUrl() @IsOptional() + @Type(() => URL) privacy?: URL; /** @@ -112,6 +117,7 @@ export class SpecialUrlsDto extends BaseDto { */ @IsUrl() @IsOptional() + @Type(() => URL) termsOfUse?: URL; /** @@ -120,6 +126,7 @@ export class SpecialUrlsDto extends BaseDto { */ @IsUrl() @IsOptional() + @Type(() => URL) imprint?: URL; } @@ -139,6 +146,7 @@ export class FrontendConfigDto extends BaseDto { /** * Which auth providers are enabled and how are they configured? */ + // eslint-disable-next-line @darraghor/nestjs-typed/validated-non-primitive-property-needs-type-decorator @IsArray() @ValidateNested({ each: true }) authProviders: AuthProviderDto[]; @@ -147,6 +155,7 @@ export class FrontendConfigDto extends BaseDto { * Individual branding information */ @ValidateNested() + @Type(() => BrandingDto) branding: BrandingDto; /** @@ -159,12 +168,14 @@ export class FrontendConfigDto extends BaseDto { * Links to some special pages */ @ValidateNested() + @Type(() => SpecialUrlsDto) specialUrls: SpecialUrlsDto; /** * The version of HedgeDoc */ @ValidateNested() + @Type(() => ServerVersion) version: ServerVersion; /** @@ -172,6 +183,7 @@ export class FrontendConfigDto extends BaseDto { */ @IsUrl() @IsOptional() + @Type(() => URL) plantUmlServer?: URL; /** diff --git a/backend/src/history/history-entry.dto.ts b/backend/src/history/history-entry.dto.ts index 9f75ba9f5..eaf2e1b5a 100644 --- a/backend/src/history/history-entry.dto.ts +++ b/backend/src/history/history-entry.dto.ts @@ -37,7 +37,7 @@ export class HistoryEntryDto extends BaseDto { @IsArray() @IsString({ each: true }) - @ApiProperty() + @ApiProperty({ isArray: true, type: String }) tags: string[]; /** diff --git a/backend/src/identity/identity.module.ts b/backend/src/identity/identity.module.ts index dfbf9bb68..57794f4ce 100644 --- a/backend/src/identity/identity.module.ts +++ b/backend/src/identity/identity.module.ts @@ -12,8 +12,8 @@ import { User } from '../users/user.entity'; import { UsersModule } from '../users/users.module'; import { Identity } from './identity.entity'; import { IdentityService } from './identity.service'; -import { LdapStrategy } from './ldap/ldap.strategy'; -import { LocalStrategy } from './local/local.strategy'; +import { LdapAuthGuard, LdapStrategy } from './ldap/ldap.strategy'; +import { LocalAuthGuard, LocalStrategy } from './local/local.strategy'; @Module({ imports: [ @@ -23,7 +23,13 @@ import { LocalStrategy } from './local/local.strategy'; LoggerModule, ], controllers: [], - providers: [IdentityService, LocalStrategy, LdapStrategy], + providers: [ + IdentityService, + LocalStrategy, + LdapStrategy, + LdapAuthGuard, + LocalAuthGuard, + ], exports: [IdentityService, LocalStrategy, LdapStrategy], }) export class IdentityModule {} diff --git a/backend/src/identity/local/login.dto.ts b/backend/src/identity/local/login.dto.ts index 2e4d91a88..7ec9af2a7 100644 --- a/backend/src/identity/local/login.dto.ts +++ b/backend/src/identity/local/login.dto.ts @@ -3,11 +3,13 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ +import { Type } from 'class-transformer'; import { IsLowercase, IsString } from 'class-validator'; import { Username } from '../../utils/username'; export class LoginDto { + @Type(() => String) @IsString() @IsLowercase() username: Username; diff --git a/backend/src/identity/local/register.dto.ts b/backend/src/identity/local/register.dto.ts index 54bc61cf9..7a375b8c0 100644 --- a/backend/src/identity/local/register.dto.ts +++ b/backend/src/identity/local/register.dto.ts @@ -3,11 +3,13 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ +import { Type } from 'class-transformer'; import { IsLowercase, IsString } from 'class-validator'; import { Username } from '../../utils/username'; export class RegisterDto { + @Type(() => String) @IsString() @IsLowercase() username: Username; diff --git a/backend/src/media/media-upload.dto.ts b/backend/src/media/media-upload.dto.ts index bb4044920..f625bae19 100644 --- a/backend/src/media/media-upload.dto.ts +++ b/backend/src/media/media-upload.dto.ts @@ -43,6 +43,7 @@ export class MediaUploadDto extends BaseDto { */ @IsString() @IsLowercase() + @IsOptional() @ApiProperty() username: Username | null; } diff --git a/backend/src/monitoring/server-status.dto.ts b/backend/src/monitoring/server-status.dto.ts index a4fd7a3a0..af20ec836 100644 --- a/backend/src/monitoring/server-status.dto.ts +++ b/backend/src/monitoring/server-status.dto.ts @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { BaseDto } from '../utils/base.dto.'; @@ -14,9 +14,9 @@ export class ServerVersion { minor: number; @ApiProperty() patch: number; - @ApiProperty() + @ApiPropertyOptional() preRelease?: string; - @ApiProperty() + @ApiPropertyOptional() commit?: string; @ApiProperty() fullString: string; diff --git a/backend/src/notes/note-metadata.dto.ts b/backend/src/notes/note-metadata.dto.ts index deeef526b..cbb6a5e78 100644 --- a/backend/src/notes/note-metadata.dto.ts +++ b/backend/src/notes/note-metadata.dto.ts @@ -29,9 +29,10 @@ export class NoteMetadataDto extends BaseDto { /** * All aliases of the note (including the primaryAlias) */ + @Type(() => AliasDto) @IsArray() - @ValidateNested() - @ApiProperty() + @ValidateNested({ each: true }) + @ApiProperty({ isArray: true, type: AliasDto }) aliases: AliasDto[]; /** @@ -67,7 +68,7 @@ export class NoteMetadataDto extends BaseDto { */ @IsArray() @IsString({ each: true }) - @ApiProperty() + @ApiProperty({ isArray: true, type: String }) tags: string[]; @IsNumber() @@ -86,8 +87,9 @@ export class NoteMetadataDto extends BaseDto { /** * User that last edited the note */ - @IsString() + // eslint-disable-next-line @darraghor/nestjs-typed/api-property-matches-property-optionality @ApiPropertyOptional() + @IsString() @IsOptional() updateUsername: string | null; @@ -114,13 +116,13 @@ export class NoteMetadataDto extends BaseDto { */ @IsArray() @IsString({ each: true }) - @ApiProperty() + @ApiProperty({ isArray: true, type: String }) editedBy: string[]; /** * Permissions currently in effect for the note */ - @ValidateNested({ each: true }) + @ValidateNested() @Type(() => NotePermissionsDto) @ApiProperty({ type: NotePermissionsDto }) permissions: NotePermissionsDto; @@ -151,6 +153,6 @@ export class NoteMetadataUpdateDto { */ @IsArray() @IsString({ each: true }) - @ApiProperty() + @ApiProperty({ isArray: true, type: String }) tags: string[]; } diff --git a/backend/src/notes/note-permissions.dto.ts b/backend/src/notes/note-permissions.dto.ts index 30372010e..b462d79df 100644 --- a/backend/src/notes/note-permissions.dto.ts +++ b/backend/src/notes/note-permissions.dto.ts @@ -21,6 +21,7 @@ export class NoteUserPermissionEntryDto extends BaseDto { /** * Username of the User this permission applies to */ + @Type(() => String) @IsString() @IsLowercase() @ApiProperty() @@ -40,6 +41,7 @@ export class NoteUserPermissionUpdateDto { * Username of the user this permission should apply to * @example "john.smith" */ + @Type(() => String) @IsString() @IsLowercase() @ApiProperty() @@ -93,6 +95,9 @@ export class NotePermissionsDto { /** * Username of the User this permission applies to */ + // nestjs-typed does not detect '| null' types as optional + // eslint-disable-next-line @darraghor/nestjs-typed/api-property-matches-property-optionality + @Type(() => String) @IsString() @ApiPropertyOptional() @IsOptional() diff --git a/backend/src/notes/note.dto.ts b/backend/src/notes/note.dto.ts index ddba4d72e..deff740f4 100644 --- a/backend/src/notes/note.dto.ts +++ b/backend/src/notes/note.dto.ts @@ -23,6 +23,7 @@ export class NoteDto extends BaseDto { /** * Metadata of the note */ + @Type(() => NoteMetadataDto) @ValidateNested() @ApiProperty({ type: NoteMetadataDto }) metadata: NoteMetadataDto; diff --git a/backend/src/revisions/edit.dto.ts b/backend/src/revisions/edit.dto.ts index 156254a8c..fcc6facdf 100644 --- a/backend/src/revisions/edit.dto.ts +++ b/backend/src/revisions/edit.dto.ts @@ -16,6 +16,8 @@ export class EditDto extends BaseDto { * Is `null` if the user is anonymous * @example "john.smith" */ + // nestjs-typed does not detect '| null' types as optional + // eslint-disable-next-line @darraghor/nestjs-typed/api-property-matches-property-optionality @IsString() @IsOptional() @ApiPropertyOptional() diff --git a/backend/src/revisions/revision-metadata.dto.ts b/backend/src/revisions/revision-metadata.dto.ts index 19b5a0f2f..347edf470 100644 --- a/backend/src/revisions/revision-metadata.dto.ts +++ b/backend/src/revisions/revision-metadata.dto.ts @@ -15,6 +15,7 @@ export class RevisionMetadataDto extends BaseDto { * ID of this revision * @example 13 */ + @Type(() => Number) @IsNumber() @ApiProperty() id: Revision['id']; @@ -41,7 +42,7 @@ export class RevisionMetadataDto extends BaseDto { * Does not include anonymous users */ @IsString() - @ApiProperty() + @ApiProperty({ isArray: true, type: String }) authorUsernames: string[]; /** @@ -75,6 +76,6 @@ export class RevisionMetadataDto extends BaseDto { */ @IsArray() @IsString({ each: true }) - @ApiProperty() + @ApiProperty({ isArray: true, type: String }) tags: string[]; } diff --git a/backend/src/revisions/revision.dto.ts b/backend/src/revisions/revision.dto.ts index 1744230dd..53269b8be 100644 --- a/backend/src/revisions/revision.dto.ts +++ b/backend/src/revisions/revision.dto.ts @@ -4,6 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { ApiProperty } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; import { IsString, ValidateNested } from 'class-validator'; import { EditDto } from './edit.dto'; @@ -28,7 +29,8 @@ export class RevisionDto extends RevisionMetadataDto { /** * All edit objects which are used in the revision. */ - @ValidateNested() - @ApiProperty() + @Type(() => EditDto) + @ValidateNested({ each: true }) + @ApiProperty({ isArray: true, type: EditDto }) edits: EditDto[]; } diff --git a/backend/src/users/user-info.dto.ts b/backend/src/users/user-info.dto.ts index d26937da8..af4b057bc 100644 --- a/backend/src/users/user-info.dto.ts +++ b/backend/src/users/user-info.dto.ts @@ -4,6 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { ApiProperty } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; import { IsLowercase, IsString } from 'class-validator'; import { BaseDto } from '../utils/base.dto.'; @@ -14,6 +15,7 @@ export class UserInfoDto extends BaseDto { * The username * @example "john.smith" */ + @Type(() => String) @IsString() @IsLowercase() @ApiProperty()