mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-25 11:16:31 -05:00
Add relation between User and Group
This represents the users which are members of this group Signed-off-by: Yannick Bungers <git@innay.de>
This commit is contained in:
parent
8a33f75cf9
commit
68cbb5a9c2
12 changed files with 103 additions and 16 deletions
|
@ -119,6 +119,11 @@ entity "note_group_permission" {
|
||||||
*canEdit : boolean
|
*canEdit : boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entity "group_members_user" {
|
||||||
|
*group : number <<FK group>>
|
||||||
|
*member : uuid <<FK user>>
|
||||||
|
}
|
||||||
|
|
||||||
entity "tag" {
|
entity "tag" {
|
||||||
*id: number <<generated>>
|
*id: number <<generated>>
|
||||||
*name: text
|
*name: text
|
||||||
|
@ -144,16 +149,16 @@ entity "history_entry" {
|
||||||
|
|
||||||
user "1" -- "0..*" note: owner
|
user "1" -- "0..*" note: owner
|
||||||
user "1" -u- "1..*" identity
|
user "1" -u- "1..*" identity
|
||||||
user "1" - "1..*" auth_token: authTokens
|
user "1" -l- "1..*" auth_token: authTokens
|
||||||
user "1" -l- "1..*" session
|
user "1" -r- "1..*" session
|
||||||
user "1" - "0..*" media_upload
|
user "1" -- "0..*" media_upload
|
||||||
user "1" - "0..*" history_entry
|
user "1" - "0..*" history_entry
|
||||||
user "0..*" -- "0..*" note
|
user "0..*" -- "0..*" note
|
||||||
user "1" - "0..*" authorship
|
user "1" -- "0..*" authorship
|
||||||
|
|
||||||
(user, note) . author_colors
|
(user, note) . author_colors
|
||||||
|
|
||||||
revision "0..*" - "0..*" authorship
|
revision "0..*" -- "0..*" authorship
|
||||||
(revision, authorship) .. revision_authorship
|
(revision, authorship) .. revision_authorship
|
||||||
|
|
||||||
media_upload "0..*" -- "1" note
|
media_upload "0..*" -- "1" note
|
||||||
|
@ -161,9 +166,11 @@ note "1" - "1..*" revision
|
||||||
note "1" - "0..*" history_entry
|
note "1" - "0..*" history_entry
|
||||||
note "0..*" -l- "0..*" tag
|
note "0..*" -l- "0..*" tag
|
||||||
note "0..*" -- "0..*" group
|
note "0..*" -- "0..*" group
|
||||||
|
user "1..*" -- "0..*" group
|
||||||
|
|
||||||
user "0..*" -- "0..*" note
|
user "0..*" -- "0..*" note
|
||||||
(user, note) . note_user_permission
|
(user, note) . note_user_permission
|
||||||
(note, group) . note_group_permission
|
(note, group) . note_group_permission
|
||||||
|
(user, group) . group_members_user
|
||||||
|
|
||||||
@enduml
|
@enduml
|
||||||
|
|
|
@ -20,6 +20,8 @@ import { User } from '../../../users/user.entity';
|
||||||
import { UsersModule } from '../../../users/users.module';
|
import { UsersModule } from '../../../users/users.module';
|
||||||
import { MeController } from './me.controller';
|
import { MeController } from './me.controller';
|
||||||
import { HistoryEntry } from '../../../history/history-entry.entity';
|
import { HistoryEntry } from '../../../history/history-entry.entity';
|
||||||
|
import { NoteGroupPermission } from '../../../permissions/note-group-permission.entity';
|
||||||
|
import { NoteUserPermission } from '../../../permissions/note-user-permission.entity';
|
||||||
|
|
||||||
describe('Me Controller', () => {
|
describe('Me Controller', () => {
|
||||||
let controller: MeController;
|
let controller: MeController;
|
||||||
|
@ -47,6 +49,10 @@ describe('Me Controller', () => {
|
||||||
.useValue({})
|
.useValue({})
|
||||||
.overrideProvider(getRepositoryToken(HistoryEntry))
|
.overrideProvider(getRepositoryToken(HistoryEntry))
|
||||||
.useValue({})
|
.useValue({})
|
||||||
|
.overrideProvider(getRepositoryToken(NoteGroupPermission))
|
||||||
|
.useValue({})
|
||||||
|
.overrideProvider(getRepositoryToken(NoteUserPermission))
|
||||||
|
.useValue({})
|
||||||
.compile();
|
.compile();
|
||||||
|
|
||||||
controller = module.get<MeController>(MeController);
|
controller = module.get<MeController>(MeController);
|
||||||
|
|
|
@ -22,6 +22,8 @@ import { AuthToken } from '../../../auth/auth-token.entity';
|
||||||
import { Identity } from '../../../users/identity.entity';
|
import { Identity } from '../../../users/identity.entity';
|
||||||
import { User } from '../../../users/user.entity';
|
import { User } from '../../../users/user.entity';
|
||||||
import { MediaController } from './media.controller';
|
import { MediaController } from './media.controller';
|
||||||
|
import { NoteGroupPermission } from '../../../permissions/note-group-permission.entity';
|
||||||
|
import { NoteUserPermission } from '../../../permissions/note-user-permission.entity';
|
||||||
|
|
||||||
describe('Media Controller', () => {
|
describe('Media Controller', () => {
|
||||||
let controller: MediaController;
|
let controller: MediaController;
|
||||||
|
@ -57,6 +59,10 @@ describe('Media Controller', () => {
|
||||||
.useValue({})
|
.useValue({})
|
||||||
.overrideProvider(getRepositoryToken(Tag))
|
.overrideProvider(getRepositoryToken(Tag))
|
||||||
.useValue({})
|
.useValue({})
|
||||||
|
.overrideProvider(getRepositoryToken(NoteGroupPermission))
|
||||||
|
.useValue({})
|
||||||
|
.overrideProvider(getRepositoryToken(NoteUserPermission))
|
||||||
|
.useValue({})
|
||||||
.compile();
|
.compile();
|
||||||
|
|
||||||
controller = module.get<MediaController>(MediaController);
|
controller = module.get<MediaController>(MediaController);
|
||||||
|
|
|
@ -19,8 +19,11 @@ import { Identity } from '../../../users/identity.entity';
|
||||||
import { User } from '../../../users/user.entity';
|
import { User } from '../../../users/user.entity';
|
||||||
import { UsersModule } from '../../../users/users.module';
|
import { UsersModule } from '../../../users/users.module';
|
||||||
import { NotesController } from './notes.controller';
|
import { NotesController } from './notes.controller';
|
||||||
|
import { PermissionsModule } from '../../../permissions/permissions.module';
|
||||||
import { HistoryModule } from '../../../history/history.module';
|
import { HistoryModule } from '../../../history/history.module';
|
||||||
import { HistoryEntry } from '../../../history/history-entry.entity';
|
import { HistoryEntry } from '../../../history/history-entry.entity';
|
||||||
|
import { NoteGroupPermission } from '../../../permissions/note-group-permission.entity';
|
||||||
|
import { NoteUserPermission } from '../../../permissions/note-user-permission.entity';
|
||||||
|
|
||||||
describe('Notes Controller', () => {
|
describe('Notes Controller', () => {
|
||||||
let controller: NotesController;
|
let controller: NotesController;
|
||||||
|
@ -39,7 +42,13 @@ describe('Notes Controller', () => {
|
||||||
useValue: {},
|
useValue: {},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
imports: [RevisionsModule, UsersModule, LoggerModule, HistoryModule],
|
imports: [
|
||||||
|
RevisionsModule,
|
||||||
|
UsersModule,
|
||||||
|
LoggerModule,
|
||||||
|
PermissionsModule,
|
||||||
|
HistoryModule,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
.overrideProvider(getRepositoryToken(Note))
|
.overrideProvider(getRepositoryToken(Note))
|
||||||
.useValue({})
|
.useValue({})
|
||||||
|
@ -61,6 +70,10 @@ describe('Notes Controller', () => {
|
||||||
.useValue({})
|
.useValue({})
|
||||||
.overrideProvider(getRepositoryToken(HistoryEntry))
|
.overrideProvider(getRepositoryToken(HistoryEntry))
|
||||||
.useValue({})
|
.useValue({})
|
||||||
|
.overrideProvider(getRepositoryToken(NoteGroupPermission))
|
||||||
|
.useValue({})
|
||||||
|
.overrideProvider(getRepositoryToken(NoteUserPermission))
|
||||||
|
.useValue({})
|
||||||
.compile();
|
.compile();
|
||||||
|
|
||||||
controller = module.get<NotesController>(NotesController);
|
controller = module.get<NotesController>(NotesController);
|
||||||
|
|
|
@ -4,7 +4,14 @@
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
|
import {
|
||||||
|
Column,
|
||||||
|
Entity,
|
||||||
|
JoinTable,
|
||||||
|
ManyToMany,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
} from 'typeorm';
|
||||||
|
import { User } from '../users/user.entity';
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class Group {
|
export class Group {
|
||||||
|
@ -26,4 +33,11 @@ export class Group {
|
||||||
*/
|
*/
|
||||||
@Column()
|
@Column()
|
||||||
special: boolean;
|
special: boolean;
|
||||||
|
|
||||||
|
@ManyToMany((_) => User, (user) => user.groups, {
|
||||||
|
eager: true,
|
||||||
|
cascade: true,
|
||||||
|
})
|
||||||
|
@JoinTable()
|
||||||
|
members: User[];
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ import { AuthToken } from '../auth/auth-token.entity';
|
||||||
import { Revision } from '../revisions/revision.entity';
|
import { Revision } from '../revisions/revision.entity';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { NotInDBError } from '../errors/errors';
|
import { NotInDBError } from '../errors/errors';
|
||||||
|
import { NoteGroupPermission } from '../permissions/note-group-permission.entity';
|
||||||
|
import { NoteUserPermission } from '../permissions/note-user-permission.entity';
|
||||||
|
|
||||||
describe('HistoryService', () => {
|
describe('HistoryService', () => {
|
||||||
let service: HistoryService;
|
let service: HistoryService;
|
||||||
|
@ -54,6 +56,10 @@ describe('HistoryService', () => {
|
||||||
.useClass(Repository)
|
.useClass(Repository)
|
||||||
.overrideProvider(getRepositoryToken(Tag))
|
.overrideProvider(getRepositoryToken(Tag))
|
||||||
.useValue({})
|
.useValue({})
|
||||||
|
.overrideProvider(getRepositoryToken(NoteGroupPermission))
|
||||||
|
.useValue({})
|
||||||
|
.overrideProvider(getRepositoryToken(NoteUserPermission))
|
||||||
|
.useValue({})
|
||||||
.compile();
|
.compile();
|
||||||
|
|
||||||
service = module.get<HistoryService>(HistoryService);
|
service = module.get<HistoryService>(HistoryService);
|
||||||
|
@ -99,7 +105,7 @@ describe('HistoryService', () => {
|
||||||
describe('createOrUpdateHistoryEntry', () => {
|
describe('createOrUpdateHistoryEntry', () => {
|
||||||
describe('works', () => {
|
describe('works', () => {
|
||||||
it('without an preexisting entry', async () => {
|
it('without an preexisting entry', async () => {
|
||||||
const user = new User();
|
const user = {} as User;
|
||||||
const alias = 'alias';
|
const alias = 'alias';
|
||||||
jest.spyOn(historyRepo, 'findOne').mockResolvedValueOnce(undefined);
|
jest.spyOn(historyRepo, 'findOne').mockResolvedValueOnce(undefined);
|
||||||
jest
|
jest
|
||||||
|
@ -118,7 +124,7 @@ describe('HistoryService', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('with an preexisting entry', async () => {
|
it('with an preexisting entry', async () => {
|
||||||
const user = new User();
|
const user = {} as User;
|
||||||
const alias = 'alias';
|
const alias = 'alias';
|
||||||
const historyEntry = HistoryEntry.create(
|
const historyEntry = HistoryEntry.create(
|
||||||
user,
|
user,
|
||||||
|
@ -148,7 +154,7 @@ describe('HistoryService', () => {
|
||||||
describe('updateHistoryEntry', () => {
|
describe('updateHistoryEntry', () => {
|
||||||
describe('works', () => {
|
describe('works', () => {
|
||||||
it('with an entry', async () => {
|
it('with an entry', async () => {
|
||||||
const user = new User();
|
const user = {} as User;
|
||||||
const alias = 'alias';
|
const alias = 'alias';
|
||||||
const note = Note.create(user, alias);
|
const note = Note.create(user, alias);
|
||||||
const historyEntry = HistoryEntry.create(user, note);
|
const historyEntry = HistoryEntry.create(user, note);
|
||||||
|
@ -173,7 +179,7 @@ describe('HistoryService', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('without an entry', async () => {
|
it('without an entry', async () => {
|
||||||
const user = new User();
|
const user = {} as User;
|
||||||
const alias = 'alias';
|
const alias = 'alias';
|
||||||
const note = Note.create(user, alias);
|
const note = Note.create(user, alias);
|
||||||
jest.spyOn(historyRepo, 'findOne').mockResolvedValueOnce(undefined);
|
jest.spyOn(historyRepo, 'findOne').mockResolvedValueOnce(undefined);
|
||||||
|
@ -192,7 +198,7 @@ describe('HistoryService', () => {
|
||||||
describe('deleteHistoryEntry', () => {
|
describe('deleteHistoryEntry', () => {
|
||||||
describe('works', () => {
|
describe('works', () => {
|
||||||
it('with an entry', async () => {
|
it('with an entry', async () => {
|
||||||
const user = new User();
|
const user = {} as User;
|
||||||
const alias = 'alias';
|
const alias = 'alias';
|
||||||
const note = Note.create(user, alias);
|
const note = Note.create(user, alias);
|
||||||
const historyEntry = HistoryEntry.create(user, note);
|
const historyEntry = HistoryEntry.create(user, note);
|
||||||
|
@ -208,7 +214,7 @@ describe('HistoryService', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('without an entry', async () => {
|
it('without an entry', async () => {
|
||||||
const user = new User();
|
const user = {} as User;
|
||||||
const alias = 'alias';
|
const alias = 'alias';
|
||||||
const note = Note.create(user, alias);
|
const note = Note.create(user, alias);
|
||||||
jest.spyOn(historyRepo, 'findOne').mockResolvedValueOnce(undefined);
|
jest.spyOn(historyRepo, 'findOne').mockResolvedValueOnce(undefined);
|
||||||
|
@ -225,7 +231,7 @@ describe('HistoryService', () => {
|
||||||
describe('toHistoryEntryDto', () => {
|
describe('toHistoryEntryDto', () => {
|
||||||
describe('works', () => {
|
describe('works', () => {
|
||||||
it('with aliased note', async () => {
|
it('with aliased note', async () => {
|
||||||
const user = new User();
|
const user = {} as User;
|
||||||
const alias = 'alias';
|
const alias = 'alias';
|
||||||
const title = 'title';
|
const title = 'title';
|
||||||
const tags = ['tag1', 'tag2'];
|
const tags = ['tag1', 'tag2'];
|
||||||
|
@ -247,7 +253,7 @@ describe('HistoryService', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('with regular note', async () => {
|
it('with regular note', async () => {
|
||||||
const user = new User();
|
const user = {} as User;
|
||||||
const title = 'title';
|
const title = 'title';
|
||||||
const id = 'id';
|
const id = 'id';
|
||||||
const tags = ['tag1', 'tag2'];
|
const tags = ['tag1', 'tag2'];
|
||||||
|
|
|
@ -25,6 +25,8 @@ import { MediaService } from './media.service';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { promises as fs } from 'fs';
|
import { promises as fs } from 'fs';
|
||||||
import { ClientError, NotInDBError, PermissionError } from '../errors/errors';
|
import { ClientError, NotInDBError, PermissionError } from '../errors/errors';
|
||||||
|
import { NoteGroupPermission } from '../permissions/note-group-permission.entity';
|
||||||
|
import { NoteUserPermission } from '../permissions/note-user-permission.entity';
|
||||||
|
|
||||||
describe('MediaService', () => {
|
describe('MediaService', () => {
|
||||||
let service: MediaService;
|
let service: MediaService;
|
||||||
|
@ -70,6 +72,10 @@ describe('MediaService', () => {
|
||||||
.useClass(Repository)
|
.useClass(Repository)
|
||||||
.overrideProvider(getRepositoryToken(Tag))
|
.overrideProvider(getRepositoryToken(Tag))
|
||||||
.useValue({})
|
.useValue({})
|
||||||
|
.overrideProvider(getRepositoryToken(NoteGroupPermission))
|
||||||
|
.useValue({})
|
||||||
|
.overrideProvider(getRepositoryToken(NoteUserPermission))
|
||||||
|
.useValue({})
|
||||||
.overrideProvider(getRepositoryToken(MediaUpload))
|
.overrideProvider(getRepositoryToken(MediaUpload))
|
||||||
.useClass(Repository)
|
.useClass(Repository)
|
||||||
.compile();
|
.compile();
|
||||||
|
|
|
@ -13,10 +13,18 @@ import { AuthorColor } from './author-color.entity';
|
||||||
import { Note } from './note.entity';
|
import { Note } from './note.entity';
|
||||||
import { NotesService } from './notes.service';
|
import { NotesService } from './notes.service';
|
||||||
import { Tag } from './tag.entity';
|
import { Tag } from './tag.entity';
|
||||||
|
import { NoteGroupPermission } from '../permissions/note-group-permission.entity';
|
||||||
|
import { NoteUserPermission } from '../permissions/note-user-permission.entity';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
TypeOrmModule.forFeature([Note, AuthorColor, Tag]),
|
TypeOrmModule.forFeature([
|
||||||
|
Note,
|
||||||
|
AuthorColor,
|
||||||
|
Tag,
|
||||||
|
NoteGroupPermission,
|
||||||
|
NoteUserPermission,
|
||||||
|
]),
|
||||||
forwardRef(() => RevisionsModule),
|
forwardRef(() => RevisionsModule),
|
||||||
UsersModule,
|
UsersModule,
|
||||||
LoggerModule,
|
LoggerModule,
|
||||||
|
|
|
@ -18,6 +18,8 @@ import { AuthorColor } from './author-color.entity';
|
||||||
import { Note } from './note.entity';
|
import { Note } from './note.entity';
|
||||||
import { NotesService } from './notes.service';
|
import { NotesService } from './notes.service';
|
||||||
import { Tag } from './tag.entity';
|
import { Tag } from './tag.entity';
|
||||||
|
import { NoteGroupPermission } from '../permissions/note-group-permission.entity';
|
||||||
|
import { NoteUserPermission } from '../permissions/note-user-permission.entity';
|
||||||
|
|
||||||
describe('NotesService', () => {
|
describe('NotesService', () => {
|
||||||
let service: NotesService;
|
let service: NotesService;
|
||||||
|
@ -53,6 +55,10 @@ describe('NotesService', () => {
|
||||||
.useValue({})
|
.useValue({})
|
||||||
.overrideProvider(getRepositoryToken(Tag))
|
.overrideProvider(getRepositoryToken(Tag))
|
||||||
.useValue({})
|
.useValue({})
|
||||||
|
.overrideProvider(getRepositoryToken(NoteGroupPermission))
|
||||||
|
.useValue({})
|
||||||
|
.overrideProvider(getRepositoryToken(NoteUserPermission))
|
||||||
|
.useValue({})
|
||||||
.compile();
|
.compile();
|
||||||
service = module.get<NotesService>(NotesService);
|
service = module.get<NotesService>(NotesService);
|
||||||
});
|
});
|
||||||
|
|
|
@ -159,6 +159,7 @@ export class NotesService {
|
||||||
historyEntries: [],
|
historyEntries: [],
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
userName: 'Testy',
|
userName: 'Testy',
|
||||||
|
groups: [],
|
||||||
},
|
},
|
||||||
description: 'Very descriptive text.',
|
description: 'Very descriptive text.',
|
||||||
userPermissions: [],
|
userPermissions: [],
|
||||||
|
|
|
@ -17,6 +17,8 @@ import { Authorship } from './authorship.entity';
|
||||||
import { Revision } from './revision.entity';
|
import { Revision } from './revision.entity';
|
||||||
import { RevisionsService } from './revisions.service';
|
import { RevisionsService } from './revisions.service';
|
||||||
import { Tag } from '../notes/tag.entity';
|
import { Tag } from '../notes/tag.entity';
|
||||||
|
import { NoteGroupPermission } from '../permissions/note-group-permission.entity';
|
||||||
|
import { NoteUserPermission } from '../permissions/note-user-permission.entity';
|
||||||
|
|
||||||
describe('RevisionsService', () => {
|
describe('RevisionsService', () => {
|
||||||
let service: RevisionsService;
|
let service: RevisionsService;
|
||||||
|
@ -48,6 +50,10 @@ describe('RevisionsService', () => {
|
||||||
.useValue({})
|
.useValue({})
|
||||||
.overrideProvider(getRepositoryToken(Tag))
|
.overrideProvider(getRepositoryToken(Tag))
|
||||||
.useValue({})
|
.useValue({})
|
||||||
|
.overrideProvider(getRepositoryToken(NoteGroupPermission))
|
||||||
|
.useValue({})
|
||||||
|
.overrideProvider(getRepositoryToken(NoteUserPermission))
|
||||||
|
.useValue({})
|
||||||
.compile();
|
.compile();
|
||||||
|
|
||||||
service = module.get<RevisionsService>(RevisionsService);
|
service = module.get<RevisionsService>(RevisionsService);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
import {
|
import {
|
||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
Entity,
|
Entity,
|
||||||
|
ManyToMany,
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
} from 'typeorm';
|
} from 'typeorm';
|
||||||
|
@ -14,6 +15,7 @@ import { Column, OneToMany } from 'typeorm';
|
||||||
import { Note } from '../notes/note.entity';
|
import { Note } from '../notes/note.entity';
|
||||||
import { AuthToken } from '../auth/auth-token.entity';
|
import { AuthToken } from '../auth/auth-token.entity';
|
||||||
import { Identity } from './identity.entity';
|
import { Identity } from './identity.entity';
|
||||||
|
import { Group } from '../groups/group.entity';
|
||||||
import { HistoryEntry } from '../history/history-entry.entity';
|
import { HistoryEntry } from '../history/history-entry.entity';
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
|
@ -52,9 +54,15 @@ export class User {
|
||||||
@OneToMany((_) => Identity, (identity) => identity.user)
|
@OneToMany((_) => Identity, (identity) => identity.user)
|
||||||
identities: Identity[];
|
identities: Identity[];
|
||||||
|
|
||||||
|
@ManyToMany((_) => Group, (group) => group.members)
|
||||||
|
groups: Group[];
|
||||||
|
|
||||||
@OneToMany((_) => HistoryEntry, (historyEntry) => historyEntry.user)
|
@OneToMany((_) => HistoryEntry, (historyEntry) => historyEntry.user)
|
||||||
historyEntries: HistoryEntry[];
|
historyEntries: HistoryEntry[];
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||||
|
private constructor() {}
|
||||||
|
|
||||||
public static create(
|
public static create(
|
||||||
userName: string,
|
userName: string,
|
||||||
displayName: string,
|
displayName: string,
|
||||||
|
|
Loading…
Reference in a new issue