feat(backend/ApiCallService): allow limited access for suspend accounts
This commit is contained in:
parent
ab58b651f7
commit
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) {
|
||||
|
|
|
@ -729,7 +729,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',
|
||||
|
||||
|
|
|
@ -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',
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ export const meta = {
|
|||
|
||||
requireCredential: true,
|
||||
|
||||
prohibitMoved: true,
|
||||
prohibitDeactivated: true,
|
||||
|
||||
kind: 'write:clip-favorite',
|
||||
|
||||
|
|
|
@ -15,7 +15,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',
|
||||
|
||||
|
|
|
@ -15,7 +15,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);
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue