This commit is contained in:
tamaina 2023-06-04 14:48:23 +00:00
parent f81479ad05
commit 2fc2f2d616
5 changed files with 204 additions and 149 deletions

View File

@ -11,24 +11,10 @@ import { bindThis } from '@/decorators.js';
import { RoleService } from '@/core/RoleService.js'; import { RoleService } from '@/core/RoleService.js';
import { QueueService } from '@/core/QueueService.js'; import { QueueService } from '@/core/QueueService.js';
export const meta = {
tags: ['admin'],
requireCredential: true,
requireModerator: true,
} as const;
export const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
},
required: ['userId'],
} as const;
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
@Injectable() @Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { export default class extends Endpoint<'admin/suspend-user'> {
name = 'admin/suspend-user' as const;
constructor( constructor(
@Inject(DI.usersRepository) @Inject(DI.usersRepository)
private usersRepository: UsersRepository, private usersRepository: UsersRepository,
@ -41,7 +27,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private moderationLogService: ModerationLogService, private moderationLogService: ModerationLogService,
private queueService: QueueService, private queueService: QueueService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(async (ps, me) => {
const user = await this.usersRepository.findOneBy({ id: ps.userId }); const user = await this.usersRepository.findOneBy({ id: ps.userId });
if (user == null) { if (user == null) {

View File

@ -13,16 +13,12 @@ export const meta = {
} as const; } as const;
export const paramDef = { export const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
},
required: ['userId'],
} as const; } as const;
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
@Injectable() @Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { export default class extends Endpoint<'admin/unsuspend-user'> {
name = 'admin/unsuspend-user' as const;
constructor( constructor(
@Inject(DI.usersRepository) @Inject(DI.usersRepository)
private usersRepository: UsersRepository, private usersRepository: UsersRepository,
@ -30,7 +26,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private userSuspendService: UserSuspendService, private userSuspendService: UserSuspendService,
private moderationLogService: ModerationLogService, private moderationLogService: ModerationLogService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(async (ps, me) => {
const user = await this.usersRepository.findOneBy({ id: ps.userId }); const user = await this.usersRepository.findOneBy({ id: ps.userId });
if (user == null) { if (user == null) {

View File

@ -6,103 +6,10 @@ import { Endpoint } from '@/server/api/endpoint-base.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { MetaService } from '@/core/MetaService.js'; import { MetaService } from '@/core/MetaService.js';
export const meta = {
tags: ['admin'],
requireCredential: true,
requireAdmin: true,
} as const;
export const paramDef = {
type: 'object',
properties: {
disableRegistration: { type: 'boolean', nullable: true },
pinnedUsers: { type: 'array', nullable: true, items: {
type: 'string',
} },
hiddenTags: { type: 'array', nullable: true, items: {
type: 'string',
} },
blockedHosts: { type: 'array', nullable: true, items: {
type: 'string',
} },
sensitiveWords: { type: 'array', nullable: true, items: {
type: 'string',
} },
themeColor: { type: 'string', nullable: true, pattern: '^#[0-9a-fA-F]{6}$' },
mascotImageUrl: { type: 'string', nullable: true },
bannerUrl: { type: 'string', nullable: true },
errorImageUrl: { type: 'string', nullable: true },
iconUrl: { type: 'string', nullable: true },
backgroundImageUrl: { type: 'string', nullable: true },
logoImageUrl: { type: 'string', nullable: true },
name: { type: 'string', nullable: true },
description: { type: 'string', nullable: true },
defaultLightTheme: { type: 'string', nullable: true },
defaultDarkTheme: { type: 'string', nullable: true },
cacheRemoteFiles: { type: 'boolean' },
emailRequiredForSignup: { type: 'boolean' },
enableHcaptcha: { type: 'boolean' },
hcaptchaSiteKey: { type: 'string', nullable: true },
hcaptchaSecretKey: { type: 'string', nullable: true },
enableRecaptcha: { type: 'boolean' },
recaptchaSiteKey: { type: 'string', nullable: true },
recaptchaSecretKey: { type: 'string', nullable: true },
enableTurnstile: { type: 'boolean' },
turnstileSiteKey: { type: 'string', nullable: true },
turnstileSecretKey: { type: 'string', nullable: true },
sensitiveMediaDetection: { type: 'string', enum: ['none', 'all', 'local', 'remote'] },
sensitiveMediaDetectionSensitivity: { type: 'string', enum: ['medium', 'low', 'high', 'veryLow', 'veryHigh'] },
setSensitiveFlagAutomatically: { type: 'boolean' },
enableSensitiveMediaDetectionForVideos: { type: 'boolean' },
proxyAccountId: { type: 'string', format: 'misskey:id', nullable: true },
maintainerName: { type: 'string', nullable: true },
maintainerEmail: { type: 'string', nullable: true },
langs: { type: 'array', items: {
type: 'string',
} },
summalyProxy: { type: 'string', nullable: true },
deeplAuthKey: { type: 'string', nullable: true },
deeplIsPro: { type: 'boolean' },
enableEmail: { type: 'boolean' },
email: { type: 'string', nullable: true },
smtpSecure: { type: 'boolean' },
smtpHost: { type: 'string', nullable: true },
smtpPort: { type: 'integer', nullable: true },
smtpUser: { type: 'string', nullable: true },
smtpPass: { type: 'string', nullable: true },
enableServiceWorker: { type: 'boolean' },
swPublicKey: { type: 'string', nullable: true },
swPrivateKey: { type: 'string', nullable: true },
tosUrl: { type: 'string', nullable: true },
repositoryUrl: { type: 'string' },
feedbackUrl: { type: 'string' },
useObjectStorage: { type: 'boolean' },
objectStorageBaseUrl: { type: 'string', nullable: true },
objectStorageBucket: { type: 'string', nullable: true },
objectStoragePrefix: { type: 'string', nullable: true },
objectStorageEndpoint: { type: 'string', nullable: true },
objectStorageRegion: { type: 'string', nullable: true },
objectStoragePort: { type: 'integer', nullable: true },
objectStorageAccessKey: { type: 'string', nullable: true },
objectStorageSecretKey: { type: 'string', nullable: true },
objectStorageUseSSL: { type: 'boolean' },
objectStorageUseProxy: { type: 'boolean' },
objectStorageSetPublicRead: { type: 'boolean' },
objectStorageS3ForcePathStyle: { type: 'boolean' },
enableIpLogging: { type: 'boolean' },
enableActiveEmailValidation: { type: 'boolean' },
enableChartsForRemoteUser: { type: 'boolean' },
enableChartsForFederatedInstances: { type: 'boolean' },
serverRules: { type: 'array', items: { type: 'string' } },
preservedUsernames: { type: 'array', items: { type: 'string' } },
},
required: [],
} as const;
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
@Injectable() @Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { export default class extends Endpoint<'admin/update-meta'> {
name = 'admin/update-meta' as const;
constructor( constructor(
@Inject(DI.db) @Inject(DI.db)
private db: DataSource, private db: DataSource,
@ -110,7 +17,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private metaService: MetaService, private metaService: MetaService,
private moderationLogService: ModerationLogService, private moderationLogService: ModerationLogService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(async (ps, me) => {
const set = {} as Partial<Meta>; const set = {} as Partial<Meta>;
if (typeof ps.disableRegistration === 'boolean') { if (typeof ps.disableRegistration === 'boolean') {

View File

@ -3,25 +3,10 @@ import type { UserProfilesRepository, UsersRepository } from '@/models/index.js'
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['admin'],
requireCredential: true,
requireModerator: true,
} as const;
export const paramDef = {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
text: { type: 'string' },
},
required: ['userId', 'text'],
} as const;
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
@Injectable() @Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { export default class extends Endpoint<'admin/update-user-note'> {
name = 'admin/update-user-note' as const;
constructor( constructor(
@Inject(DI.usersRepository) @Inject(DI.usersRepository)
private usersRepository: UsersRepository, private usersRepository: UsersRepository,
@ -29,7 +14,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
@Inject(DI.userProfilesRepository) @Inject(DI.userProfilesRepository)
private userProfilesRepository: UserProfilesRepository, private userProfilesRepository: UserProfilesRepository,
) { ) {
super(meta, paramDef, async (ps, me) => { super(async (ps, me) => {
const user = await this.usersRepository.findOneBy({ id: ps.userId }); const user = await this.usersRepository.findOneBy({ id: ps.userId });
if (user == null) { if (user == null) {

View File

@ -1588,7 +1588,7 @@ export const endpoints = {
properties: { properties: {
reportId: { type: 'string', format: 'misskey:id' }, reportId: { type: 'string', format: 'misskey:id' },
forward: { type: 'boolean', default: false }, forward: { type: 'boolean', default: false },
} satisfies Record<string, JSONSchema7>, } as const satisfies Record<string, JSONSchema7>,
required: ['reportId'], required: ['reportId'],
}, },
res: undefined, res: undefined,
@ -1616,9 +1616,9 @@ export const endpoints = {
'admin/server-info': { 'admin/server-info': {
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
tags: ['admin', 'meta'], tags: ['admin', 'meta'],
defines: [{ defines: [{
req: undefined, req: undefined,
res: { res: {
@ -1628,7 +1628,7 @@ export const endpoints = {
}, },
'admin/show-moderation-logs': { 'admin/show-moderation-logs': {
tags: ['admin'], tags: ['admin'],
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
@ -1639,7 +1639,7 @@ export const endpoints = {
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 }, limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
sinceId: { type: 'string', format: 'misskey:id' }, sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' }, untilId: { type: 'string', format: 'misskey:id' },
} satisfies Record<string, JSONSchema7>, } as const satisfies Record<string, JSONSchema7>,
required: [], required: [],
}, },
res: { res: {
@ -1652,10 +1652,10 @@ export const endpoints = {
}, },
'admin/show-user': { 'admin/show-user': {
tags: ['admin'], tags: ['admin'],
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
defines: [{ defines: [{
req: { req: {
type: 'object', type: 'object',
@ -1725,7 +1725,7 @@ export const endpoints = {
$ref: 'https://misskey-hub.net/api/schemas/Role', $ref: 'https://misskey-hub.net/api/schemas/Role',
} }
}, },
} satisfies Record<string, JSONSchema7>, } as const satisfies Record<string, JSONSchema7>,
required: [ required: [
'email', 'email',
'emailVerified', 'emailVerified',
@ -1754,7 +1754,7 @@ export const endpoints = {
}, },
'admin/show-users': { 'admin/show-users': {
tags: ['admin'], tags: ['admin'],
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
@ -1773,7 +1773,7 @@ export const endpoints = {
default: null, default: null,
description: 'The local host is represented with `null`.', description: 'The local host is represented with `null`.',
}, },
} satisfies Record<string, JSONSchema7>, } as const satisfies Record<string, JSONSchema7>,
required: [], required: [],
}, },
res: { res: {
@ -1781,7 +1781,188 @@ export const endpoints = {
items: { items: {
$ref: 'https://misskey-hub.net/api/schemas/UserDetailed', $ref: 'https://misskey-hub.net/api/schemas/UserDetailed',
}, },
} },
}],
},
'admin/suspend-user': {
tags: ['admin'],
requireCredential: true,
requireModerator: true,
defines: [{
req: {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
},
required: ['userId'],
},
res: undefined,
}],
},
'admin/unsuspend-user': {
tags: ['admin'],
requireCredential: true,
requireModerator: true,
defines: [{
req: {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
},
required: ['userId'],
},
res: undefined,
}],
},
'admin/update-meta': {
tags: ['admin'],
requireCredential: true,
requireAdmin: true,
defines: [{
req: {
type: 'object',
properties: {
disableRegistration: { type: ['boolean', 'null'] },
pinnedUsers: {
oneOf: [{
type: 'array',
items: { type: 'string', format: 'misskey:id' },
}, {
type: 'null',
}],
},
hiddenTags: {
oneOf: [{
type: 'array',
items: { type: 'string' },
}, {
type: 'null',
}],
},
blockedHosts: {
oneOf: [{
type: 'array',
items: { type: 'string' },
}, {
type: 'null',
}],
},
sensitiveWords: {
oneOf: [{
type: 'array',
items: { type: 'string' },
}, {
type: 'null',
}],
},
themeColor: {
oneOf: [
{ type: 'string', pattern: '^#[0-9a-fA-F]{6}$' },
{ type: 'null' },
],
},
mascotImageUrl: { type: ['string', 'null'] },
bannerUrl: { type: ['string', 'null'] },
errorImageUrl: { type: ['string', 'null'] },
iconUrl: { type: ['string', 'null'] },
backgroundImageUrl: { type: ['string', 'null'] },
logoImageUrl: { type: ['string', 'null'] },
name: { type: ['string', 'null'] },
description: { type: ['string', 'null'] },
defaultLightTheme: { type: ['string', 'null'] },
defaultDarkTheme: { type: ['string', 'null'] },
cacheRemoteFiles: { type: 'boolean' },
emailRequiredForSignup: { type: 'boolean' },
enableHcaptcha: { type: 'boolean' },
hcaptchaSiteKey: { type: ['string', 'null'] },
hcaptchaSecretKey: { type: ['string', 'null'] },
enableRecaptcha: { type: 'boolean' },
recaptchaSiteKey: { type: ['string', 'null'] },
recaptchaSecretKey: { type: ['string', 'null'] },
enableTurnstile: { type: 'boolean' },
turnstileSiteKey: { type: ['string', 'null'] },
turnstileSecretKey: { type: ['string', 'null'] },
sensitiveMediaDetection: { enum: ['none', 'all', 'local', 'remote'] },
sensitiveMediaDetectionSensitivity: { enum: ['medium', 'low', 'high', 'veryLow', 'veryHigh'] },
setSensitiveFlagAutomatically: { type: 'boolean' },
enableSensitiveMediaDetectionForVideos: { type: 'boolean' },
proxyAccountId: {
oneOf: [
{ type: 'string', format: 'misskey:id' },
{ type: 'null' },
],
},
maintainerName: { type: ['string', 'null'] },
maintainerEmail: { type: ['string', 'null'] },
langs: {
type: 'array',
items: {
type: 'string',
},
},
summalyProxy: { type: ['string', 'null'] },
deeplAuthKey: { type: ['string', 'null'] },
deeplIsPro: { type: 'boolean' },
enableEmail: { type: 'boolean' },
email: { type: ['string', 'null'] },
smtpSecure: { type: 'boolean' },
smtpHost: { type: ['string', 'null'] },
smtpPort: { type: ['integer', 'null'] },
smtpUser: { type: ['string', 'null'] },
smtpPass: { type: ['string', 'null'] },
enableServiceWorker: { type: 'boolean' },
swPublicKey: { type: ['string', 'null'] },
swPrivateKey: { type: ['string', 'null'] },
tosUrl: { type: ['string', 'null'] },
repositoryUrl: { type: 'string' },
feedbackUrl: { type: 'string' },
useObjectStorage: { type: 'boolean' },
objectStorageBaseUrl: { type: ['string', 'null'] },
objectStorageBucket: { type: ['string', 'null'] },
objectStoragePrefix: { type: ['string', 'null'] },
objectStorageEndpoint: { type: ['string', 'null'] },
objectStorageRegion: { type: ['string', 'null'] },
objectStoragePort: { type: ['integer', 'null'] },
objectStorageAccessKey: { type: ['string', 'null'] },
objectStorageSecretKey: { type: ['string', 'null'] },
objectStorageUseSSL: { type: 'boolean' },
objectStorageUseProxy: { type: 'boolean' },
objectStorageSetPublicRead: { type: 'boolean' },
objectStorageS3ForcePathStyle: { type: 'boolean' },
enableIpLogging: { type: 'boolean' },
enableActiveEmailValidation: { type: 'boolean' },
enableChartsForRemoteUser: { type: 'boolean' },
enableChartsForFederatedInstances: { type: 'boolean' },
serverRules: { type: 'array', items: { type: 'string' } },
preservedUsernames: { type: 'array', items: { type: 'string' } },
} as const satisfies Record<string, JSONSchema7>,
required: [],
},
res: undefined,
}],
},
'admin/update-user-note': {
tags: ['admin'],
requireCredential: true,
requireModerator: true,
defines: [{
req: {
type: 'object',
properties: {
userId: { type: 'string', format: 'misskey:id' },
text: { type: 'string' },
},
required: ['userId', 'text'],
},
res: undefined,
}], }],
} }
} as const satisfies { [x: string]: IEndpointMeta; }; } as const satisfies { [x: string]: IEndpointMeta; };