Skip to content

Commit e16f251

Browse files
authored
Merge branch 'neko-feat/user-approve' into update-neko/2024.11.0
2 parents ac45775 + a95ab97 commit e16f251

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+803
-50
lines changed

Changelog-neko.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
## Unreleased
1+
## Unreleased (2024.9.0+neko.rc-2)
22

33
### General
4+
- Feat: 사용자 등록을 승인제로 할 수 있도록
5+
(pull from 0e2e4c353f6d2fd2cc650007ec2f6a876acde8f7)
46

57
### Frontend
68

locales/index.d.ts

+72
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ export interface Locale extends ILocale {
166166
* ユーザー
167167
*/
168168
"users": string;
169+
/**
170+
* 承認
171+
*/
172+
"approvals": string;
169173
/**
170174
* ユーザーを追加
171175
*/
@@ -626,6 +630,14 @@ export interface Locale extends ILocale {
626630
* 凍結しますか?
627631
*/
628632
"suspendConfirm": string;
633+
/**
634+
* 登録を承認しますか?
635+
*/
636+
"registerApproveConfirm": string;
637+
/**
638+
* この操作は取り消せません。承認後、このユーザーに登録が承認された旨が記載されたメールが送信されます。
639+
*/
640+
"registerApproveConfirmDescription": string;
629641
/**
630642
* 解凍しますか?
631643
*/
@@ -3654,6 +3666,14 @@ export interface Locale extends ILocale {
36543666
* アカウント登録にメールアドレスを必須にする
36553667
*/
36563668
"emailRequiredForSignup": string;
3669+
/**
3670+
* アカウント登録を承認制にする
3671+
*/
3672+
"approvalRequiredForSignup": string;
3673+
/**
3674+
* アカウント登録の承認
3675+
*/
3676+
"signupPendingApprovals": string;
36573677
/**
36583678
* 未読
36593679
*/
@@ -3870,6 +3890,10 @@ export interface Locale extends ILocale {
38703890
* 未対応の通報があります。
38713891
*/
38723892
"thereIsUnresolvedAbuseReportWarning": string;
3893+
/**
3894+
* 承認待ちのユーザーがいます。
3895+
*/
3896+
"pendingUserApprovals": string;
38733897
/**
38743898
* 推奨
38753899
*/
@@ -3902,6 +3926,26 @@ export interface Locale extends ILocale {
39023926
* アカウント削除
39033927
*/
39043928
"deleteAccount": string;
3929+
/**
3930+
* 承認する
3931+
*/
3932+
"approveAccount": string;
3933+
/**
3934+
* 拒否してアカウント削除
3935+
*/
3936+
"denyAccount": string;
3937+
/**
3938+
* 承認済み
3939+
*/
3940+
"approved": string;
3941+
/**
3942+
* 未承認
3943+
*/
3944+
"notApproved": string;
3945+
/**
3946+
* 承認状況
3947+
*/
3948+
"approvalStatus": string;
39053949
/**
39063950
* ドキュメント
39073951
*/
@@ -4270,6 +4314,22 @@ export interface Locale extends ILocale {
42704314
* 現在このサーバーは招待制です。招待コードをお持ちの方のみ登録できます。
42714315
*/
42724316
"invitationRequiredToRegister": string;
4317+
/**
4318+
* 現在このサーバーは承認制です。参加したい理由を記入し、承認された方のみ登録できます。
4319+
*/
4320+
"approvalRequiredToRegister": string;
4321+
/**
4322+
* 登録理由
4323+
*/
4324+
"registerReason": string;
4325+
/**
4326+
* サーバーへの登録はまだ承認されていません。しばらくしてから再度お試しください。登録時にメールアドレスを記入した場合は、登録が承認されたらメールでお知らせします。
4327+
*/
4328+
"registerHasNotBeenApprovedYet": string;
4329+
/**
4330+
* サーバーへの登録が承認されたかどうかの通知を行うために、併せてアカウント登録にメールアドレスを必須にすることを強く推奨します。
4331+
*/
4332+
"registerApprovalEmailRecommended": string;
42734333
/**
42744334
* このサーバーではメール配信はサポートされていません
42754335
*/
@@ -7164,6 +7224,14 @@ export interface Locale extends ILocale {
71647224
* 入力されたメールアドレス({email})宛に確認のメールが送信されました。メールに記載されたリンクにアクセスすると、アカウントの作成が完了します。メールに記載されているリンクの有効期限は30分です。
71657225
*/
71667226
"emailSent": ParameterizedString<"email">;
7227+
/**
7228+
* アカウントが作成され、承認待ちの状態です。
7229+
*/
7230+
"approvalPending": string;
7231+
/**
7232+
* このサーバーに参加したい理由を入力してください。
7233+
*/
7234+
"reasonInfo": string;
71677235
};
71687236
"_accountDelete": {
71697237
/**
@@ -9850,6 +9918,10 @@ export interface Locale extends ILocale {
98509918
* ロールのアサイン解除
98519919
*/
98529920
"unassignRole": string;
9921+
/**
9922+
* 承認済み
9923+
*/
9924+
"approve": string;
98539925
/**
98549926
* 凍結
98559927
*/

locales/ja-JP.yml

+18
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ signup: "新規登録"
3737
uploading: "アップロード中"
3838
save: "保存"
3939
users: "ユーザー"
40+
approvals: "承認"
4041
addUser: "ユーザーを追加"
4142
favorite: "お気に入り"
4243
favorites: "お気に入り"
@@ -152,6 +153,8 @@ unsuspend: "解凍"
152153
blockConfirm: "ブロックしますか?"
153154
unblockConfirm: "ブロック解除しますか?"
154155
suspendConfirm: "凍結しますか?"
156+
registerApproveConfirm: "登録を承認しますか?"
157+
registerApproveConfirmDescription: "この操作は取り消せません。承認後、このユーザーに登録が承認された旨が記載されたメールが送信されます。"
155158
unsuspendConfirm: "解凍しますか?"
156159
selectList: "リストを選択"
157160
editList: "リストを編集"
@@ -909,6 +912,8 @@ itsOff: "オフになっています"
909912
on: "オン"
910913
off: "オフ"
911914
emailRequiredForSignup: "アカウント登録にメールアドレスを必須にする"
915+
approvalRequiredForSignup: "アカウント登録を承認制にする"
916+
signupPendingApprovals: "アカウント登録の承認"
912917
unread: "未読"
913918
filter: "フィルタ"
914919
controlPanel: "コントロールパネル"
@@ -963,6 +968,7 @@ recentNHours: "直近{n}時間"
963968
recentNDays: "直近{n}日"
964969
noEmailServerWarning: "メールサーバーの設定がされていません。"
965970
thereIsUnresolvedAbuseReportWarning: "未対応の通報があります。"
971+
pendingUserApprovals: "承認待ちのユーザーがいます。"
966972
recommended: "推奨"
967973
check: "チェック"
968974
driveCapOverrideLabel: "このユーザーのドライブ容量上限を変更"
@@ -971,6 +977,11 @@ requireAdminForView: "閲覧するには管理者アカウントでログイン
971977
isSystemAccount: "システムにより自動で作成・管理されているアカウントです。"
972978
typeToConfirm: "この操作を行うには {x} と入力してください"
973979
deleteAccount: "アカウント削除"
980+
approveAccount: "承認する"
981+
denyAccount: "拒否してアカウント削除"
982+
approved: "承認済み"
983+
notApproved: "未承認"
984+
approvalStatus: "承認状況"
974985
document: "ドキュメント"
975986
numberOfPageCache: "ページキャッシュ数"
976987
numberOfPageCacheDescription: "多くすると利便性が向上しますが、負荷とメモリ使用量が増えます。"
@@ -1063,6 +1074,10 @@ disableFederationConfirm: "連合なしにしますか?"
10631074
disableFederationConfirmWarn: "連合なしにしても投稿は非公開になりません。ほとんどの場合、連合なしにする必要はありません。"
10641075
disableFederationOk: "連合なしにする"
10651076
invitationRequiredToRegister: "現在このサーバーは招待制です。招待コードをお持ちの方のみ登録できます。"
1077+
approvalRequiredToRegister: "現在このサーバーは承認制です。参加したい理由を記入し、承認された方のみ登録できます。"
1078+
registerReason: "登録理由"
1079+
registerHasNotBeenApprovedYet: "サーバーへの登録はまだ承認されていません。しばらくしてから再度お試しください。登録時にメールアドレスを記入した場合は、登録が承認されたらメールでお知らせします。"
1080+
registerApprovalEmailRecommended: "サーバーへの登録が承認されたかどうかの通知を行うために、併せてアカウント登録にメールアドレスを必須にすることを強く推奨します。"
10661081
emailNotSupported: "このサーバーではメール配信はサポートされていません"
10671082
postToTheChannel: "チャンネルに投稿"
10681083
cannotBeChangedLater: "後から変更できません。"
@@ -1856,6 +1871,8 @@ _signup:
18561871
almostThere: "ほとんど完了です"
18571872
emailAddressInfo: "あなたが使っているメールアドレスを入力してください。メールアドレスが公開されることはありません。"
18581873
emailSent: "入力されたメールアドレス({email})宛に確認のメールが送信されました。メールに記載されたリンクにアクセスすると、アカウントの作成が完了します。メールに記載されているリンクの有効期限は30分です。"
1874+
approvalPending: "アカウントが作成され、承認待ちの状態です。"
1875+
reasonInfo: "このサーバーに参加したい理由を入力してください。"
18591876

18601877
_accountDelete:
18611878
accountDelete: "アカウントの削除"
@@ -2612,6 +2629,7 @@ _moderationLogTypes:
26122629
updateRole: "ロールを更新"
26132630
assignRole: "ロールへアサイン"
26142631
unassignRole: "ロールのアサイン解除"
2632+
approve: "承認済み"
26152633
suspend: "凍結"
26162634
unsuspend: "凍結解除"
26172635
addCustomEmoji: "カスタム絵文字追加"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* SPDX-FileCopyrightText: syuilo and other misskey contributors
3+
* SPDX-License-Identifier: AGPL-3.0-only
4+
*/
5+
6+
export class ApprovalSignup1697580470000 {
7+
name = 'ApprovalSignup1697580470000'
8+
9+
async up(queryRunner) {
10+
await queryRunner.query(`ALTER TABLE "meta" ADD "approvalRequiredForSignup" boolean DEFAULT false NOT NULL`);
11+
await queryRunner.query(`ALTER TABLE "user" ADD "approved" boolean DEFAULT false NOT NULL`);
12+
//▼ 既存のユーザーについては全員Approveにする
13+
await queryRunner.query(`UPDATE "user" SET "approved" = true`);
14+
await queryRunner.query(`ALTER TABLE "user" ADD "signupReason" character varying(1000) NULL`);
15+
await queryRunner.query(`ALTER TABLE "user_pending" ADD "reason" character varying(1000) NULL`);
16+
}
17+
18+
async down(queryRunner) {
19+
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "approvalRequiredForSignup"`);
20+
await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "approved"`);
21+
await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "signupReason"`);
22+
await queryRunner.query(`ALTER TABLE "user_pending" DROP COLUMN "reason"`);
23+
}
24+
}

packages/backend/src/config.ts

+5
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ type Source = {
9999
perUserNotificationsMaxCount?: number;
100100
deactivateAntennaThreshold?: number;
101101
pidFile: string;
102+
103+
approvalRequiredForSignup: boolean;
102104
};
103105

104106
export type Config = {
@@ -190,6 +192,8 @@ export type Config = {
190192
perUserNotificationsMaxCount: number;
191193
deactivateAntennaThreshold: number;
192194
pidFile: string;
195+
196+
approvalRequiredForSignup: boolean;
193197
};
194198

195199
const _filename = fileURLToPath(import.meta.url);
@@ -302,6 +306,7 @@ export function loadConfig(): Config {
302306
deactivateAntennaThreshold: config.deactivateAntennaThreshold ?? (1000 * 60 * 60 * 24 * 7),
303307
pidFile: config.pidFile,
304308
skebStatus: undefined,
309+
approvalRequiredForSignup: config.approvalRequiredForSignup,
305310
};
306311
}
307312

packages/backend/src/core/CreateSystemUserService.ts

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export class CreateSystemUserService {
6060
isRoot: false,
6161
isLocked: true,
6262
isExplorable: false,
63+
approved: true,
6364
isBot: true,
6465
}).then(x => transactionalEntityManager.findOneByOrFail(MiUser, x.identifiers[0]));
6566

packages/backend/src/core/SignupService.ts

+2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export class SignupService {
5353
passwordHash?: MiUserProfile['password'] | null;
5454
host?: string | null;
5555
ignorePreservedUsernames?: boolean;
56+
reason?: string | null;
5657
}) {
5758
const { username, password, passwordHash, host } = opts;
5859
let hash = passwordHash;
@@ -130,6 +131,7 @@ export class SignupService {
130131
host: this.utilityService.toPunyNullable(host),
131132
token: secret,
132133
isRoot: isTheFirstUser,
134+
signupReason: opts.reason,
133135
}));
134136

135137
await transactionalEntityManager.save(new MiUserKeypair({

packages/backend/src/core/WebhookTestService.ts

+3
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ function generateDummyUser(override?: Partial<MiUser>): MiUser {
9595
uri: null,
9696
followersUri: null,
9797
token: null,
98+
approved: override?.approved ?? false,
99+
signupReason: override?.signupReason ?? null,
98100
...override,
99101
};
100102
}
@@ -208,6 +210,7 @@ function toPackedUserLite(user: MiUser, override?: Packed<'UserLite'>): Packed<'
208210
emojis: user.emojis,
209211
onlineStatus: 'active',
210212
badgeRoles: [],
213+
approved: override?.approved ?? false,
211214
...override,
212215
};
213216
}

0 commit comments

Comments
 (0)