merge: upstream

This commit is contained in:
Marie 2023-12-23 02:09:23 +01:00
commit 5db583a3eb
701 changed files with 50809 additions and 13660 deletions

View file

@ -13,6 +13,8 @@ import { AbuseUserReportEntityService } from '@/core/entities/AbuseUserReportEnt
export const meta = {
tags: ['admin'],
kind: 'read:admin',
requireCredential: true,
requireModerator: true,

View file

@ -15,6 +15,8 @@ import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
res: {
type: 'object',
optional: false, nullable: false,

View file

@ -14,6 +14,8 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireAdmin: true,
} as const;

View file

@ -13,6 +13,8 @@ import { ApiError } from '@/server/api/error.js';
export const meta = {
tags: ['admin'],
kind: 'read:admin',
requireCredential: true,
requireAdmin: true,
@ -23,6 +25,11 @@ export const meta = {
id: 'cb865949-8af5-4062-a88c-ef55e8786d1d',
},
},
res: {
type: 'object',
optional: false, nullable: false,
ref: 'User',
},
} as const;
export const paramDef = {

View file

@ -13,8 +13,16 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,
res: {
type: 'object',
optional: false,
nullable: false,
ref: 'Ad',
},
} as const;
export const paramDef = {
@ -61,7 +69,18 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
ad: ad,
});
return ad;
return {
id: ad.id,
expiresAt: ad.expiresAt.toISOString(),
startsAt: ad.startsAt.toISOString(),
dayOfWeek: ad.dayOfWeek,
url: ad.url,
imageUrl: ad.imageUrl,
priority: ad.priority,
ratio: ad.ratio,
place: ad.place,
memo: ad.memo,
};
});
}
}

View file

@ -13,6 +13,8 @@ import { ApiError } from '../../../error.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,

View file

@ -12,8 +12,21 @@ import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['admin'],
kind: 'read:admin',
requireCredential: true,
requireModerator: true,
res: {
type: 'array',
optional: false,
nullable: false,
items: {
type: 'object',
optional: false,
nullable: false,
ref: 'Ad',
},
},
} as const;
export const paramDef = {
@ -22,7 +35,7 @@ export const paramDef = {
limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' },
publishing: { type: 'boolean', default: false },
publishing: { type: 'boolean', default: null, nullable: true },
},
required: [],
} as const;
@ -37,12 +50,25 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
) {
super(meta, paramDef, async (ps, me) => {
const query = this.queryService.makePaginationQuery(this.adsRepository.createQueryBuilder('ad'), ps.sinceId, ps.untilId);
if (ps.publishing) {
if (ps.publishing === true) {
query.andWhere('ad.expiresAt > :now', { now: new Date() }).andWhere('ad.startsAt <= :now', { now: new Date() });
} else if (ps.publishing === false) {
query.andWhere('ad.expiresAt <= :now', { now: new Date() }).orWhere('ad.startsAt > :now', { now: new Date() });
}
const ads = await query.limit(ps.limit).getMany();
return ads;
return ads.map(ad => ({
id: ad.id,
expiresAt: ad.expiresAt.toISOString(),
startsAt: ad.startsAt.toISOString(),
dayOfWeek: ad.dayOfWeek,
url: ad.url,
imageUrl: ad.imageUrl,
memo: ad.memo,
place: ad.place,
priority: ad.priority,
ratio: ad.ratio,
}));
});
}
}

View file

@ -13,6 +13,8 @@ import { ApiError } from '../../../error.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,

View file

@ -10,6 +10,8 @@ import { AnnouncementService } from '@/core/AnnouncementService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,

View file

@ -13,6 +13,8 @@ import { ApiError } from '../../../error.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,

View file

@ -14,6 +14,8 @@ import { IdService } from '@/core/IdService.js';
export const meta = {
tags: ['admin'],
kind: 'read:admin',
requireCredential: true,
requireModerator: true,

View file

@ -13,6 +13,8 @@ import { ApiError } from '../../../error.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,

View file

@ -10,6 +10,8 @@ import { AvatarDecorationService } from '@/core/AvatarDecorationService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireRolePolicy: 'canManageAvatarDecorations',
} as const;

View file

@ -12,6 +12,8 @@ import { ApiError } from '../../../error.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireRolePolicy: 'canManageAvatarDecorations',
errors: {

View file

@ -15,6 +15,8 @@ import { AvatarDecorationService } from '@/core/AvatarDecorationService.js';
export const meta = {
tags: ['admin'],
kind: 'read:admin',
requireCredential: true,
requireRolePolicy: 'canManageAvatarDecorations',

View file

@ -12,6 +12,8 @@ import { ApiError } from '../../../error.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireRolePolicy: 'canManageAvatarDecorations',

View file

@ -12,6 +12,8 @@ import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireAdmin: true,

View file

@ -12,6 +12,8 @@ import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireAdmin: true,
} as const;

View file

@ -10,6 +10,8 @@ import { QueueService } from '@/core/QueueService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,
} as const;

View file

@ -13,6 +13,8 @@ import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,
} as const;

View file

@ -13,6 +13,8 @@ import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.j
export const meta = {
tags: ['admin'],
kind: 'read:admin',
requireCredential: true,
requireModerator: true,

View file

@ -14,6 +14,8 @@ import { ApiError } from '../../../error.js';
export const meta = {
tags: ['admin'],
kind: 'read:admin',
requireCredential: true,
requireModerator: true,

View file

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis',
} as const;

View file

@ -14,6 +14,8 @@ import { ApiError } from '../../../error.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis',
@ -29,6 +31,8 @@ export const meta = {
id: 'f7a3462c-4e6e-4069-8421-b9bd4f4c3975',
},
},
ref: 'EmojiDetailed',
} as const;
export const paramDef = {

View file

@ -7,17 +7,18 @@ import { Inject, Injectable } from '@nestjs/common';
import { IsNull } from 'typeorm';
import { Endpoint } from '@/server/api/endpoint-base.js';
import type { EmojisRepository } from '@/models/_.js';
import { IdService } from '@/core/IdService.js';
import type { MiDriveFile } from '@/models/DriveFile.js';
import { DI } from '@/di-symbols.js';
import { DriveService } from '@/core/DriveService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
import { ApiError } from '../../../error.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis',
@ -62,50 +63,43 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
constructor(
@Inject(DI.emojisRepository)
private emojisRepository: EmojisRepository,
private emojiEntityService: EmojiEntityService,
private idService: IdService,
private globalEventService: GlobalEventService,
private customEmojiService: CustomEmojiService,
private driveService: DriveService,
) {
super(meta, paramDef, async (ps, me) => {
const emoji = await this.emojisRepository.findOneBy({ id: ps.emojiId });
if (emoji == null) {
throw new ApiError(meta.errors.noSuchEmoji);
}
const isDuplicate = await this.emojisRepository.findOneBy({ name: emoji.name, host: IsNull() } );
if (isDuplicate) throw new ApiError(meta.errors.duplicateName);
let driveFile: MiDriveFile;
try {
// Create file
driveFile = await this.driveService.uploadFromUrl({ url: emoji.originalUrl, user: null, force: true });
} catch (e) {
// TODO: need to return Drive Error
throw new ApiError();
}
const copied = await this.emojisRepository.insert({
id: this.idService.gen(),
updatedAt: new Date(),
// Duplication Check
const isDuplicate = await this.customEmojiService.checkDuplicate(emoji.name);
if (isDuplicate) throw new ApiError(meta.errors.duplicateName);
const addedEmoji = await this.customEmojiService.add({
driveFile,
name: emoji.name,
category: emoji.category,
aliases: emoji.aliases,
host: null,
aliases: [],
originalUrl: driveFile.url,
publicUrl: driveFile.webpublicUrl ?? driveFile.url,
type: driveFile.webpublicType ?? driveFile.type,
license: emoji.license,
}).then(x => this.emojisRepository.findOneByOrFail(x.identifiers[0]));
isSensitive: emoji.isSensitive,
localOnly: emoji.localOnly,
roleIdsThatCanBeUsedThisEmojiAsReaction: emoji.roleIdsThatCanBeUsedThisEmojiAsReaction,
}, me);
this.globalEventService.publishBroadcastStream('emojiAdded', {
emoji: await this.emojiEntityService.packDetailed(copied.id),
});
return {
id: copied.id,
};
return this.emojiEntityService.packDetailed(addedEmoji);
});
}
}

View file

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis',
} as const;

View file

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis',

View file

@ -8,7 +8,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js';
import { QueueService } from '@/core/QueueService.js';
export const meta = {
secure: true,
kind: 'write:admin',
requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis',
} as const;

View file

@ -15,6 +15,8 @@ import { sqlLikeEscape } from '@/misc/sql-like-escape.js';
export const meta = {
tags: ['admin'],
kind: 'read:admin',
requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis',

View file

@ -15,6 +15,8 @@ import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
export const meta = {
tags: ['admin'],
kind: 'read:admin',
requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis',

View file

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis',
} as const;

View file

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis',
} as const;

View file

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis',
} as const;

View file

@ -10,6 +10,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis',
} as const;

View file

@ -13,6 +13,8 @@ import { ApiError } from '../../../error.js';
export const meta = {
tags: ['admin'],
kind: 'read:admin',
requireCredential: true,
requireRolePolicy: 'canManageCustomEmojis',

View file

@ -12,6 +12,8 @@ import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,
} as const;

View file

@ -13,6 +13,8 @@ import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,
} as const;

View file

@ -12,6 +12,8 @@ import { QueueService } from '@/core/QueueService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,
} as const;

View file

@ -14,6 +14,8 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,
} as const;

View file

@ -12,7 +12,19 @@ export const meta = {
requireCredential: true,
requireAdmin: true,
kind: 'read:admin',
tags: ['admin'],
res: {
type: 'array',
items: {
type: 'object',
properties: {
tablename: { type: 'string' },
indexname: { type: 'string' },
},
},
},
} as const;
export const paramDef = {

View file

@ -12,6 +12,8 @@ export const meta = {
requireCredential: true,
requireAdmin: true,
kind: 'read:admin',
tags: ['admin'],
res: {

View file

@ -12,8 +12,29 @@ import { IdService } from '@/core/IdService.js';
export const meta = {
tags: ['admin'],
kind: 'read:admin',
requireCredential: true,
requireModerator: true,
res: {
type: 'array',
optional: false,
nullable: false,
items: {
type: 'object',
optional: false,
nullable: false,
properties: {
ip: { type: 'string' },
createdAt: {
type: 'string',
optional: false,
nullable: false,
format: 'date-time',
},
},
},
}
} as const;
export const paramDef = {

View file

@ -16,6 +16,8 @@ import { ApiError } from '../../../error.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,
@ -33,13 +35,7 @@ export const meta = {
items: {
type: 'object',
optional: false, nullable: false,
properties: {
code: {
type: 'string',
optional: false, nullable: false,
example: 'GR6S02ERUA5VR',
},
},
ref: 'InviteCode',
},
},
} as const;

View file

@ -12,6 +12,8 @@ import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,
@ -21,6 +23,7 @@ export const meta = {
items: {
type: 'object',
optional: false, nullable: false,
ref: 'InviteCode',
},
},
} as const;

View file

@ -13,6 +13,8 @@ import { DEFAULT_POLICIES } from '@/core/RoleService.js';
export const meta = {
tags: ['meta'],
kind: 'read:admin',
requireCredential: true,
requireAdmin: true,
@ -282,6 +284,14 @@ export const meta = {
type: 'boolean',
optional: false, nullable: false,
},
enableVerifymailApi: {
type: 'boolean',
optional: false, nullable: false,
},
verifymailAuthKey: {
type: 'string',
optional: false, nullable: true,
},
enableChartsForRemoteUser: {
type: 'boolean',
optional: false, nullable: false,
@ -338,6 +348,82 @@ export const meta = {
type: 'number',
optional: false, nullable: false,
},
backgroundImageUrl: {
type: 'string',
optional: false, nullable: true,
},
deeplAuthKey: {
type: 'string',
optional: false, nullable: true,
},
deeplIsPro: {
type: 'boolean',
optional: false, nullable: false,
},
defaultDarkTheme: {
type: 'string',
optional: false, nullable: true,
},
defaultLightTheme: {
type: 'string',
optional: false, nullable: true,
},
description: {
type: 'string',
optional: false, nullable: true,
},
disableRegistration: {
type: 'boolean',
optional: false, nullable: false,
},
impressumUrl: {
type: 'string',
optional: false, nullable: true,
},
maintainerEmail: {
type: 'string',
optional: false, nullable: true,
},
maintainerName: {
type: 'string',
optional: false, nullable: true,
},
name: {
type: 'string',
optional: false, nullable: true,
},
objectStorageS3ForcePathStyle: {
type: 'boolean',
optional: false, nullable: false,
},
privacyPolicyUrl: {
type: 'string',
optional: false, nullable: true,
},
repositoryUrl: {
type: 'string',
optional: false, nullable: false,
},
summalyProxy: {
type: 'string',
optional: false, nullable: true,
},
themeColor: {
type: 'string',
optional: false, nullable: true,
},
tosUrl: {
type: 'string',
optional: false, nullable: true,
},
uri: {
type: 'string',
optional: false, nullable: false,
},
version: {
type: 'string',
optional: false, nullable: false,
},
},
},
} as const;
@ -444,6 +530,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
deeplIsPro: instance.deeplIsPro,
enableIpLogging: instance.enableIpLogging,
enableActiveEmailValidation: instance.enableActiveEmailValidation,
enableVerifymailApi: instance.enableVerifymailApi,
verifymailAuthKey: instance.verifymailAuthKey,
enableChartsForRemoteUser: instance.enableChartsForRemoteUser,
enableChartsForFederatedInstances: instance.enableChartsForFederatedInstances,
enableServerMachineStats: instance.enableServerMachineStats,

View file

@ -13,6 +13,8 @@ import { ApiError } from '../../../error.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,

View file

@ -11,6 +11,8 @@ import { QueueService } from '@/core/QueueService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,
} as const;

View file

@ -11,6 +11,8 @@ import type { DeliverQueue } from '@/core/QueueModule.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,

View file

@ -11,6 +11,8 @@ import type { InboxQueue } from '@/core/QueueModule.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,

View file

@ -11,6 +11,8 @@ import { QueueService } from '@/core/QueueService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,
} as const;

View file

@ -10,6 +10,8 @@ import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, Obj
export const meta = {
tags: ['admin'],
kind: 'read:admin',
requireCredential: true,
requireModerator: true,

View file

@ -12,6 +12,8 @@ import { ApiError } from '../../../error.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,

View file

@ -10,6 +10,8 @@ import { RelayService } from '@/core/RelayService.js';
export const meta = {
tags: ['admin'],
kind: 'read:admin',
requireCredential: true,
requireModerator: true,

View file

@ -10,6 +10,8 @@ import { RelayService } from '@/core/RelayService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,
} as const;

View file

@ -15,6 +15,8 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,

View file

@ -15,6 +15,8 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,
} as const;

View file

@ -13,6 +13,8 @@ import { RoleService } from '@/core/RoleService.js';
export const meta = {
tags: ['admin', 'role'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,

View file

@ -11,8 +11,16 @@ import { RoleService } from '@/core/RoleService.js';
export const meta = {
tags: ['admin', 'role'],
kind: 'write:admin',
requireCredential: true,
requireAdmin: true,
res: {
type: 'object',
optional: false, nullable: false,
ref: 'Role',
},
} as const;
export const paramDef = {

View file

@ -13,6 +13,8 @@ import { RoleService } from '@/core/RoleService.js';
export const meta = {
tags: ['admin', 'role'],
kind: 'write:admin',
requireCredential: true,
requireAdmin: true,

View file

@ -12,8 +12,20 @@ import { RoleEntityService } from '@/core/entities/RoleEntityService.js';
export const meta = {
tags: ['admin', 'role'],
kind: 'read:admin',
requireCredential: true,
requireModerator: true,
res: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'object',
optional: false, nullable: false,
ref: 'Role',
},
},
} as const;
export const paramDef = {

View file

@ -13,6 +13,8 @@ import { RoleEntityService } from '@/core/entities/RoleEntityService.js';
export const meta = {
tags: ['admin', 'role'],
kind: 'read:admin',
requireCredential: true,
requireModerator: true,
@ -23,6 +25,12 @@ export const meta = {
id: '07dc7d34-c0d8-49b7-96c6-db3ce64ee0b3',
},
},
res: {
type: 'object',
optional: false, nullable: false,
ref: 'Role',
},
} as const;
export const paramDef = {

View file

@ -13,6 +13,8 @@ import { RoleService } from '@/core/RoleService.js';
export const meta = {
tags: ['admin', 'role'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,

View file

@ -11,6 +11,8 @@ import { MetaService } from '@/core/MetaService.js';
export const meta = {
tags: ['admin', 'role'],
kind: 'write:admin',
requireCredential: true,
requireAdmin: true,
} as const;

View file

@ -14,6 +14,8 @@ import { RoleService } from '@/core/RoleService.js';
export const meta = {
tags: ['admin', 'role'],
kind: 'write:admin',
requireCredential: true,
requireAdmin: true,

View file

@ -16,6 +16,8 @@ import { ApiError } from '../../../error.js';
export const meta = {
tags: ['admin', 'role', 'users'],
kind: 'read:admin',
requireCredential: false,
requireAdmin: true,
@ -26,6 +28,20 @@ export const meta = {
id: '224eff5e-2488-4b18-b3e7-f50d94421648',
},
},
res: {
type: 'array',
items: {
type: 'object',
properties: {
id: { type: 'string', format: 'misskey:id' },
createdAt: { type: 'string', format: 'date-time' },
user: { ref: 'UserDetailed' },
expiresAt: { type: 'string', format: 'date-time', nullable: true },
},
required: ['id', 'createdAt', 'user'],
},
}
} as const;
export const paramDef = {
@ -78,7 +94,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
id: assign.id,
createdAt: this.idService.parse(assign.id).date.toISOString(),
user: await this.userEntityService.pack(assign.user!, me, { detail: true }),
expiresAt: assign.expiresAt,
expiresAt: assign.expiresAt?.toISOString() ?? null,
})));
});
}

View file

@ -10,6 +10,8 @@ import { EmailService } from '@/core/EmailService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,
} as const;

View file

@ -17,6 +17,8 @@ export const meta = {
tags: ['admin', 'meta'],
kind: 'read:admin',
res: {
type: 'object',
optional: false, nullable: false,

View file

@ -14,7 +14,9 @@ export const meta = {
tags: ['admin'],
requireCredential: true,
requireModerator: true,
requireAdmin: true,
kind: 'read:admin',
res: {
type: 'array',

View file

@ -17,6 +17,8 @@ export const meta = {
requireCredential: true,
requireModerator: true,
kind: 'read:admin',
res: {
type: 'object',
nullable: false, optional: false,

View file

@ -17,6 +17,8 @@ export const meta = {
requireCredential: true,
requireModerator: true,
kind: 'read:admin',
res: {
type: 'array',
nullable: false, optional: false,

View file

@ -19,6 +19,8 @@ import { QueueService } from '@/core/QueueService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,
} as const;

View file

@ -0,0 +1,62 @@
/*
* SPDX-FileCopyrightText: syuilo and other misskey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { Inject, Injectable } from '@nestjs/common';
import type { UsersRepository } from '@/models/_.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { DI } from '@/di-symbols.js';
import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = {
tags: ['admin'],
kind: 'write: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
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
@Inject(DI.usersRepository)
private usersRepository: UsersRepository,
private moderationLogService: ModerationLogService,
) {
super(meta, paramDef, async (ps, me) => {
const user = await this.usersRepository.findOneBy({ id: ps.userId });
if (user == null) {
throw new Error('user not found');
}
if (user.avatarId == null) return;
await this.usersRepository.update(user.id, {
avatar: null,
avatarId: null,
avatarUrl: null,
avatarBlurhash: null,
});
this.moderationLogService.log(me, 'unsetUserAvatar', {
userId: user.id,
userUsername: user.username,
userHost: user.host,
fileId: user.avatarId,
});
});
}
}

View file

@ -0,0 +1,62 @@
/*
* SPDX-FileCopyrightText: syuilo and other misskey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { Inject, Injectable } from '@nestjs/common';
import type { UsersRepository } from '@/models/_.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { DI } from '@/di-symbols.js';
import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = {
tags: ['admin'],
kind: 'write: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
@Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor(
@Inject(DI.usersRepository)
private usersRepository: UsersRepository,
private moderationLogService: ModerationLogService,
) {
super(meta, paramDef, async (ps, me) => {
const user = await this.usersRepository.findOneBy({ id: ps.userId });
if (user == null) {
throw new Error('user not found');
}
if (user.bannerId == null) return;
await this.usersRepository.update(user.id, {
banner: null,
bannerId: null,
bannerUrl: null,
bannerBlurhash: null,
});
this.moderationLogService.log(me, 'unsetUserBanner', {
userId: user.id,
userUsername: user.username,
userHost: user.host,
fileId: user.bannerId,
});
});
}
}

View file

@ -13,6 +13,8 @@ import { DI } from '@/di-symbols.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,
} as const;

View file

@ -12,6 +12,8 @@ import { MetaService } from '@/core/MetaService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireAdmin: true,
} as const;
@ -116,6 +118,8 @@ export const paramDef = {
objectStorageS3ForcePathStyle: { type: 'boolean' },
enableIpLogging: { type: 'boolean' },
enableActiveEmailValidation: { type: 'boolean' },
enableVerifymailApi: { type: 'boolean' },
verifymailAuthKey: { type: 'string', nullable: true },
enableChartsForRemoteUser: { type: 'boolean' },
enableChartsForFederatedInstances: { type: 'boolean' },
enableServerMachineStats: { type: 'boolean' },
@ -455,6 +459,18 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
set.enableActiveEmailValidation = ps.enableActiveEmailValidation;
}
if (ps.enableVerifymailApi !== undefined) {
set.enableVerifymailApi = ps.enableVerifymailApi;
}
if (ps.verifymailAuthKey !== undefined) {
if (ps.verifymailAuthKey === '') {
set.verifymailAuthKey = null;
} else {
set.verifymailAuthKey = ps.verifymailAuthKey;
}
}
if (ps.enableChartsForRemoteUser !== undefined) {
set.enableChartsForRemoteUser = ps.enableChartsForRemoteUser;
}

View file

@ -12,6 +12,8 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
export const meta = {
tags: ['admin'],
kind: 'write:admin',
requireCredential: true,
requireModerator: true,
} as const;