merge upstream
This commit is contained in:
commit
d8908ef2d8
1065 changed files with 32953 additions and 20092 deletions
|
|
@ -5,10 +5,9 @@
|
|||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { UsersRepository } from '@/models/_.js';
|
||||
import type { MiMeta, UsersRepository } from '@/models/_.js';
|
||||
import { SignupService } from '@/core/SignupService.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { InstanceActorService } from '@/core/InstanceActorService.js';
|
||||
import { localUsernameSchema, passwordSchema } from '@/models/User.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import type { Config } from '@/config.js';
|
||||
|
|
@ -90,20 +89,21 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
@Inject(DI.config)
|
||||
private config: Config,
|
||||
|
||||
@Inject(DI.meta)
|
||||
private serverSettings: MiMeta,
|
||||
|
||||
@Inject(DI.usersRepository)
|
||||
private usersRepository: UsersRepository,
|
||||
|
||||
private roleService: RoleService,
|
||||
private userEntityService: UserEntityService,
|
||||
private signupService: SignupService,
|
||||
private instanceActorService: InstanceActorService,
|
||||
private readonly moderationLogService: ModerationLogService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, _me, token) => {
|
||||
const me = _me ? await this.usersRepository.findOneByOrFail({ id: _me.id }) : null;
|
||||
const realUsers = await this.instanceActorService.realLocalUsersPresent();
|
||||
|
||||
if (!realUsers && me == null && token == null) {
|
||||
if (this.serverSettings.rootUserId == null && me == null && token == null) {
|
||||
// 初回セットアップの場合
|
||||
if (this.config.setupPassword != null) {
|
||||
// 初期パスワードが設定されている場合
|
||||
|
|
@ -127,7 +127,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
}
|
||||
|
||||
// Anonymous access is only allowed for initial instance setup (this check may be redundant)
|
||||
if (!me && realUsers) {
|
||||
if (!me && this.serverSettings.rootUserId != null) {
|
||||
throw new ApiError(meta.errors.noCredential);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,10 +42,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
throw new Error('user not found');
|
||||
}
|
||||
|
||||
if (user.isRoot) {
|
||||
throw new Error('cannot delete a root account');
|
||||
}
|
||||
|
||||
await this.deleteAccoountService.deleteAccount(user, me);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export const meta = {
|
|||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageAvatarDecorations',
|
||||
requiredRolePolicy: 'canManageAvatarDecorations',
|
||||
kind: 'write:admin:avatar-decorations',
|
||||
|
||||
res: {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export const meta = {
|
|||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageAvatarDecorations',
|
||||
requiredRolePolicy: 'canManageAvatarDecorations',
|
||||
kind: 'write:admin:avatar-decorations',
|
||||
errors: {
|
||||
},
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export const meta = {
|
|||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageAvatarDecorations',
|
||||
requiredRolePolicy: 'canManageAvatarDecorations',
|
||||
kind: 'read:admin:avatar-decorations',
|
||||
|
||||
res: {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export const meta = {
|
|||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageAvatarDecorations',
|
||||
requiredRolePolicy: 'canManageAvatarDecorations',
|
||||
kind: 'write:admin:avatar-decorations',
|
||||
|
||||
errors: {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export const meta = {
|
|||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
requiredRolePolicy: 'canManageCustomEmojis',
|
||||
kind: 'write:admin:emoji',
|
||||
} as const;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export const meta = {
|
|||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
requiredRolePolicy: 'canManageCustomEmojis',
|
||||
kind: 'write:admin:emoji',
|
||||
|
||||
errors: {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ export const meta = {
|
|||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
requiredRolePolicy: 'canManageCustomEmojis',
|
||||
kind: 'write:admin:emoji',
|
||||
|
||||
errors: {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export const meta = {
|
|||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
requiredRolePolicy: 'canManageCustomEmojis',
|
||||
kind: 'write:admin:emoji',
|
||||
} as const;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export const meta = {
|
|||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
requiredRolePolicy: 'canManageCustomEmojis',
|
||||
kind: 'write:admin:emoji',
|
||||
|
||||
errors: {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { DI } from '@/di-symbols.js';
|
|||
export const meta = {
|
||||
secure: true,
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
requiredRolePolicy: 'canManageCustomEmojis',
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export const meta = {
|
|||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
requiredRolePolicy: 'canManageCustomEmojis',
|
||||
kind: 'read:admin:emoji',
|
||||
|
||||
res: {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export const meta = {
|
|||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
requiredRolePolicy: 'canManageCustomEmojis',
|
||||
kind: 'read:admin:emoji',
|
||||
|
||||
res: {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export const meta = {
|
|||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
requiredRolePolicy: 'canManageCustomEmojis',
|
||||
kind: 'write:admin:emoji',
|
||||
} as const;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export const meta = {
|
|||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
requiredRolePolicy: 'canManageCustomEmojis',
|
||||
kind: 'write:admin:emoji',
|
||||
} as const;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export const meta = {
|
|||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
requiredRolePolicy: 'canManageCustomEmojis',
|
||||
kind: 'write:admin:emoji',
|
||||
} as const;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export const meta = {
|
|||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
requiredRolePolicy: 'canManageCustomEmojis',
|
||||
kind: 'write:admin:emoji',
|
||||
} as const;
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export const meta = {
|
|||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireRolePolicy: 'canManageCustomEmojis',
|
||||
requiredRolePolicy: 'canManageCustomEmojis',
|
||||
kind: 'write:admin:emoji',
|
||||
|
||||
errors: {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import type { Config } from '@/config.js';
|
|||
import { DI } from '@/di-symbols.js';
|
||||
import { DEFAULT_POLICIES } from '@/core/RoleService.js';
|
||||
import { instanceUnsignedFetchOptions } from '@/const.js';
|
||||
import { SystemAccountService } from '@/core/SystemAccountService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['meta'],
|
||||
|
|
@ -86,6 +87,10 @@ export const meta = {
|
|||
type: 'boolean',
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
googleAnalyticsMeasurementId: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
swPublickey: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
|
|
@ -265,7 +270,7 @@ export const meta = {
|
|||
},
|
||||
proxyAccountId: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
optional: false, nullable: false,
|
||||
format: 'id',
|
||||
},
|
||||
email: {
|
||||
|
|
@ -580,6 +585,7 @@ export const meta = {
|
|||
},
|
||||
federation: {
|
||||
type: 'string',
|
||||
enum: ['all', 'specified', 'none'],
|
||||
optional: false, nullable: false,
|
||||
},
|
||||
federationHosts: {
|
||||
|
|
@ -617,10 +623,13 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
private config: Config,
|
||||
|
||||
private metaService: MetaService,
|
||||
private systemAccountService: SystemAccountService,
|
||||
) {
|
||||
super(meta, paramDef, async () => {
|
||||
const instance = await this.metaService.fetch(true);
|
||||
|
||||
const proxy = await this.systemAccountService.fetch('proxy');
|
||||
|
||||
return {
|
||||
maintainerName: instance.maintainerName,
|
||||
maintainerEmail: instance.maintainerEmail,
|
||||
|
|
@ -652,6 +661,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
enableFC: instance.enableFC,
|
||||
fcSiteKey: instance.fcSiteKey,
|
||||
enableTestcaptcha: instance.enableTestcaptcha,
|
||||
googleAnalyticsMeasurementId: instance.googleAnalyticsMeasurementId,
|
||||
swPublickey: instance.swPublicKey,
|
||||
themeColor: instance.themeColor,
|
||||
mascotImageUrl: instance.mascotImageUrl,
|
||||
|
|
@ -693,7 +703,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
setSensitiveFlagAutomatically: instance.setSensitiveFlagAutomatically,
|
||||
enableSensitiveMediaDetectionForVideos: instance.enableSensitiveMediaDetectionForVideos,
|
||||
enableBotTrending: instance.enableBotTrending,
|
||||
proxyAccountId: instance.proxyAccountId,
|
||||
proxyAccountId: proxy.id,
|
||||
email: instance.email,
|
||||
smtpSecure: instance.smtpSecure,
|
||||
smtpHost: instance.smtpHost,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
//import bcrypt from 'bcryptjs';
|
||||
import * as argon2 from 'argon2';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { UsersRepository, UserProfilesRepository } from '@/models/_.js';
|
||||
import type { UsersRepository, UserProfilesRepository, MiMeta } from '@/models/_.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { secureRndstr } from '@/misc/secure-rndstr.js';
|
||||
import { ModerationLogService } from '@/core/ModerationLogService.js';
|
||||
|
|
@ -45,6 +45,9 @@ export const paramDef = {
|
|||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.meta)
|
||||
private serverSettings: MiMeta,
|
||||
|
||||
@Inject(DI.usersRepository)
|
||||
private usersRepository: UsersRepository,
|
||||
|
||||
|
|
@ -60,7 +63,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
throw new Error('user not found');
|
||||
}
|
||||
|
||||
if (user.isRoot) {
|
||||
if (this.serverSettings.rootUserId === user.id) {
|
||||
throw new Error('cannot reset password of root');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -91,12 +91,12 @@ export const paramDef = {
|
|||
fcSiteKey: { type: 'string', nullable: true },
|
||||
fcSecretKey: { type: 'string', nullable: true },
|
||||
enableTestcaptcha: { type: 'boolean' },
|
||||
googleAnalyticsMeasurementId: { 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' },
|
||||
enableBotTrending: { type: 'boolean' },
|
||||
proxyAccountId: { type: 'string', format: 'misskey:id', nullable: true },
|
||||
maintainerName: { type: 'string', nullable: true },
|
||||
maintainerEmail: { type: 'string', nullable: true },
|
||||
langs: {
|
||||
|
|
@ -130,7 +130,7 @@ export const paramDef = {
|
|||
useObjectStorage: { type: 'boolean' },
|
||||
objectStorageBaseUrl: { type: 'string', nullable: true },
|
||||
objectStorageBucket: { type: 'string', nullable: true },
|
||||
objectStoragePrefix: { type: 'string', nullable: true },
|
||||
objectStoragePrefix: { type: 'string', pattern: /^[a-zA-Z0-9-._]*$/.source, nullable: true },
|
||||
objectStorageEndpoint: { type: 'string', nullable: true },
|
||||
objectStorageRegion: { type: 'string', nullable: true },
|
||||
objectStoragePort: { type: 'integer', nullable: true },
|
||||
|
|
@ -413,6 +413,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
set.enableTestcaptcha = ps.enableTestcaptcha;
|
||||
}
|
||||
|
||||
if (ps.googleAnalyticsMeasurementId !== undefined) {
|
||||
// 空文字列をnullにしたいので??は使わない
|
||||
set.googleAnalyticsMeasurementId = ps.googleAnalyticsMeasurementId || null;
|
||||
}
|
||||
|
||||
if (ps.fcSiteKey !== undefined) {
|
||||
set.fcSiteKey = ps.fcSiteKey;
|
||||
}
|
||||
|
|
@ -425,10 +430,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
set.enableBotTrending = ps.enableBotTrending;
|
||||
}
|
||||
|
||||
if (ps.proxyAccountId !== undefined) {
|
||||
set.proxyAccountId = ps.proxyAccountId;
|
||||
}
|
||||
|
||||
if (ps.maintainerName !== undefined) {
|
||||
set.maintainerName = ps.maintainerName;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import {
|
||||
descriptionSchema,
|
||||
} from '@/models/User.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { ModerationLogService } from '@/core/ModerationLogService.js';
|
||||
import { SystemAccountService } from '@/core/SystemAccountService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
kind: 'write:admin:account',
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
nullable: false, optional: false,
|
||||
ref: 'UserDetailed',
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
description: { ...descriptionSchema, nullable: true },
|
||||
},
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
private userEntityService: UserEntityService,
|
||||
private moderationLogService: ModerationLogService,
|
||||
private systemAccountService: SystemAccountService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const proxy = await this.systemAccountService.updateCorrespondingUserProfile('proxy', {
|
||||
description: ps.description,
|
||||
});
|
||||
|
||||
const updated = await this.userEntityService.pack(proxy.id, proxy, {
|
||||
schema: 'MeDetailed',
|
||||
});
|
||||
|
||||
if (ps.description !== undefined) {
|
||||
this.moderationLogService.log(me, 'updateProxyAccountDescription', {
|
||||
before: null, //TODO
|
||||
after: ps.description,
|
||||
});
|
||||
}
|
||||
|
||||
return updated;
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue