diff --git a/src/api/private/me/history/history.controller.spec.ts b/src/api/private/me/history/history.controller.spec.ts index 5b5a01424..f650c3df7 100644 --- a/src/api/private/me/history/history.controller.spec.ts +++ b/src/api/private/me/history/history.controller.spec.ts @@ -21,7 +21,7 @@ import { User } from '../../../../users/user.entity'; import { Note } from '../../../../notes/note.entity'; import { AuthToken } from '../../../../auth/auth-token.entity'; import { Identity } from '../../../../users/identity.entity'; -import { Authorship } from '../../../../revisions/authorship.entity'; +import { Edit } from '../../../../revisions/edit.entity'; import { Revision } from '../../../../revisions/revision.entity'; import { Tag } from '../../../../notes/tag.entity'; import { HistoryEntry } from '../../../../history/history-entry.entity'; @@ -59,7 +59,7 @@ describe('HistoryController', () => { .useValue({}) .overrideProvider(getRepositoryToken(Identity)) .useValue({}) - .overrideProvider(getRepositoryToken(Authorship)) + .overrideProvider(getRepositoryToken(Edit)) .useValue({}) .overrideProvider(getRepositoryToken(Revision)) .useValue({}) diff --git a/src/api/private/me/me.controller.spec.ts b/src/api/private/me/me.controller.spec.ts index 8e3151b74..06e091480 100644 --- a/src/api/private/me/me.controller.spec.ts +++ b/src/api/private/me/me.controller.spec.ts @@ -16,7 +16,7 @@ import { Identity } from '../../../users/identity.entity'; import { MediaModule } from '../../../media/media.module'; import { NoteGroupPermission } from '../../../permissions/note-group-permission.entity'; import { NoteUserPermission } from '../../../permissions/note-user-permission.entity'; -import { Authorship } from '../../../revisions/authorship.entity'; +import { Edit } from '../../../revisions/edit.entity'; import { ConfigModule } from '@nestjs/config'; import appConfigMock from '../../../config/mock/app.config.mock'; import authConfigMock from '../../../config/mock/auth.config.mock'; @@ -67,7 +67,7 @@ describe('MeController', () => { .useValue({}) .overrideProvider(getRepositoryToken(NoteUserPermission)) .useValue({}) - .overrideProvider(getRepositoryToken(Authorship)) + .overrideProvider(getRepositoryToken(Edit)) .useValue({}) .overrideProvider(getRepositoryToken(MediaUpload)) .useValue({}) diff --git a/src/api/private/media/media.controller.spec.ts b/src/api/private/media/media.controller.spec.ts index b294091cb..c5d03a52e 100644 --- a/src/api/private/media/media.controller.spec.ts +++ b/src/api/private/media/media.controller.spec.ts @@ -19,7 +19,7 @@ import externalConfigMock from '../../../config/mock/external-services.config.mo import { MediaModule } from '../../../media/media.module'; import { NotesModule } from '../../../notes/notes.module'; import { getRepositoryToken } from '@nestjs/typeorm'; -import { Authorship } from '../../../revisions/authorship.entity'; +import { Edit } from '../../../revisions/edit.entity'; import { AuthToken } from '../../../auth/auth-token.entity'; import { Identity } from '../../../users/identity.entity'; import { MediaUpload } from '../../../media/media-upload.entity'; @@ -54,7 +54,7 @@ describe('MediaController', () => { ], controllers: [MediaController], }) - .overrideProvider(getRepositoryToken(Authorship)) + .overrideProvider(getRepositoryToken(Edit)) .useValue({}) .overrideProvider(getRepositoryToken(AuthToken)) .useValue({}) diff --git a/src/api/private/notes/notes.controller.spec.ts b/src/api/private/notes/notes.controller.spec.ts index 393f3f592..ff2231a8f 100644 --- a/src/api/private/notes/notes.controller.spec.ts +++ b/src/api/private/notes/notes.controller.spec.ts @@ -27,7 +27,7 @@ import { ConfigModule } from '@nestjs/config'; import appConfigMock from '../../../config/mock/app.config.mock'; import mediaConfigMock from '../../../config/mock/media.config.mock'; import { Revision } from '../../../revisions/revision.entity'; -import { Authorship } from '../../../revisions/authorship.entity'; +import { Edit } from '../../../revisions/edit.entity'; import { User } from '../../../users/user.entity'; import { AuthToken } from '../../../auth/auth-token.entity'; import { Identity } from '../../../users/identity.entity'; @@ -77,7 +77,7 @@ describe('NotesController', () => { .useValue({}) .overrideProvider(getRepositoryToken(Revision)) .useValue({}) - .overrideProvider(getRepositoryToken(Authorship)) + .overrideProvider(getRepositoryToken(Edit)) .useValue({}) .overrideProvider(getRepositoryToken(User)) .useValue({}) diff --git a/src/api/public/me/me.controller.spec.ts b/src/api/public/me/me.controller.spec.ts index fa8293d5a..0e4a737be 100644 --- a/src/api/public/me/me.controller.spec.ts +++ b/src/api/public/me/me.controller.spec.ts @@ -16,7 +16,7 @@ import { LoggerModule } from '../../../logger/logger.module'; import { Note } from '../../../notes/note.entity'; import { NotesModule } from '../../../notes/notes.module'; import { Tag } from '../../../notes/tag.entity'; -import { Authorship } from '../../../revisions/authorship.entity'; +import { Edit } from '../../../revisions/edit.entity'; import { Revision } from '../../../revisions/revision.entity'; import { AuthToken } from '../../../auth/auth-token.entity'; import { Identity } from '../../../users/identity.entity'; @@ -63,7 +63,7 @@ describe('Me Controller', () => { .useValue({}) .overrideProvider(getRepositoryToken(Identity)) .useValue({}) - .overrideProvider(getRepositoryToken(Authorship)) + .overrideProvider(getRepositoryToken(Edit)) .useValue({}) .overrideProvider(getRepositoryToken(Revision)) .useValue({}) diff --git a/src/api/public/media/media.controller.spec.ts b/src/api/public/media/media.controller.spec.ts index 30c75a5c5..1c7f83946 100644 --- a/src/api/public/media/media.controller.spec.ts +++ b/src/api/public/media/media.controller.spec.ts @@ -16,7 +16,7 @@ import { MediaModule } from '../../../media/media.module'; import { Note } from '../../../notes/note.entity'; import { NotesModule } from '../../../notes/notes.module'; import { Tag } from '../../../notes/tag.entity'; -import { Authorship } from '../../../revisions/authorship.entity'; +import { Edit } from '../../../revisions/edit.entity'; import { Revision } from '../../../revisions/revision.entity'; import { AuthToken } from '../../../auth/auth-token.entity'; import { Identity } from '../../../users/identity.entity'; @@ -43,7 +43,7 @@ describe('Media Controller', () => { NotesModule, ], }) - .overrideProvider(getRepositoryToken(Authorship)) + .overrideProvider(getRepositoryToken(Edit)) .useValue({}) .overrideProvider(getRepositoryToken(AuthToken)) .useValue({}) diff --git a/src/api/public/notes/notes.controller.spec.ts b/src/api/public/notes/notes.controller.spec.ts index 633fc616c..f32c0b16a 100644 --- a/src/api/public/notes/notes.controller.spec.ts +++ b/src/api/public/notes/notes.controller.spec.ts @@ -15,7 +15,7 @@ import { LoggerModule } from '../../../logger/logger.module'; import { Note } from '../../../notes/note.entity'; import { NotesService } from '../../../notes/notes.service'; import { Tag } from '../../../notes/tag.entity'; -import { Authorship } from '../../../revisions/authorship.entity'; +import { Edit } from '../../../revisions/edit.entity'; import { Revision } from '../../../revisions/revision.entity'; import { RevisionsModule } from '../../../revisions/revisions.module'; import { AuthToken } from '../../../auth/auth-token.entity'; @@ -79,7 +79,7 @@ describe('Notes Controller', () => { .useValue({}) .overrideProvider(getRepositoryToken(Revision)) .useValue({}) - .overrideProvider(getRepositoryToken(Authorship)) + .overrideProvider(getRepositoryToken(Edit)) .useValue({}) .overrideProvider(getRepositoryToken(User)) .useValue({}) diff --git a/src/authors/author.entity.ts b/src/authors/author.entity.ts index 51732c6e8..fc8eaea0a 100644 --- a/src/authors/author.entity.ts +++ b/src/authors/author.entity.ts @@ -11,7 +11,7 @@ import { OneToMany, PrimaryGeneratedColumn, } from 'typeorm'; -import { Authorship } from '../revisions/authorship.entity'; +import { Edit } from '../revisions/edit.entity'; import { Session } from '../users/session.entity'; import { User } from '../users/user.entity'; @@ -20,7 +20,7 @@ export type AuthorColor = number; /** * The author represents a single user editing a note. * A 'user' can either be a registered and logged-in user or a browser session identified by its cookie. - * All edits (aka authorships) of one user in a note must belong to the same author, so that the same color can be displayed. + * All edits of one user in a note must belong to the same author, so that the same color can be displayed. */ @Entity() export class Author { @@ -49,23 +49,23 @@ export class Author { user: User | null; /** - * List of authorships that this author created - * All authorships must belong to the same note + * List of edits that this author created + * All edits must belong to the same note */ - @OneToMany(() => Authorship, (authorship) => authorship.author) - authorships: Authorship[]; + @OneToMany(() => Edit, (edit) => edit.author) + edits: Edit[]; // eslint-disable-next-line @typescript-eslint/no-empty-function private constructor() {} public static create( color: number, - ): Pick { + ): Pick { const newAuthor = new Author(); newAuthor.color = color; newAuthor.sessions = []; newAuthor.user = null; - newAuthor.authorships = []; + newAuthor.edits = []; return newAuthor; } } diff --git a/src/history/history.service.spec.ts b/src/history/history.service.spec.ts index 476991b19..d8ac1177e 100644 --- a/src/history/history.service.spec.ts +++ b/src/history/history.service.spec.ts @@ -14,7 +14,7 @@ import { NotesModule } from '../notes/notes.module'; import { getConnectionToken, getRepositoryToken } from '@nestjs/typeorm'; import { Identity } from '../users/identity.entity'; import { User } from '../users/user.entity'; -import { Authorship } from '../revisions/authorship.entity'; +import { Edit } from '../revisions/edit.entity'; import { HistoryEntry } from './history-entry.entity'; import { Note } from '../notes/note.entity'; import { Tag } from '../notes/tag.entity'; @@ -74,7 +74,7 @@ describe('HistoryService', () => { .useValue({}) .overrideProvider(getRepositoryToken(Identity)) .useValue({}) - .overrideProvider(getRepositoryToken(Authorship)) + .overrideProvider(getRepositoryToken(Edit)) .useValue({}) .overrideProvider(getRepositoryToken(Revision)) .useValue({}) diff --git a/src/media/media.service.spec.ts b/src/media/media.service.spec.ts index 32ddb4507..2b08e225d 100644 --- a/src/media/media.service.spec.ts +++ b/src/media/media.service.spec.ts @@ -13,7 +13,7 @@ import { LoggerModule } from '../logger/logger.module'; import { Note } from '../notes/note.entity'; import { NotesModule } from '../notes/notes.module'; import { Tag } from '../notes/tag.entity'; -import { Authorship } from '../revisions/authorship.entity'; +import { Edit } from '../revisions/edit.entity'; import { Revision } from '../revisions/revision.entity'; import { AuthToken } from '../auth/auth-token.entity'; import { Identity } from '../users/identity.entity'; @@ -57,7 +57,7 @@ describe('MediaService', () => { UsersModule, ], }) - .overrideProvider(getRepositoryToken(Authorship)) + .overrideProvider(getRepositoryToken(Edit)) .useValue({}) .overrideProvider(getRepositoryToken(AuthToken)) .useValue({}) diff --git a/src/notes/note.dto.ts b/src/notes/note.dto.ts index a41b2b9c3..10dcf4e88 100644 --- a/src/notes/note.dto.ts +++ b/src/notes/note.dto.ts @@ -5,7 +5,7 @@ */ import { IsArray, IsString, ValidateNested } from 'class-validator'; -import { NoteAuthorshipDto } from './note-authorship.dto'; +import { EditDto } from '../revisions/edit.dto'; import { NoteMetadataDto } from './note-metadata.dto'; import { ApiProperty } from '@nestjs/swagger'; @@ -26,10 +26,10 @@ export class NoteDto { metadata: NoteMetadataDto; /** - * Authorship information of this note + * Edit information of this note */ @IsArray() @ValidateNested({ each: true }) - @ApiProperty({ isArray: true, type: NoteAuthorshipDto }) - editedByAtPosition: NoteAuthorshipDto[]; + @ApiProperty({ isArray: true, type: EditDto }) + editedByAtPosition: EditDto[]; } diff --git a/src/notes/notes.service.spec.ts b/src/notes/notes.service.spec.ts index 667522593..209753ad8 100644 --- a/src/notes/notes.service.spec.ts +++ b/src/notes/notes.service.spec.ts @@ -8,7 +8,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { getRepositoryToken } from '@nestjs/typeorm'; import { Author } from '../authors/author.entity'; import { LoggerModule } from '../logger/logger.module'; -import { Authorship } from '../revisions/authorship.entity'; +import { Edit } from '../revisions/edit.entity'; import { Revision } from '../revisions/revision.entity'; import { RevisionsModule } from '../revisions/revisions.module'; import { AuthToken } from '../auth/auth-token.entity'; @@ -89,7 +89,7 @@ describe('NotesService', () => { .useValue({}) .overrideProvider(getRepositoryToken(Identity)) .useValue({}) - .overrideProvider(getRepositoryToken(Authorship)) + .overrideProvider(getRepositoryToken(Edit)) .useValue({}) .overrideProvider(getRepositoryToken(Revision)) .useClass(Repository) @@ -680,21 +680,21 @@ describe('NotesService', () => { .mockImplementation(async (note: Note): Promise => note); const note = await service.createNote(content); const revisions = await note.revisions; - revisions[0].authorships = [ + revisions[0].edits = [ { revisions: revisions, startPos: 0, endPos: 1, updatedAt: new Date(1549312452000), author: author, - } as Authorship, + } as Edit, { revisions: revisions, startPos: 0, endPos: 1, updatedAt: new Date(1549312452001), author: author, - } as Authorship, + } as Edit, ]; revisions[0].createdAt = new Date(1549312452000); jest.spyOn(revisionRepo, 'findOne').mockResolvedValue(revisions[0]); @@ -776,21 +776,21 @@ describe('NotesService', () => { .mockImplementation(async (note: Note): Promise => note); const note = await service.createNote(content); const revisions = await note.revisions; - revisions[0].authorships = [ + revisions[0].edits = [ { revisions: revisions, startPos: 0, endPos: 1, updatedAt: new Date(1549312452000), author: author, - } as Authorship, + } as Edit, { revisions: revisions, startPos: 0, endPos: 1, updatedAt: new Date(1549312452001), author: author, - } as Authorship, + } as Edit, ]; revisions[0].createdAt = new Date(1549312452000); jest diff --git a/src/notes/notes.service.ts b/src/notes/notes.service.ts index 048bb4fc5..fbf390cc5 100644 --- a/src/notes/notes.service.ts +++ b/src/notes/notes.service.ts @@ -198,8 +198,8 @@ export class NotesService { return await this.userRepository .createQueryBuilder('user') .innerJoin('user.authors', 'author') - .innerJoin('author.authorships', 'authorship') - .innerJoin('authorship.revisions', 'revision') + .innerJoin('author.edits', 'edit') + .innerJoin('edit.revisions', 'revision') .innerJoin('revision.note', 'note') .where('note.id = :id', { id: note.id }) .getMany(); @@ -322,14 +322,14 @@ export class NotesService { */ async calculateUpdateUser(note: Note): Promise { const lastRevision = await this.getLatestRevision(note); - if (lastRevision && lastRevision.authorships) { - // Sort the last Revisions Authorships by their updatedAt Date to get the latest one - // the user of that Authorship is the updateUser - return lastRevision.authorships.sort( + if (lastRevision && lastRevision.edits) { + // Sort the last Revisions Edits by their updatedAt Date to get the latest one + // the user of that Edit is the updateUser + return lastRevision.edits.sort( (a, b) => b.updatedAt.getTime() - a.updatedAt.getTime(), )[0].author.user; } - // If there are no Authorships, the owner is the updateUser + // If there are no Edits, the owner is the updateUser return note.owner; } diff --git a/src/permissions/permissions.service.spec.ts b/src/permissions/permissions.service.spec.ts index 234c18690..e8ebcecd4 100644 --- a/src/permissions/permissions.service.spec.ts +++ b/src/permissions/permissions.service.spec.ts @@ -13,7 +13,7 @@ import { LoggerModule } from '../logger/logger.module'; import { Note } from '../notes/note.entity'; import { NotesModule } from '../notes/notes.module'; import { Tag } from '../notes/tag.entity'; -import { Authorship } from '../revisions/authorship.entity'; +import { Edit } from '../revisions/edit.entity'; import { Revision } from '../revisions/revision.entity'; import { Identity } from '../users/identity.entity'; import { Session } from '../users/session.entity'; @@ -49,7 +49,7 @@ describe('PermissionsService', () => { .useValue({}) .overrideProvider(getRepositoryToken(Identity)) .useValue({}) - .overrideProvider(getRepositoryToken(Authorship)) + .overrideProvider(getRepositoryToken(Edit)) .useValue({}) .overrideProvider(getRepositoryToken(Revision)) .useValue({}) diff --git a/src/notes/note-authorship.dto.ts b/src/revisions/edit.dto.ts similarity index 75% rename from src/notes/note-authorship.dto.ts rename to src/revisions/edit.dto.ts index 16acac592..138750ff2 100644 --- a/src/notes/note-authorship.dto.ts +++ b/src/revisions/edit.dto.ts @@ -4,18 +4,20 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { IsDate, IsNumber, IsString, Min } from 'class-validator'; +import { IsDate, IsNumber, IsOptional, IsString, Min } from 'class-validator'; import { UserInfoDto } from '../users/user-info.dto'; -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -export class NoteAuthorshipDto { +export class EditDto { /** * Username of the user who authored this section + * Is `null` if the user is anonymous * @example "john.smith" */ @IsString() - @ApiProperty() - userName: UserInfoDto['userName']; + @IsOptional() + @ApiPropertyOptional() + userName: UserInfoDto['userName'] | null; /** * Character index of the start of this section diff --git a/src/revisions/authorship.entity.ts b/src/revisions/edit.entity.ts similarity index 64% rename from src/revisions/authorship.entity.ts rename to src/revisions/edit.entity.ts index b2b50e28f..b6c0c0710 100644 --- a/src/revisions/authorship.entity.ts +++ b/src/revisions/edit.entity.ts @@ -17,23 +17,23 @@ import { Author } from '../authors/author.entity'; import { Revision } from './revision.entity'; /** - * The Authorship represents a change in the content of a note by a particular {@link Author} + * The Edit represents a change in the content of a note by a particular {@link Author} */ @Entity() -export class Authorship { +export class Edit { @PrimaryGeneratedColumn('uuid') id: string; /** - * Revisions this authorship appears in + * Revisions this edit appears in */ - @ManyToMany((_) => Revision, (revision) => revision.authorships) + @ManyToMany((_) => Revision, (revision) => revision.edits) revisions: Revision[]; /** * Author that created the change */ - @ManyToOne(() => Author, (author) => author.authorships) + @ManyToOne(() => Author, (author) => author.edits) author: Author; @Column() @@ -52,10 +52,10 @@ export class Authorship { private constructor() {} public static create(author: Author, startPos: number, endPos: number) { - const newAuthorship = new Authorship(); - newAuthorship.author = author; - newAuthorship.startPos = startPos; - newAuthorship.endPos = endPos; - return newAuthorship; + const newEdit = new Edit(); + newEdit.author = author; + newEdit.startPos = startPos; + newEdit.endPos = endPos; + return newEdit; } } diff --git a/src/revisions/revision.entity.ts b/src/revisions/revision.entity.ts index 967ef26c5..14bf3622c 100644 --- a/src/revisions/revision.entity.ts +++ b/src/revisions/revision.entity.ts @@ -13,7 +13,7 @@ import { } from 'typeorm'; import { JoinTable, ManyToMany } from 'typeorm'; import { Note } from '../notes/note.entity'; -import { Authorship } from './authorship.entity'; +import { Edit } from './edit.entity'; /** * The state of a note at a particular point in time, @@ -59,11 +59,11 @@ export class Revision { @ManyToOne((_) => Note, (note) => note.revisions, { onDelete: 'CASCADE' }) note: Note; /** - * All authorship objects which are used in the revision. + * All edit objects which are used in the revision. */ - @ManyToMany((_) => Authorship, (authorship) => authorship.revisions) + @ManyToMany((_) => Edit, (edit) => edit.revisions) @JoinTable() - authorships: Authorship[]; + edits: Edit[]; // eslint-disable-next-line @typescript-eslint/no-empty-function private constructor() {} diff --git a/src/revisions/revisions.module.ts b/src/revisions/revisions.module.ts index 0d17971d9..ff0accabb 100644 --- a/src/revisions/revisions.module.ts +++ b/src/revisions/revisions.module.ts @@ -9,14 +9,14 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { AuthorsModule } from '../authors/authors.module'; import { LoggerModule } from '../logger/logger.module'; import { NotesModule } from '../notes/notes.module'; -import { Authorship } from './authorship.entity'; +import { Edit } from './edit.entity'; import { Revision } from './revision.entity'; import { RevisionsService } from './revisions.service'; import { ConfigModule } from '@nestjs/config'; @Module({ imports: [ - TypeOrmModule.forFeature([Revision, Authorship]), + TypeOrmModule.forFeature([Revision, Edit]), forwardRef(() => NotesModule), LoggerModule, ConfigModule, diff --git a/src/revisions/revisions.service.spec.ts b/src/revisions/revisions.service.spec.ts index a56e3ae6d..660d60e7e 100644 --- a/src/revisions/revisions.service.spec.ts +++ b/src/revisions/revisions.service.spec.ts @@ -17,7 +17,7 @@ import { AuthToken } from '../auth/auth-token.entity'; import { Identity } from '../users/identity.entity'; import { Session } from '../users/session.entity'; import { User } from '../users/user.entity'; -import { Authorship } from './authorship.entity'; +import { Edit } from './edit.entity'; import { Revision } from './revision.entity'; import { RevisionsService } from './revisions.service'; import { Tag } from '../notes/tag.entity'; @@ -49,7 +49,7 @@ describe('RevisionsService', () => { }), ], }) - .overrideProvider(getRepositoryToken(Authorship)) + .overrideProvider(getRepositoryToken(Edit)) .useValue({}) .overrideProvider(getRepositoryToken(User)) .useValue({}) diff --git a/src/seed.ts b/src/seed.ts index 6a76de437..97cc94c52 100644 --- a/src/seed.ts +++ b/src/seed.ts @@ -10,7 +10,7 @@ import { Session } from './users/session.entity'; import { User } from './users/user.entity'; import { Note } from './notes/note.entity'; import { Revision } from './revisions/revision.entity'; -import { Authorship } from './revisions/authorship.entity'; +import { Edit } from './revisions/edit.entity'; import { NoteGroupPermission } from './permissions/note-group-permission.entity'; import { NoteUserPermission } from './permissions/note-user-permission.entity'; import { Group } from './groups/group.entity'; @@ -30,7 +30,7 @@ createConnection({ User, Note, Revision, - Authorship, + Edit, NoteGroupPermission, NoteUserPermission, Group, @@ -64,19 +64,13 @@ createConnection({ 'This is a test note', 'This is a test note', ); - const authorship = Authorship.create(author, 1, 42); - revision.authorships = [authorship]; + const edit = Edit.create(author, 1, 42); + revision.edits = [edit]; notes[i].revisions = Promise.all([revision]); notes[i].userPermissions = []; notes[i].groupPermissions = []; user.ownedNotes = [notes[i]]; - await connection.manager.save([ - notes[i], - user, - revision, - authorship, - author, - ]); + await connection.manager.save([notes[i], user, revision, edit, author]); } const foundUser = await connection.manager.findOne(User); if (!foundUser) {