Compare commits
	
		
			3 Commits
		
	
	
		
			2025.3.2-a
			...
			2024.2.0-b
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | aba02a0dea | ||
|   | 99fcd4054c | ||
|   | c28e0abb75 | 
| @@ -276,17 +276,10 @@ export class ApiCallService implements OnApplicationShutdown { | ||||
| 					id: '1384574d-a912-4b81-8601-c7b1c4085df1', | ||||
| 					httpStatusCode: 401, | ||||
| 				}); | ||||
| 			} else if (user!.isSuspended) { | ||||
| 				throw new ApiError({ | ||||
| 					message: 'Your account has been suspended.', | ||||
| 					code: 'YOUR_ACCOUNT_SUSPENDED', | ||||
| 					kind: 'permission', | ||||
| 					id: 'a8c724b3-6e9c-4b46-b1a8-bc3ed6258370', | ||||
| 				}); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if (ep.meta.prohibitMoved) { | ||||
| 		if (ep.meta.prohibitDeactivated) { | ||||
| 			if (user?.movedToUri) { | ||||
| 				throw new ApiError({ | ||||
| 					message: 'You have moved your account.', | ||||
| @@ -295,6 +288,14 @@ export class ApiCallService implements OnApplicationShutdown { | ||||
| 					id: '56f20ec9-fd06-4fa5-841b-edd6d7d4fa31', | ||||
| 				}); | ||||
| 			} | ||||
| 			if (user?.isSuspended) { | ||||
| 				throw new ApiError({ | ||||
| 					message: 'Your account has been suspended.', | ||||
| 					code: 'YOUR_ACCOUNT_SUSPENDED', | ||||
| 					kind: 'permission', | ||||
| 					id: 'a8c724b3-6e9c-4b46-b1a8-bc3ed6258370', | ||||
| 				}); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if ((ep.meta.requireModerator || ep.meta.requireAdmin) && !user!.isRoot) { | ||||
|   | ||||
| @@ -735,7 +735,7 @@ export interface IEndpointMeta { | ||||
| 	 * 引っ越し済みのユーザーによるリクエストを禁止するか | ||||
| 	 * 省略した場合は false として解釈されます。 | ||||
| 	 */ | ||||
| 	readonly prohibitMoved?: boolean; | ||||
| 	readonly prohibitDeactivated?: boolean; | ||||
|  | ||||
| 	/** | ||||
| 	 * エンドポイントのリミテーションに関するやつ | ||||
|   | ||||
| @@ -18,7 +18,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:account', | ||||
|  | ||||
|   | ||||
| @@ -16,7 +16,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:account', | ||||
|  | ||||
|   | ||||
| @@ -18,7 +18,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:channels', | ||||
|  | ||||
|   | ||||
| @@ -15,7 +15,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:channels', | ||||
|  | ||||
|   | ||||
| @@ -15,7 +15,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:channels', | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:channels', | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:channels', | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:account', | ||||
|  | ||||
|   | ||||
| @@ -15,7 +15,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:account', | ||||
|  | ||||
|   | ||||
| @@ -15,7 +15,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:clip-favorite', | ||||
|  | ||||
|   | ||||
| @@ -13,7 +13,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:account', | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:clip-favorite', | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:account', | ||||
|  | ||||
|   | ||||
| @@ -18,7 +18,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	limit: { | ||||
| 		duration: ms('1hour'), | ||||
|   | ||||
| @@ -22,7 +22,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:drive', | ||||
| } as const; | ||||
|   | ||||
| @@ -16,7 +16,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:flash', | ||||
|  | ||||
|   | ||||
| @@ -15,7 +15,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:flash-likes', | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:flash-likes', | ||||
|  | ||||
|   | ||||
| @@ -15,7 +15,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:flash', | ||||
|  | ||||
|   | ||||
| @@ -24,7 +24,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:following', | ||||
|  | ||||
|   | ||||
| @@ -18,7 +18,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:gallery', | ||||
|  | ||||
|   | ||||
| @@ -15,7 +15,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:gallery-likes', | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:gallery-likes', | ||||
|  | ||||
|   | ||||
| @@ -16,7 +16,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:gallery', | ||||
|  | ||||
|   | ||||
| @@ -9,7 +9,7 @@ import { AchievementService, ACHIEVEMENT_TYPES } from '@/core/AchievementService | ||||
|  | ||||
| export const meta = { | ||||
| 	requireCredential: true, | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
| } as const; | ||||
|  | ||||
| export const paramDef = { | ||||
|   | ||||
| @@ -16,7 +16,7 @@ import { ApiError } from '../../error.js'; | ||||
| export const meta = { | ||||
| 	secure: true, | ||||
| 	requireCredential: true, | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	limit: { | ||||
| 		duration: ms('1hour'), | ||||
|   | ||||
| @@ -15,7 +15,7 @@ import { ApiError } from '../../error.js'; | ||||
| export const meta = { | ||||
| 	secure: true, | ||||
| 	requireCredential: true, | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	limit: { | ||||
| 		duration: ms('1hour'), | ||||
|   | ||||
| @@ -15,7 +15,7 @@ import { ApiError } from '../../error.js'; | ||||
| export const meta = { | ||||
| 	secure: true, | ||||
| 	requireCredential: true, | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
| 	limit: { | ||||
| 		duration: ms('1hour'), | ||||
| 		max: 1, | ||||
|   | ||||
| @@ -15,7 +15,7 @@ import { ApiError } from '../../error.js'; | ||||
| export const meta = { | ||||
| 	secure: true, | ||||
| 	requireCredential: true, | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	limit: { | ||||
| 		duration: ms('1hour'), | ||||
|   | ||||
| @@ -15,7 +15,7 @@ import { ApiError } from '../../error.js'; | ||||
| export const meta = { | ||||
| 	secure: true, | ||||
| 	requireCredential: true, | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
| 	limit: { | ||||
| 		duration: ms('1hour'), | ||||
| 		max: 1, | ||||
|   | ||||
| @@ -25,7 +25,7 @@ export const meta = { | ||||
|  | ||||
| 	secure: true, | ||||
| 	requireCredential: true, | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
| 	limit: { | ||||
| 		duration: ms('1day'), | ||||
| 		max: 5, | ||||
|   | ||||
| @@ -13,7 +13,7 @@ export const meta = { | ||||
| 	tags: ['account', 'notes'], | ||||
|  | ||||
| 	requireCredential: true, | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:account', | ||||
|  | ||||
|   | ||||
| @@ -16,7 +16,7 @@ export const meta = { | ||||
| 	tags: ['account'], | ||||
|  | ||||
| 	requireCredential: true, | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:mutes', | ||||
|  | ||||
|   | ||||
| @@ -23,7 +23,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	limit: { | ||||
| 		duration: ms('1hour'), | ||||
|   | ||||
| @@ -17,7 +17,7 @@ export const meta = { | ||||
| 	tags: ['notes', 'favorites'], | ||||
|  | ||||
| 	requireCredential: true, | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:favorites', | ||||
|  | ||||
|   | ||||
| @@ -22,7 +22,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:votes', | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:reactions', | ||||
|  | ||||
|   | ||||
| @@ -18,7 +18,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:pages', | ||||
|  | ||||
|   | ||||
| @@ -15,7 +15,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:page-likes', | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:page-likes', | ||||
|  | ||||
|   | ||||
| @@ -16,7 +16,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:pages', | ||||
|  | ||||
|   | ||||
| @@ -17,7 +17,7 @@ export const meta = { | ||||
| 	tags: ['account'], | ||||
|  | ||||
| 	requireCredential: true, | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:mutes', | ||||
|  | ||||
|   | ||||
| @@ -17,7 +17,7 @@ import { UserListService } from '@/core/UserListService.js'; | ||||
|  | ||||
| export const meta = { | ||||
| 	requireCredential: true, | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
| 	res: { | ||||
| 		type: 'object', | ||||
| 		optional: false, nullable: false, | ||||
|   | ||||
| @@ -18,7 +18,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:account', | ||||
|  | ||||
|   | ||||
| @@ -17,7 +17,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:account', | ||||
|  | ||||
|   | ||||
| @@ -17,7 +17,7 @@ export const meta = { | ||||
|  | ||||
| 	requireCredential: true, | ||||
|  | ||||
| 	prohibitMoved: true, | ||||
| 	prohibitDeactivated: true, | ||||
|  | ||||
| 	kind: 'write:account', | ||||
|  | ||||
|   | ||||
							
								
								
									
										53
									
								
								packages/backend/test/e2e/suspend.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								packages/backend/test/e2e/suspend.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| /* | ||||
|  * SPDX-FileCopyrightText: syuilo and other misskey contributors | ||||
|  * SPDX-License-Identifier: AGPL-3.0-only | ||||
|  */ | ||||
|  | ||||
| process.env.NODE_ENV = 'test'; | ||||
|  | ||||
| import * as assert from 'assert'; | ||||
| import { loadConfig } from '@/config.js'; | ||||
| import { User, UsersRepository } from '@/models/index.js'; | ||||
| import { jobQueue } from '@/boot/common.js'; | ||||
| import { secureRndstr } from '@/misc/secure-rndstr.js'; | ||||
| import { uploadFile, signup, startServer, initTestDb, api, sleep, successfulApiCall } from '../utils.js'; | ||||
| import type { INestApplicationContext } from '@nestjs/common'; | ||||
| import type * as misskey from 'misskey-js'; | ||||
|  | ||||
| describe('Account Suspension', () => { | ||||
| 	let app: INestApplicationContext; | ||||
|  | ||||
| 	let root: misskey.entities.MeSignup; | ||||
| 	let alice: misskey.entities.MeSignup; | ||||
|  | ||||
| 	beforeAll(async () => { | ||||
| 		app = await startServer(); | ||||
| 		root = await signup({ username: 'root' }); | ||||
| 		alice = await signup({ username: 'alice' }); | ||||
|  | ||||
| 		await api('admin/suspend-user', { userId: alice.id }, root); | ||||
| 	}, 1000 * 60 * 2); | ||||
|  | ||||
| 	afterAll(async () => { | ||||
| 		await app.close(); | ||||
| 	}); | ||||
|  | ||||
| 	it('Cannot create notes', async () => { | ||||
| 		const res = await api('notes/create', { text: 'foo' }, alice); | ||||
|  | ||||
| 		assert.strictEqual(res.status, 403); | ||||
| 		assert.strictEqual(res.body.error.code, 'YOUR_ACCOUNT_SUSPENDED'); | ||||
| 		assert.strictEqual(res.body.error.id, 'a8c724b3-6e9c-4b46-b1a8-bc3ed6258370'); | ||||
| 	}); | ||||
|  | ||||
| 	it('Can see notes', async () => { | ||||
| 		const createRes = await api('notes/create', { text: 'bar' }, root); | ||||
| 		assert.strictEqual(createRes.status, 200); | ||||
| 		assert.strictEqual(createRes.body.createdNote.text, 'bar'); | ||||
|  | ||||
| 		const showRes = await api('notes/show', { noteId: createRes.body.createdNote.id }, alice); | ||||
| 		assert.strictEqual(showRes.status, 200); | ||||
| 		assert.strictEqual(showRes.body.text, 'bar'); | ||||
| 		assert.strictEqual(showRes.body.id, createRes.body.createdNote.id); | ||||
| 	}); | ||||
| }); | ||||
		Reference in New Issue
	
	Block a user