drop group (#9942)

* drop group

* Update operations.ts
This commit is contained in:
syuilo
2023-02-15 13:37:18 +09:00
committed by GitHub
parent 8f2049bcd2
commit 8caf288ac1
52 changed files with 66 additions and 1585 deletions

View File

@@ -211,7 +211,6 @@ import * as ep___i_signinHistory from './endpoints/i/signin-history.js';
import * as ep___i_unpin from './endpoints/i/unpin.js';
import * as ep___i_updateEmail from './endpoints/i/update-email.js';
import * as ep___i_update from './endpoints/i/update.js';
import * as ep___i_userGroupInvites from './endpoints/i/user-group-invites.js';
import * as ep___i_webhooks_create from './endpoints/i/webhooks/create.js';
import * as ep___i_webhooks_show from './endpoints/i/webhooks/show.js';
import * as ep___i_webhooks_list from './endpoints/i/webhooks/list.js';
@@ -294,18 +293,6 @@ import * as ep___users_followers from './endpoints/users/followers.js';
import * as ep___users_following from './endpoints/users/following.js';
import * as ep___users_gallery_posts from './endpoints/users/gallery/posts.js';
import * as ep___users_getFrequentlyRepliedUsers from './endpoints/users/get-frequently-replied-users.js';
import * as ep___users_groups_create from './endpoints/users/groups/create.js';
import * as ep___users_groups_delete from './endpoints/users/groups/delete.js';
import * as ep___users_groups_invitations_accept from './endpoints/users/groups/invitations/accept.js';
import * as ep___users_groups_invitations_reject from './endpoints/users/groups/invitations/reject.js';
import * as ep___users_groups_invite from './endpoints/users/groups/invite.js';
import * as ep___users_groups_joined from './endpoints/users/groups/joined.js';
import * as ep___users_groups_leave from './endpoints/users/groups/leave.js';
import * as ep___users_groups_owned from './endpoints/users/groups/owned.js';
import * as ep___users_groups_pull from './endpoints/users/groups/pull.js';
import * as ep___users_groups_show from './endpoints/users/groups/show.js';
import * as ep___users_groups_transfer from './endpoints/users/groups/transfer.js';
import * as ep___users_groups_update from './endpoints/users/groups/update.js';
import * as ep___users_lists_create from './endpoints/users/lists/create.js';
import * as ep___users_lists_delete from './endpoints/users/lists/delete.js';
import * as ep___users_lists_list from './endpoints/users/lists/list.js';
@@ -540,7 +527,6 @@ const $i_signinHistory: Provider = { provide: 'ep:i/signin-history', useClass: e
const $i_unpin: Provider = { provide: 'ep:i/unpin', useClass: ep___i_unpin.default };
const $i_updateEmail: Provider = { provide: 'ep:i/update-email', useClass: ep___i_updateEmail.default };
const $i_update: Provider = { provide: 'ep:i/update', useClass: ep___i_update.default };
const $i_userGroupInvites: Provider = { provide: 'ep:i/user-group-invites', useClass: ep___i_userGroupInvites.default };
const $i_webhooks_create: Provider = { provide: 'ep:i/webhooks/create', useClass: ep___i_webhooks_create.default };
const $i_webhooks_list: Provider = { provide: 'ep:i/webhooks/list', useClass: ep___i_webhooks_list.default };
const $i_webhooks_show: Provider = { provide: 'ep:i/webhooks/show', useClass: ep___i_webhooks_show.default };
@@ -623,18 +609,6 @@ const $users_followers: Provider = { provide: 'ep:users/followers', useClass: ep
const $users_following: Provider = { provide: 'ep:users/following', useClass: ep___users_following.default };
const $users_gallery_posts: Provider = { provide: 'ep:users/gallery/posts', useClass: ep___users_gallery_posts.default };
const $users_getFrequentlyRepliedUsers: Provider = { provide: 'ep:users/get-frequently-replied-users', useClass: ep___users_getFrequentlyRepliedUsers.default };
const $users_groups_create: Provider = { provide: 'ep:users/groups/create', useClass: ep___users_groups_create.default };
const $users_groups_delete: Provider = { provide: 'ep:users/groups/delete', useClass: ep___users_groups_delete.default };
const $users_groups_invitations_accept: Provider = { provide: 'ep:users/groups/invitations/accept', useClass: ep___users_groups_invitations_accept.default };
const $users_groups_invitations_reject: Provider = { provide: 'ep:users/groups/invitations/reject', useClass: ep___users_groups_invitations_reject.default };
const $users_groups_invite: Provider = { provide: 'ep:users/groups/invite', useClass: ep___users_groups_invite.default };
const $users_groups_joined: Provider = { provide: 'ep:users/groups/joined', useClass: ep___users_groups_joined.default };
const $users_groups_leave: Provider = { provide: 'ep:users/groups/leave', useClass: ep___users_groups_leave.default };
const $users_groups_owned: Provider = { provide: 'ep:users/groups/owned', useClass: ep___users_groups_owned.default };
const $users_groups_pull: Provider = { provide: 'ep:users/groups/pull', useClass: ep___users_groups_pull.default };
const $users_groups_show: Provider = { provide: 'ep:users/groups/show', useClass: ep___users_groups_show.default };
const $users_groups_transfer: Provider = { provide: 'ep:users/groups/transfer', useClass: ep___users_groups_transfer.default };
const $users_groups_update: Provider = { provide: 'ep:users/groups/update', useClass: ep___users_groups_update.default };
const $users_lists_create: Provider = { provide: 'ep:users/lists/create', useClass: ep___users_lists_create.default };
const $users_lists_delete: Provider = { provide: 'ep:users/lists/delete', useClass: ep___users_lists_delete.default };
const $users_lists_list: Provider = { provide: 'ep:users/lists/list', useClass: ep___users_lists_list.default };
@@ -873,7 +847,6 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
$i_unpin,
$i_updateEmail,
$i_update,
$i_userGroupInvites,
$i_webhooks_create,
$i_webhooks_list,
$i_webhooks_show,
@@ -956,18 +929,6 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
$users_following,
$users_gallery_posts,
$users_getFrequentlyRepliedUsers,
$users_groups_create,
$users_groups_delete,
$users_groups_invitations_accept,
$users_groups_invitations_reject,
$users_groups_invite,
$users_groups_joined,
$users_groups_leave,
$users_groups_owned,
$users_groups_pull,
$users_groups_show,
$users_groups_transfer,
$users_groups_update,
$users_lists_create,
$users_lists_delete,
$users_lists_list,
@@ -1200,7 +1161,6 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
$i_unpin,
$i_updateEmail,
$i_update,
$i_userGroupInvites,
$i_webhooks_create,
$i_webhooks_list,
$i_webhooks_show,
@@ -1281,18 +1241,6 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
$users_following,
$users_gallery_posts,
$users_getFrequentlyRepliedUsers,
$users_groups_create,
$users_groups_delete,
$users_groups_invitations_accept,
$users_groups_invitations_reject,
$users_groups_invite,
$users_groups_joined,
$users_groups_leave,
$users_groups_owned,
$users_groups_pull,
$users_groups_show,
$users_groups_transfer,
$users_groups_update,
$users_lists_create,
$users_lists_delete,
$users_lists_list,

View File

@@ -210,7 +210,6 @@ import * as ep___i_signinHistory from './endpoints/i/signin-history.js';
import * as ep___i_unpin from './endpoints/i/unpin.js';
import * as ep___i_updateEmail from './endpoints/i/update-email.js';
import * as ep___i_update from './endpoints/i/update.js';
import * as ep___i_userGroupInvites from './endpoints/i/user-group-invites.js';
import * as ep___i_webhooks_create from './endpoints/i/webhooks/create.js';
import * as ep___i_webhooks_show from './endpoints/i/webhooks/show.js';
import * as ep___i_webhooks_list from './endpoints/i/webhooks/list.js';
@@ -293,18 +292,6 @@ import * as ep___users_followers from './endpoints/users/followers.js';
import * as ep___users_following from './endpoints/users/following.js';
import * as ep___users_gallery_posts from './endpoints/users/gallery/posts.js';
import * as ep___users_getFrequentlyRepliedUsers from './endpoints/users/get-frequently-replied-users.js';
import * as ep___users_groups_create from './endpoints/users/groups/create.js';
import * as ep___users_groups_delete from './endpoints/users/groups/delete.js';
import * as ep___users_groups_invitations_accept from './endpoints/users/groups/invitations/accept.js';
import * as ep___users_groups_invitations_reject from './endpoints/users/groups/invitations/reject.js';
import * as ep___users_groups_invite from './endpoints/users/groups/invite.js';
import * as ep___users_groups_joined from './endpoints/users/groups/joined.js';
import * as ep___users_groups_leave from './endpoints/users/groups/leave.js';
import * as ep___users_groups_owned from './endpoints/users/groups/owned.js';
import * as ep___users_groups_pull from './endpoints/users/groups/pull.js';
import * as ep___users_groups_show from './endpoints/users/groups/show.js';
import * as ep___users_groups_transfer from './endpoints/users/groups/transfer.js';
import * as ep___users_groups_update from './endpoints/users/groups/update.js';
import * as ep___users_lists_create from './endpoints/users/lists/create.js';
import * as ep___users_lists_delete from './endpoints/users/lists/delete.js';
import * as ep___users_lists_list from './endpoints/users/lists/list.js';
@@ -537,7 +524,6 @@ const eps = [
['i/unpin', ep___i_unpin],
['i/update-email', ep___i_updateEmail],
['i/update', ep___i_update],
['i/user-group-invites', ep___i_userGroupInvites],
['i/webhooks/create', ep___i_webhooks_create],
['i/webhooks/list', ep___i_webhooks_list],
['i/webhooks/show', ep___i_webhooks_show],
@@ -620,18 +606,6 @@ const eps = [
['users/following', ep___users_following],
['users/gallery/posts', ep___users_gallery_posts],
['users/get-frequently-replied-users', ep___users_getFrequentlyRepliedUsers],
['users/groups/create', ep___users_groups_create],
['users/groups/delete', ep___users_groups_delete],
['users/groups/invitations/accept', ep___users_groups_invitations_accept],
['users/groups/invitations/reject', ep___users_groups_invitations_reject],
['users/groups/invite', ep___users_groups_invite],
['users/groups/joined', ep___users_groups_joined],
['users/groups/leave', ep___users_groups_leave],
['users/groups/owned', ep___users_groups_owned],
['users/groups/pull', ep___users_groups_pull],
['users/groups/show', ep___users_groups_show],
['users/groups/transfer', ep___users_groups_transfer],
['users/groups/update', ep___users_groups_update],
['users/lists/create', ep___users_lists_create],
['users/lists/delete', ep___users_lists_delete],
['users/lists/list', ep___users_lists_list],

View File

@@ -1,7 +1,7 @@
import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { IdService } from '@/core/IdService.js';
import type { UserListsRepository, UserGroupJoiningsRepository, AntennasRepository } from '@/models/index.js';
import type { UserListsRepository, AntennasRepository } from '@/models/index.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { AntennaEntityService } from '@/core/entities/AntennaEntityService.js';
import { DI } from '@/di-symbols.js';
@@ -22,12 +22,6 @@ export const meta = {
id: '95063e93-a283-4b8b-9aa5-bcdb8df69a7f',
},
noSuchUserGroup: {
message: 'No such user group.',
code: 'NO_SUCH_USER_GROUP',
id: 'aa3c0b9a-8cae-47c0-92ac-202ce5906682',
},
tooManyAntennas: {
message: 'You cannot create antenna any more.',
code: 'TOO_MANY_ANTENNAS',
@@ -46,9 +40,8 @@ export const paramDef = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1, maxLength: 100 },
src: { type: 'string', enum: ['home', 'all', 'users', 'list', 'group'] },
src: { type: 'string', enum: ['home', 'all', 'users', 'list'] },
userListId: { type: 'string', format: 'misskey:id', nullable: true },
userGroupId: { type: 'string', format: 'misskey:id', nullable: true },
keywords: { type: 'array', items: {
type: 'array', items: {
type: 'string',
@@ -80,9 +73,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
@Inject(DI.userListsRepository)
private userListsRepository: UserListsRepository,
@Inject(DI.userGroupJoiningsRepository)
private userGroupJoiningsRepository: UserGroupJoiningsRepository,
private antennaEntityService: AntennaEntityService,
private roleService: RoleService,
private idService: IdService,
@@ -97,7 +87,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
}
let userList;
let userGroupJoining;
if (ps.src === 'list' && ps.userListId) {
userList = await this.userListsRepository.findOneBy({
@@ -108,15 +97,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
if (userList == null) {
throw new ApiError(meta.errors.noSuchUserList);
}
} else if (ps.src === 'group' && ps.userGroupId) {
userGroupJoining = await this.userGroupJoiningsRepository.findOneBy({
userGroupId: ps.userGroupId,
userId: me.id,
});
if (userGroupJoining == null) {
throw new ApiError(meta.errors.noSuchUserGroup);
}
}
const antenna = await this.antennasRepository.insert({
@@ -126,7 +106,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
name: ps.name,
src: ps.src,
userListId: userList ? userList.id : null,
userGroupJoiningId: userGroupJoining ? userGroupJoining.id : null,
keywords: ps.keywords,
excludeKeywords: ps.excludeKeywords,
users: ps.users,

View File

@@ -1,6 +1,6 @@
import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js';
import type { AntennasRepository, UserListsRepository, UserGroupJoiningsRepository } from '@/models/index.js';
import type { AntennasRepository, UserListsRepository } from '@/models/index.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { AntennaEntityService } from '@/core/entities/AntennaEntityService.js';
import { DI } from '@/di-symbols.js';
@@ -25,12 +25,6 @@ export const meta = {
code: 'NO_SUCH_USER_LIST',
id: '1c6b35c9-943e-48c2-81e4-2844989407f7',
},
noSuchUserGroup: {
message: 'No such user group.',
code: 'NO_SUCH_USER_GROUP',
id: '109ed789-b6eb-456e-b8a9-6059d567d385',
},
},
res: {
@@ -45,9 +39,8 @@ export const paramDef = {
properties: {
antennaId: { type: 'string', format: 'misskey:id' },
name: { type: 'string', minLength: 1, maxLength: 100 },
src: { type: 'string', enum: ['home', 'all', 'users', 'list', 'group'] },
src: { type: 'string', enum: ['home', 'all', 'users', 'list'] },
userListId: { type: 'string', format: 'misskey:id', nullable: true },
userGroupId: { type: 'string', format: 'misskey:id', nullable: true },
keywords: { type: 'array', items: {
type: 'array', items: {
type: 'string',
@@ -78,9 +71,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
@Inject(DI.userListsRepository)
private userListsRepository: UserListsRepository,
@Inject(DI.userGroupJoiningsRepository)
private userGroupJoiningsRepository: UserGroupJoiningsRepository,
private antennaEntityService: AntennaEntityService,
private globalEventService: GlobalEventService,
@@ -97,7 +87,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
}
let userList;
let userGroupJoining;
if (ps.src === 'list' && ps.userListId) {
userList = await this.userListsRepository.findOneBy({
@@ -108,22 +97,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
if (userList == null) {
throw new ApiError(meta.errors.noSuchUserList);
}
} else if (ps.src === 'group' && ps.userGroupId) {
userGroupJoining = await this.userGroupJoiningsRepository.findOneBy({
userGroupId: ps.userGroupId,
userId: me.id,
});
if (userGroupJoining == null) {
throw new ApiError(meta.errors.noSuchUserGroup);
}
}
await this.antennasRepository.update(antenna.id, {
name: ps.name,
src: ps.src,
userListId: userList ? userList.id : null,
userGroupJoiningId: userGroupJoining ? userGroupJoining.id : null,
keywords: ps.keywords,
excludeKeywords: ps.excludeKeywords,
users: ps.users,

View File

@@ -1,69 +0,0 @@
import { Inject, Injectable } from '@nestjs/common';
import { Endpoint } from '@/server/api/endpoint-base.js';
import type { UserGroupInvitationsRepository } from '@/models/index.js';
import { QueryService } from '@/core/QueryService.js';
import { UserGroupInvitationEntityService } from '@/core/entities/UserGroupInvitationEntityService.js';
import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['account', 'groups'],
requireCredential: true,
kind: 'read:user-groups',
res: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'object',
optional: false, nullable: false,
properties: {
id: {
type: 'string',
optional: false, nullable: false,
format: 'id',
},
group: {
type: 'object',
optional: false, nullable: false,
ref: 'UserGroup',
},
},
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' },
},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
@Inject(DI.userGroupInvitationsRepository)
private userGroupInvitationsRepository: UserGroupInvitationsRepository,
private userGroupInvitationEntityService: UserGroupInvitationEntityService,
private queryService: QueryService,
) {
super(meta, paramDef, async (ps, me) => {
const query = this.queryService.makePaginationQuery(this.userGroupInvitationsRepository.createQueryBuilder('invitation'), ps.sinceId, ps.untilId)
.andWhere('invitation.userId = :meId', { meId: me.id })
.leftJoinAndSelect('invitation.userGroup', 'user_group');
const invitations = await query
.take(ps.limit)
.getMany();
return await this.userGroupInvitationEntityService.packMany(invitations);
});
}
}

View File

@@ -1,72 +0,0 @@
import { Inject, Injectable } from '@nestjs/common';
import ms from 'ms';
import type { UserGroupsRepository, UserGroupJoiningsRepository } from '@/models/index.js';
import { IdService } from '@/core/IdService.js';
import type { UserGroup } from '@/models/entities/UserGroup.js';
import type { UserGroupJoining } from '@/models/entities/UserGroupJoining.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { UserGroupEntityService } from '@/core/entities/UserGroupEntityService.js';
import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['groups'],
requireCredential: true,
kind: 'write:user-groups',
description: 'Create a new group.',
limit: {
duration: ms('1hour'),
max: 10,
},
res: {
type: 'object',
optional: false, nullable: false,
ref: 'UserGroup',
},
} as const;
export const paramDef = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1, maxLength: 100 },
},
required: ['name'],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
@Inject(DI.userGroupsRepository)
private userGroupsRepository: UserGroupsRepository,
@Inject(DI.userGroupJoiningsRepository)
private userGroupJoiningsRepository: UserGroupJoiningsRepository,
private userGroupEntityService: UserGroupEntityService,
private idService: IdService,
) {
super(meta, paramDef, async (ps, me) => {
const userGroup = await this.userGroupsRepository.insert({
id: this.idService.genId(),
createdAt: new Date(),
userId: me.id,
name: ps.name,
} as UserGroup).then(x => this.userGroupsRepository.findOneByOrFail(x.identifiers[0]));
// Push the owner
await this.userGroupJoiningsRepository.insert({
id: this.idService.genId(),
createdAt: new Date(),
userId: me.id,
userGroupId: userGroup.id,
} as UserGroupJoining);
return await this.userGroupEntityService.pack(userGroup);
});
}
}

View File

@@ -1,53 +0,0 @@
import { Inject, Injectable } from '@nestjs/common';
import type { UserGroupsRepository } from '@/models/index.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { DI } from '@/di-symbols.js';
import { ApiError } from '../../../error.js';
export const meta = {
tags: ['groups'],
requireCredential: true,
kind: 'write:user-groups',
description: 'Delete an existing group.',
errors: {
noSuchGroup: {
message: 'No such group.',
code: 'NO_SUCH_GROUP',
id: '63dbd64c-cd77-413f-8e08-61781e210b38',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
groupId: { type: 'string', format: 'misskey:id' },
},
required: ['groupId'],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
@Inject(DI.userGroupsRepository)
private userGroupsRepository: UserGroupsRepository,
) {
super(meta, paramDef, async (ps, me) => {
const userGroup = await this.userGroupsRepository.findOneBy({
id: ps.groupId,
userId: me.id,
});
if (userGroup == null) {
throw new ApiError(meta.errors.noSuchGroup);
}
await this.userGroupsRepository.delete(userGroup.id);
});
}
}

View File

@@ -1,72 +0,0 @@
import { Inject, Injectable } from '@nestjs/common';
import type { UserGroupInvitationsRepository, UserGroupJoiningsRepository } from '@/models/index.js';
import { IdService } from '@/core/IdService.js';
import type { UserGroupJoining } from '@/models/entities/UserGroupJoining.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { DI } from '@/di-symbols.js';
import { ApiError } from '../../../../error.js';
export const meta = {
tags: ['groups', 'users'],
requireCredential: true,
kind: 'write:user-groups',
description: 'Join a group the authenticated user has been invited to.',
errors: {
noSuchInvitation: {
message: 'No such invitation.',
code: 'NO_SUCH_INVITATION',
id: '98c11eca-c890-4f42-9806-c8c8303ebb5e',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
invitationId: { type: 'string', format: 'misskey:id' },
},
required: ['invitationId'],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
@Inject(DI.userGroupInvitationsRepository)
private userGroupInvitationsRepository: UserGroupInvitationsRepository,
@Inject(DI.userGroupJoiningsRepository)
private userGroupJoiningsRepository: UserGroupJoiningsRepository,
private idService: IdService,
) {
super(meta, paramDef, async (ps, me) => {
// Fetch the invitation
const invitation = await this.userGroupInvitationsRepository.findOneBy({
id: ps.invitationId,
});
if (invitation == null) {
throw new ApiError(meta.errors.noSuchInvitation);
}
if (invitation.userId !== me.id) {
throw new ApiError(meta.errors.noSuchInvitation);
}
// Push the user
await this.userGroupJoiningsRepository.insert({
id: this.idService.genId(),
createdAt: new Date(),
userId: me.id,
userGroupId: invitation.userGroupId,
} as UserGroupJoining);
this.userGroupInvitationsRepository.delete(invitation.id);
});
}
}

View File

@@ -1,57 +0,0 @@
import { Inject, Injectable } from '@nestjs/common';
import type { UserGroupInvitationsRepository } from '@/models/index.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { DI } from '@/di-symbols.js';
import { ApiError } from '../../../../error.js';
export const meta = {
tags: ['groups', 'users'],
requireCredential: true,
kind: 'write:user-groups',
description: 'Delete an existing group invitation for the authenticated user without joining the group.',
errors: {
noSuchInvitation: {
message: 'No such invitation.',
code: 'NO_SUCH_INVITATION',
id: 'ad7471d4-2cd9-44b4-ac68-e7136b4ce656',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
invitationId: { type: 'string', format: 'misskey:id' },
},
required: ['invitationId'],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
@Inject(DI.userGroupInvitationsRepository)
private userGroupInvitationsRepository: UserGroupInvitationsRepository,
) {
super(meta, paramDef, async (ps, me) => {
// Fetch the invitation
const invitation = await this.userGroupInvitationsRepository.findOneBy({
id: ps.invitationId,
});
if (invitation == null) {
throw new ApiError(meta.errors.noSuchInvitation);
}
if (invitation.userId !== me.id) {
throw new ApiError(meta.errors.noSuchInvitation);
}
await this.userGroupInvitationsRepository.delete(invitation.id);
});
}
}

View File

@@ -1,122 +0,0 @@
import { Inject, Injectable } from '@nestjs/common';
import type { UserGroupsRepository, UserGroupJoiningsRepository, UserGroupInvitationsRepository } from '@/models/index.js';
import { IdService } from '@/core/IdService.js';
import type { UserGroupInvitation } from '@/models/entities/UserGroupInvitation.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { GetterService } from '@/server/api/GetterService.js';
import { CreateNotificationService } from '@/core/CreateNotificationService.js';
import { DI } from '@/di-symbols.js';
import { ApiError } from '../../../error.js';
export const meta = {
tags: ['groups', 'users'],
requireCredential: true,
kind: 'write:user-groups',
description: 'Invite a user to an existing group.',
errors: {
noSuchGroup: {
message: 'No such group.',
code: 'NO_SUCH_GROUP',
id: '583f8bc0-8eee-4b78-9299-1e14fc91e409',
},
noSuchUser: {
message: 'No such user.',
code: 'NO_SUCH_USER',
id: 'da52de61-002c-475b-90e1-ba64f9cf13a8',
},
alreadyAdded: {
message: 'That user has already been added to that group.',
code: 'ALREADY_ADDED',
id: '7e35c6a0-39b2-4488-aea6-6ee20bd5da2c',
},
alreadyInvited: {
message: 'That user has already been invited to that group.',
code: 'ALREADY_INVITED',
id: 'ee0f58b4-b529-4d13-b761-b9a3e69f97e6',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
groupId: { type: 'string', format: 'misskey:id' },
userId: { type: 'string', format: 'misskey:id' },
},
required: ['groupId', 'userId'],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
@Inject(DI.userGroupsRepository)
private userGroupsRepository: UserGroupsRepository,
@Inject(DI.userGroupInvitationsRepository)
private userGroupInvitationsRepository: UserGroupInvitationsRepository,
@Inject(DI.userGroupJoiningsRepository)
private userGroupJoiningsRepository: UserGroupJoiningsRepository,
private idService: IdService,
private getterService: GetterService,
private createNotificationService: CreateNotificationService,
) {
super(meta, paramDef, async (ps, me) => {
// Fetch the group
const userGroup = await this.userGroupsRepository.findOneBy({
id: ps.groupId,
userId: me.id,
});
if (userGroup == null) {
throw new ApiError(meta.errors.noSuchGroup);
}
// Fetch the user
const user = await this.getterService.getUser(ps.userId).catch(err => {
if (err.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
throw err;
});
const joining = await this.userGroupJoiningsRepository.findOneBy({
userGroupId: userGroup.id,
userId: user.id,
});
if (joining) {
throw new ApiError(meta.errors.alreadyAdded);
}
const existInvitation = await this.userGroupInvitationsRepository.findOneBy({
userGroupId: userGroup.id,
userId: user.id,
});
if (existInvitation) {
throw new ApiError(meta.errors.alreadyInvited);
}
const invitation = await this.userGroupInvitationsRepository.insert({
id: this.idService.genId(),
createdAt: new Date(),
userId: user.id,
userGroupId: userGroup.id,
} as UserGroupInvitation).then(x => this.userGroupInvitationsRepository.findOneByOrFail(x.identifiers[0]));
// 通知を作成
this.createNotificationService.createNotification(user.id, 'groupInvited', {
notifierId: me.id,
userGroupInvitationId: invitation.id,
});
});
}
}

View File

@@ -1,61 +0,0 @@
import { Not, In } from 'typeorm';
import { Inject, Injectable } from '@nestjs/common';
import type { UserGroupsRepository, UserGroupJoiningsRepository } from '@/models/index.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { UserGroupEntityService } from '@/core/entities/UserGroupEntityService.js';
import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['groups', 'account'],
requireCredential: true,
kind: 'read:user-groups',
description: 'List the groups that the authenticated user is a member of.',
res: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'object',
optional: false, nullable: false,
ref: 'UserGroup',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
@Inject(DI.userGroupsRepository)
private userGroupsRepository: UserGroupsRepository,
@Inject(DI.userGroupJoiningsRepository)
private userGroupJoiningsRepository: UserGroupJoiningsRepository,
private userGroupEntityService: UserGroupEntityService,
) {
super(meta, paramDef, async (ps, me) => {
const ownedGroups = await this.userGroupsRepository.findBy({
userId: me.id,
});
const joinings = await this.userGroupJoiningsRepository.findBy({
userId: me.id,
...(ownedGroups.length > 0 ? {
userGroupId: Not(In(ownedGroups.map(x => x.id))),
} : {}),
});
return await Promise.all(joinings.map(x => this.userGroupEntityService.pack(x.userGroupId)));
});
}
}

View File

@@ -1,66 +0,0 @@
import { Inject, Injectable } from '@nestjs/common';
import type { UserGroupsRepository, UserGroupJoiningsRepository } from '@/models/index.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { DI } from '@/di-symbols.js';
import { ApiError } from '../../../error.js';
export const meta = {
tags: ['groups', 'users'],
requireCredential: true,
kind: 'write:user-groups',
description: 'Leave a group. The owner of a group can not leave. They must transfer ownership or delete the group instead.',
errors: {
noSuchGroup: {
message: 'No such group.',
code: 'NO_SUCH_GROUP',
id: '62780270-1f67-5dc0-daca-3eb510612e31',
},
youAreOwner: {
message: 'Your are the owner.',
code: 'YOU_ARE_OWNER',
id: 'b6d6e0c2-ef8a-9bb8-653d-79f4a3107c69',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
groupId: { type: 'string', format: 'misskey:id' },
},
required: ['groupId'],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
@Inject(DI.userGroupsRepository)
private userGroupsRepository: UserGroupsRepository,
@Inject(DI.userGroupJoiningsRepository)
private userGroupJoiningsRepository: UserGroupJoiningsRepository,
) {
super(meta, paramDef, async (ps, me) => {
// Fetch the group
const userGroup = await this.userGroupsRepository.findOneBy({
id: ps.groupId,
});
if (userGroup == null) {
throw new ApiError(meta.errors.noSuchGroup);
}
if (me.id === userGroup.userId) {
throw new ApiError(meta.errors.youAreOwner);
}
await this.userGroupJoiningsRepository.delete({ userGroupId: userGroup.id, userId: me.id });
});
}
}

View File

@@ -1,50 +0,0 @@
import { Inject, Injectable } from '@nestjs/common';
import type { UserGroupsRepository } from '@/models/index.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { UserGroupEntityService } from '@/core/entities/UserGroupEntityService.js';
import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['groups', 'account'],
requireCredential: true,
kind: 'read:user-groups',
description: 'List the groups that the authenticated user is the owner of.',
res: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'object',
optional: false, nullable: false,
ref: 'UserGroup',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
@Inject(DI.userGroupsRepository)
private userGroupsRepository: UserGroupsRepository,
private userGroupEntityService: UserGroupEntityService,
) {
super(meta, paramDef, async (ps, me) => {
const userGroups = await this.userGroupsRepository.findBy({
userId: me.id,
});
return await Promise.all(userGroups.map(x => this.userGroupEntityService.pack(x)));
});
}
}

View File

@@ -1,84 +0,0 @@
import { Inject, Injectable } from '@nestjs/common';
import type { UserGroupsRepository, UserGroupJoiningsRepository } from '@/models/index.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { GetterService } from '@/server/api/GetterService.js';
import { DI } from '@/di-symbols.js';
import { ApiError } from '../../../error.js';
export const meta = {
tags: ['groups', 'users'],
requireCredential: true,
kind: 'write:user-groups',
description: 'Removes a specified user from a group. The owner can not be removed.',
errors: {
noSuchGroup: {
message: 'No such group.',
code: 'NO_SUCH_GROUP',
id: '4662487c-05b1-4b78-86e5-fd46998aba74',
},
noSuchUser: {
message: 'No such user.',
code: 'NO_SUCH_USER',
id: '0b5cc374-3681-41da-861e-8bc1146f7a55',
},
isOwner: {
message: 'The user is the owner.',
code: 'IS_OWNER',
id: '1546eed5-4414-4dea-81c1-b0aec4f6d2af',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
groupId: { type: 'string', format: 'misskey:id' },
userId: { type: 'string', format: 'misskey:id' },
},
required: ['groupId', 'userId'],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
@Inject(DI.userGroupsRepository)
private userGroupsRepository: UserGroupsRepository,
@Inject(DI.userGroupJoiningsRepository)
private userGroupJoiningsRepository: UserGroupJoiningsRepository,
private getterService: GetterService,
) {
super(meta, paramDef, async (ps, me) => {
// Fetch the group
const userGroup = await this.userGroupsRepository.findOneBy({
id: ps.groupId,
userId: me.id,
});
if (userGroup == null) {
throw new ApiError(meta.errors.noSuchGroup);
}
// Fetch the user
const user = await this.getterService.getUser(ps.userId).catch(err => {
if (err.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
throw err;
});
if (user.id === userGroup.userId) {
throw new ApiError(meta.errors.isOwner);
}
// Pull the user
await this.userGroupJoiningsRepository.delete({ userGroupId: userGroup.id, userId: user.id });
});
}
}

View File

@@ -1,74 +0,0 @@
import { Inject, Injectable } from '@nestjs/common';
import type { UserGroupsRepository, UserGroupJoiningsRepository } from '@/models/index.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { UserGroupEntityService } from '@/core/entities/UserGroupEntityService.js';
import { DI } from '@/di-symbols.js';
import { ApiError } from '../../../error.js';
export const meta = {
tags: ['groups', 'account'],
requireCredential: true,
kind: 'read:user-groups',
description: 'Show the properties of a group.',
res: {
type: 'object',
optional: false, nullable: false,
ref: 'UserGroup',
},
errors: {
noSuchGroup: {
message: 'No such group.',
code: 'NO_SUCH_GROUP',
id: 'ea04751e-9b7e-487b-a509-330fb6bd6b9b',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
groupId: { type: 'string', format: 'misskey:id' },
},
required: ['groupId'],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
@Inject(DI.userGroupsRepository)
private userGroupsRepository: UserGroupsRepository,
@Inject(DI.userGroupJoiningsRepository)
private userGroupJoiningsRepository: UserGroupJoiningsRepository,
private userGroupEntityService: UserGroupEntityService,
) {
super(meta, paramDef, async (ps, me) => {
// Fetch the group
const userGroup = await this.userGroupsRepository.findOneBy({
id: ps.groupId,
});
if (userGroup == null) {
throw new ApiError(meta.errors.noSuchGroup);
}
const joining = await this.userGroupJoiningsRepository.findOneBy({
userId: me.id,
userGroupId: userGroup.id,
});
if (joining == null && userGroup.userId !== me.id) {
throw new ApiError(meta.errors.noSuchGroup);
}
return await this.userGroupEntityService.pack(userGroup);
});
}
}

View File

@@ -1,100 +0,0 @@
import { Inject, Injectable } from '@nestjs/common';
import type { UserGroupsRepository, UserGroupJoiningsRepository } from '@/models/index.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { UserGroupEntityService } from '@/core/entities/UserGroupEntityService.js';
import { GetterService } from '@/server/api/GetterService.js';
import { DI } from '@/di-symbols.js';
import { ApiError } from '../../../error.js';
export const meta = {
tags: ['groups', 'users'],
requireCredential: true,
kind: 'write:user-groups',
description: 'Transfer ownership of a group from the authenticated user to another user.',
res: {
type: 'object',
optional: false, nullable: false,
ref: 'UserGroup',
},
errors: {
noSuchGroup: {
message: 'No such group.',
code: 'NO_SUCH_GROUP',
id: '8e31d36b-2f88-4ccd-a438-e2d78a9162db',
},
noSuchUser: {
message: 'No such user.',
code: 'NO_SUCH_USER',
id: '711f7ebb-bbb9-4dfa-b540-b27809fed5e9',
},
noSuchGroupMember: {
message: 'No such group member.',
code: 'NO_SUCH_GROUP_MEMBER',
id: 'd31bebee-196d-42c2-9a3e-9474d4be6cc4',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
groupId: { type: 'string', format: 'misskey:id' },
userId: { type: 'string', format: 'misskey:id' },
},
required: ['groupId', 'userId'],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
@Inject(DI.userGroupsRepository)
private userGroupsRepository: UserGroupsRepository,
@Inject(DI.userGroupJoiningsRepository)
private userGroupJoiningsRepository: UserGroupJoiningsRepository,
private userGroupEntityService: UserGroupEntityService,
private getterService: GetterService,
) {
super(meta, paramDef, async (ps, me) => {
// Fetch the group
const userGroup = await this.userGroupsRepository.findOneBy({
id: ps.groupId,
userId: me.id,
});
if (userGroup == null) {
throw new ApiError(meta.errors.noSuchGroup);
}
// Fetch the user
const user = await this.getterService.getUser(ps.userId).catch(err => {
if (err.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser);
throw err;
});
const joining = await this.userGroupJoiningsRepository.findOneBy({
userGroupId: userGroup.id,
userId: user.id,
});
if (joining == null) {
throw new ApiError(meta.errors.noSuchGroupMember);
}
await this.userGroupsRepository.update(userGroup.id, {
userId: ps.userId,
});
return await this.userGroupEntityService.pack(userGroup.id);
});
}
}

View File

@@ -1,68 +0,0 @@
import { Inject, Injectable } from '@nestjs/common';
import type { UserGroupsRepository } from '@/models/index.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { UserGroupEntityService } from '@/core/entities/UserGroupEntityService.js';
import { DI } from '@/di-symbols.js';
import { ApiError } from '../../../error.js';
export const meta = {
tags: ['groups'],
requireCredential: true,
kind: 'write:user-groups',
description: 'Update the properties of a group.',
res: {
type: 'object',
optional: false, nullable: false,
ref: 'UserGroup',
},
errors: {
noSuchGroup: {
message: 'No such group.',
code: 'NO_SUCH_GROUP',
id: '9081cda3-7a9e-4fac-a6ce-908d70f282f6',
},
},
} as const;
export const paramDef = {
type: 'object',
properties: {
groupId: { type: 'string', format: 'misskey:id' },
name: { type: 'string', minLength: 1, maxLength: 100 },
},
required: ['groupId', 'name'],
} as const;
// eslint-disable-next-line import/no-default-export
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
@Inject(DI.userGroupsRepository)
private userGroupsRepository: UserGroupsRepository,
private userGroupEntityService: UserGroupEntityService,
) {
super(meta, paramDef, async (ps, me) => {
// Fetch the group
const userGroup = await this.userGroupsRepository.findOneBy({
id: ps.groupId,
userId: me.id,
});
if (userGroup == null) {
throw new ApiError(meta.errors.noSuchGroup);
}
await this.userGroupsRepository.update(userGroup.id, {
name: ps.name,
});
return await this.userGroupEntityService.pack(userGroup.id);
});
}
}

View File

@@ -3,7 +3,6 @@ import type { Channel as ChannelModel } from '@/models/entities/Channel.js';
import type { FollowingsRepository, MutingsRepository, UserProfilesRepository, ChannelFollowingsRepository, BlockingsRepository } from '@/models/index.js';
import type { AccessToken } from '@/models/entities/AccessToken.js';
import type { UserProfile } from '@/models/entities/UserProfile.js';
import type { UserGroup } from '@/models/entities/UserGroup.js';
import type { Packed } from '@/misc/schema.js';
import type { GlobalEventService } from '@/core/GlobalEventService.js';
import type { NoteReadService } from '@/core/NoteReadService.js';

View File

@@ -6,7 +6,6 @@ import type { Antenna } from '@/models/entities/Antenna.js';
import type { DriveFile } from '@/models/entities/DriveFile.js';
import type { DriveFolder } from '@/models/entities/DriveFolder.js';
import type { UserList } from '@/models/entities/UserList.js';
import type { UserGroup } from '@/models/entities/UserGroup.js';
import type { AbuseUserReport } from '@/models/entities/AbuseUserReport.js';
import type { Signin } from '@/models/entities/Signin.js';
import type { Page } from '@/models/entities/Page.js';