summaryrefslogtreecommitdiff
path: root/src/server/api/endpoints/i
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/api/endpoints/i')
-rw-r--r--src/server/api/endpoints/i/2fa/done.ts41
-rw-r--r--src/server/api/endpoints/i/2fa/key-done.ts150
-rw-r--r--src/server/api/endpoints/i/2fa/password-less.ts21
-rw-r--r--src/server/api/endpoints/i/2fa/register-key.ts59
-rw-r--r--src/server/api/endpoints/i/2fa/register.ts54
-rw-r--r--src/server/api/endpoints/i/2fa/remove-key.ts45
-rw-r--r--src/server/api/endpoints/i/2fa/unregister.ts32
-rw-r--r--src/server/api/endpoints/i/apps.ts43
-rw-r--r--src/server/api/endpoints/i/authorized-apps.ts44
-rw-r--r--src/server/api/endpoints/i/change-password.ts39
-rw-r--r--src/server/api/endpoints/i/delete-account.ts48
-rw-r--r--src/server/api/endpoints/i/export-blocking.ts16
-rw-r--r--src/server/api/endpoints/i/export-following.ts16
-rw-r--r--src/server/api/endpoints/i/export-mute.ts16
-rw-r--r--src/server/api/endpoints/i/export-notes.ts16
-rw-r--r--src/server/api/endpoints/i/export-user-lists.ts16
-rw-r--r--src/server/api/endpoints/i/favorites.ts50
-rw-r--r--src/server/api/endpoints/i/gallery/likes.ts57
-rw-r--r--src/server/api/endpoints/i/gallery/posts.ts49
-rw-r--r--src/server/api/endpoints/i/get-word-muted-notes-count.ts33
-rw-r--r--src/server/api/endpoints/i/import-blocking.ts60
-rw-r--r--src/server/api/endpoints/i/import-following.ts59
-rw-r--r--src/server/api/endpoints/i/import-muting.ts60
-rw-r--r--src/server/api/endpoints/i/import-user-lists.ts59
-rw-r--r--src/server/api/endpoints/i/notifications.ts138
-rw-r--r--src/server/api/endpoints/i/page-likes.ts57
-rw-r--r--src/server/api/endpoints/i/pages.ts49
-rw-r--r--src/server/api/endpoints/i/pin.ts59
-rw-r--r--src/server/api/endpoints/i/read-all-messaging-messages.ts37
-rw-r--r--src/server/api/endpoints/i/read-all-unread-notes.ts25
-rw-r--r--src/server/api/endpoints/i/read-announcement.ts60
-rw-r--r--src/server/api/endpoints/i/regenerate-token.ts44
-rw-r--r--src/server/api/endpoints/i/registry/get-all.ts33
-rw-r--r--src/server/api/endpoints/i/registry/get-detail.ts48
-rw-r--r--src/server/api/endpoints/i/registry/get.ts45
-rw-r--r--src/server/api/endpoints/i/registry/keys-with-type.ts41
-rw-r--r--src/server/api/endpoints/i/registry/keys.ts28
-rw-r--r--src/server/api/endpoints/i/registry/remove.ts45
-rw-r--r--src/server/api/endpoints/i/registry/scopes.ts29
-rw-r--r--src/server/api/endpoints/i/registry/set.ts61
-rw-r--r--src/server/api/endpoints/i/revoke-token.ts31
-rw-r--r--src/server/api/endpoints/i/signin-history.ts35
-rw-r--r--src/server/api/endpoints/i/unpin.ts45
-rw-r--r--src/server/api/endpoints/i/update-email.ts94
-rw-r--r--src/server/api/endpoints/i/update.ts294
-rw-r--r--src/server/api/endpoints/i/user-group-invites.ts61
46 files changed, 0 insertions, 2442 deletions
diff --git a/src/server/api/endpoints/i/2fa/done.ts b/src/server/api/endpoints/i/2fa/done.ts
deleted file mode 100644
index 2bd2128cce..0000000000
--- a/src/server/api/endpoints/i/2fa/done.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import $ from 'cafy';
-import * as speakeasy from 'speakeasy';
-import define from '../../../define';
-import { UserProfiles } from '@/models/index';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- token: {
- validator: $.str
- }
- }
-};
-
-export default define(meta, async (ps, user) => {
- const token = ps.token.replace(/\s/g, '');
-
- const profile = await UserProfiles.findOneOrFail(user.id);
-
- if (profile.twoFactorTempSecret == null) {
- throw new Error('二段階認証の設定が開始されていません');
- }
-
- const verified = (speakeasy as any).totp.verify({
- secret: profile.twoFactorTempSecret,
- encoding: 'base32',
- token: token
- });
-
- if (!verified) {
- throw new Error('not verified');
- }
-
- await UserProfiles.update(user.id, {
- twoFactorSecret: profile.twoFactorTempSecret,
- twoFactorEnabled: true
- });
-});
diff --git a/src/server/api/endpoints/i/2fa/key-done.ts b/src/server/api/endpoints/i/2fa/key-done.ts
deleted file mode 100644
index b4d3af235a..0000000000
--- a/src/server/api/endpoints/i/2fa/key-done.ts
+++ /dev/null
@@ -1,150 +0,0 @@
-import $ from 'cafy';
-import * as bcrypt from 'bcryptjs';
-import { promisify } from 'util';
-import * as cbor from 'cbor';
-import define from '../../../define';
-import {
- UserProfiles,
- UserSecurityKeys,
- AttestationChallenges,
- Users
-} from '@/models/index';
-import config from '@/config/index';
-import { procedures, hash } from '../../../2fa';
-import { publishMainStream } from '@/services/stream';
-
-const cborDecodeFirst = promisify(cbor.decodeFirst) as any;
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- clientDataJSON: {
- validator: $.str
- },
- attestationObject: {
- validator: $.str
- },
- password: {
- validator: $.str
- },
- challengeId: {
- validator: $.str
- },
- name: {
- validator: $.str
- }
- }
-};
-
-const rpIdHashReal = hash(Buffer.from(config.hostname, 'utf-8'));
-
-export default define(meta, async (ps, user) => {
- const profile = await UserProfiles.findOneOrFail(user.id);
-
- // Compare password
- const same = await bcrypt.compare(ps.password, profile.password!);
-
- if (!same) {
- throw new Error('incorrect password');
- }
-
- if (!profile.twoFactorEnabled) {
- throw new Error('2fa not enabled');
- }
-
- const clientData = JSON.parse(ps.clientDataJSON);
-
- if (clientData.type != 'webauthn.create') {
- throw new Error('not a creation attestation');
- }
- if (clientData.origin != config.scheme + '://' + config.host) {
- throw new Error('origin mismatch');
- }
-
- const clientDataJSONHash = hash(Buffer.from(ps.clientDataJSON, 'utf-8'));
-
- const attestation = await cborDecodeFirst(ps.attestationObject);
-
- const rpIdHash = attestation.authData.slice(0, 32);
- if (!rpIdHashReal.equals(rpIdHash)) {
- throw new Error('rpIdHash mismatch');
- }
-
- const flags = attestation.authData[32];
-
- // tslint:disable-next-line:no-bitwise
- if (!(flags & 1)) {
- throw new Error('user not present');
- }
-
- const authData = Buffer.from(attestation.authData);
- const credentialIdLength = authData.readUInt16BE(53);
- const credentialId = authData.slice(55, 55 + credentialIdLength);
- const publicKeyData = authData.slice(55 + credentialIdLength);
- const publicKey: Map<number, any> = await cborDecodeFirst(publicKeyData);
- if (publicKey.get(3) != -7) {
- throw new Error('alg mismatch');
- }
-
- if (!(procedures as any)[attestation.fmt]) {
- throw new Error('unsupported fmt');
- }
-
- const verificationData = (procedures as any)[attestation.fmt].verify({
- attStmt: attestation.attStmt,
- authenticatorData: authData,
- clientDataHash: clientDataJSONHash,
- credentialId,
- publicKey,
- rpIdHash
- });
- if (!verificationData.valid) throw new Error('signature invalid');
-
- const attestationChallenge = await AttestationChallenges.findOne({
- userId: user.id,
- id: ps.challengeId,
- registrationChallenge: true,
- challenge: hash(clientData.challenge).toString('hex')
- });
-
- if (!attestationChallenge) {
- throw new Error('non-existent challenge');
- }
-
- await AttestationChallenges.delete({
- userId: user.id,
- id: ps.challengeId
- });
-
- // Expired challenge (> 5min old)
- if (
- new Date().getTime() - attestationChallenge.createdAt.getTime() >=
- 5 * 60 * 1000
- ) {
- throw new Error('expired challenge');
- }
-
- const credentialIdString = credentialId.toString('hex');
-
- await UserSecurityKeys.save({
- userId: user.id,
- id: credentialIdString,
- lastUsed: new Date(),
- name: ps.name,
- publicKey: verificationData.publicKey.toString('hex')
- });
-
- // Publish meUpdated event
- publishMainStream(user.id, 'meUpdated', await Users.pack(user.id, user, {
- detail: true,
- includeSecrets: true
- }));
-
- return {
- id: credentialIdString,
- name: ps.name
- };
-});
diff --git a/src/server/api/endpoints/i/2fa/password-less.ts b/src/server/api/endpoints/i/2fa/password-less.ts
deleted file mode 100644
index 064828b638..0000000000
--- a/src/server/api/endpoints/i/2fa/password-less.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import $ from 'cafy';
-import define from '../../../define';
-import { UserProfiles } from '@/models/index';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- value: {
- validator: $.boolean
- }
- }
-};
-
-export default define(meta, async (ps, user) => {
- await UserProfiles.update(user.id, {
- usePasswordLessLogin: ps.value
- });
-});
diff --git a/src/server/api/endpoints/i/2fa/register-key.ts b/src/server/api/endpoints/i/2fa/register-key.ts
deleted file mode 100644
index 1b385a10ee..0000000000
--- a/src/server/api/endpoints/i/2fa/register-key.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import $ from 'cafy';
-import * as bcrypt from 'bcryptjs';
-import define from '../../../define';
-import { UserProfiles, AttestationChallenges } from '@/models/index';
-import { promisify } from 'util';
-import * as crypto from 'crypto';
-import { genId } from '@/misc/gen-id';
-import { hash } from '../../../2fa';
-
-const randomBytes = promisify(crypto.randomBytes);
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- password: {
- validator: $.str
- }
- }
-};
-
-export default define(meta, async (ps, user) => {
- const profile = await UserProfiles.findOneOrFail(user.id);
-
- // Compare password
- const same = await bcrypt.compare(ps.password, profile.password!);
-
- if (!same) {
- throw new Error('incorrect password');
- }
-
- if (!profile.twoFactorEnabled) {
- throw new Error('2fa not enabled');
- }
-
- // 32 byte challenge
- const entropy = await randomBytes(32);
- const challenge = entropy.toString('base64')
- .replace(/=/g, '')
- .replace(/\+/g, '-')
- .replace(/\//g, '_');
-
- const challengeId = genId();
-
- await AttestationChallenges.save({
- userId: user.id,
- id: challengeId,
- challenge: hash(Buffer.from(challenge, 'utf-8')).toString('hex'),
- createdAt: new Date(),
- registrationChallenge: true
- });
-
- return {
- challengeId,
- challenge
- };
-});
diff --git a/src/server/api/endpoints/i/2fa/register.ts b/src/server/api/endpoints/i/2fa/register.ts
deleted file mode 100644
index b03b98188a..0000000000
--- a/src/server/api/endpoints/i/2fa/register.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import $ from 'cafy';
-import * as bcrypt from 'bcryptjs';
-import * as speakeasy from 'speakeasy';
-import * as QRCode from 'qrcode';
-import config from '@/config/index';
-import define from '../../../define';
-import { UserProfiles } from '@/models/index';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- password: {
- validator: $.str
- }
- }
-};
-
-export default define(meta, async (ps, user) => {
- const profile = await UserProfiles.findOneOrFail(user.id);
-
- // Compare password
- const same = await bcrypt.compare(ps.password, profile.password!);
-
- if (!same) {
- throw new Error('incorrect password');
- }
-
- // Generate user's secret key
- const secret = speakeasy.generateSecret({
- length: 32
- });
-
- await UserProfiles.update(user.id, {
- twoFactorTempSecret: secret.base32
- });
-
- // Get the data URL of the authenticator URL
- const dataUrl = await QRCode.toDataURL(speakeasy.otpauthURL({
- secret: secret.base32,
- encoding: 'base32',
- label: user.username,
- issuer: config.host
- }));
-
- return {
- qr: dataUrl,
- secret: secret.base32,
- label: user.username,
- issuer: config.host
- };
-});
diff --git a/src/server/api/endpoints/i/2fa/remove-key.ts b/src/server/api/endpoints/i/2fa/remove-key.ts
deleted file mode 100644
index dea56301ab..0000000000
--- a/src/server/api/endpoints/i/2fa/remove-key.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import $ from 'cafy';
-import * as bcrypt from 'bcryptjs';
-import define from '../../../define';
-import { UserProfiles, UserSecurityKeys, Users } from '@/models/index';
-import { publishMainStream } from '@/services/stream';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- password: {
- validator: $.str
- },
- credentialId: {
- validator: $.str
- },
- }
-};
-
-export default define(meta, async (ps, user) => {
- const profile = await UserProfiles.findOneOrFail(user.id);
-
- // Compare password
- const same = await bcrypt.compare(ps.password, profile.password!);
-
- if (!same) {
- throw new Error('incorrect password');
- }
-
- // Make sure we only delete the user's own creds
- await UserSecurityKeys.delete({
- userId: user.id,
- id: ps.credentialId
- });
-
- // Publish meUpdated event
- publishMainStream(user.id, 'meUpdated', await Users.pack(user.id, user, {
- detail: true,
- includeSecrets: true
- }));
-
- return {};
-});
diff --git a/src/server/api/endpoints/i/2fa/unregister.ts b/src/server/api/endpoints/i/2fa/unregister.ts
deleted file mode 100644
index af53033daa..0000000000
--- a/src/server/api/endpoints/i/2fa/unregister.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import $ from 'cafy';
-import * as bcrypt from 'bcryptjs';
-import define from '../../../define';
-import { UserProfiles } from '@/models/index';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- password: {
- validator: $.str
- }
- }
-};
-
-export default define(meta, async (ps, user) => {
- const profile = await UserProfiles.findOneOrFail(user.id);
-
- // Compare password
- const same = await bcrypt.compare(ps.password, profile.password!);
-
- if (!same) {
- throw new Error('incorrect password');
- }
-
- await UserProfiles.update(user.id, {
- twoFactorSecret: null,
- twoFactorEnabled: false
- });
-});
diff --git a/src/server/api/endpoints/i/apps.ts b/src/server/api/endpoints/i/apps.ts
deleted file mode 100644
index 994528e5c9..0000000000
--- a/src/server/api/endpoints/i/apps.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import $ from 'cafy';
-import define from '../../define';
-import { AccessTokens } from '@/models/index';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- sort: {
- validator: $.optional.str.or([
- '+createdAt',
- '-createdAt',
- '+lastUsedAt',
- '-lastUsedAt',
- ]),
- },
- }
-};
-
-export default define(meta, async (ps, user) => {
- const query = AccessTokens.createQueryBuilder('token')
- .where('token.userId = :userId', { userId: user.id });
-
- switch (ps.sort) {
- case '+createdAt': query.orderBy('token.createdAt', 'DESC'); break;
- case '-createdAt': query.orderBy('token.createdAt', 'ASC'); break;
- case '+lastUsedAt': query.orderBy('token.lastUsedAt', 'DESC'); break;
- case '-lastUsedAt': query.orderBy('token.lastUsedAt', 'ASC'); break;
- default: query.orderBy('token.id', 'ASC'); break;
- }
-
- const tokens = await query.getMany();
-
- return await Promise.all(tokens.map(token => ({
- id: token.id,
- name: token.name,
- createdAt: token.createdAt,
- lastUsedAt: token.lastUsedAt,
- permission: token.permission,
- })));
-});
diff --git a/src/server/api/endpoints/i/authorized-apps.ts b/src/server/api/endpoints/i/authorized-apps.ts
deleted file mode 100644
index 042fcd14e8..0000000000
--- a/src/server/api/endpoints/i/authorized-apps.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import $ from 'cafy';
-import define from '../../define';
-import { AccessTokens, Apps } from '@/models/index';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- limit: {
- validator: $.optional.num.range(1, 100),
- default: 10,
- },
-
- offset: {
- validator: $.optional.num.min(0),
- default: 0,
- },
-
- sort: {
- validator: $.optional.str.or('desc|asc'),
- default: 'desc',
- }
- }
-};
-
-export default define(meta, async (ps, user) => {
- // Get tokens
- const tokens = await AccessTokens.find({
- where: {
- userId: user.id
- },
- take: ps.limit!,
- skip: ps.offset,
- order: {
- id: ps.sort == 'asc' ? 1 : -1
- }
- });
-
- return await Promise.all(tokens.map(token => Apps.pack(token.appId, user, {
- detail: true
- })));
-});
diff --git a/src/server/api/endpoints/i/change-password.ts b/src/server/api/endpoints/i/change-password.ts
deleted file mode 100644
index 7ea5f8c488..0000000000
--- a/src/server/api/endpoints/i/change-password.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import $ from 'cafy';
-import * as bcrypt from 'bcryptjs';
-import define from '../../define';
-import { UserProfiles } from '@/models/index';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- currentPassword: {
- validator: $.str
- },
-
- newPassword: {
- validator: $.str
- }
- }
-};
-
-export default define(meta, async (ps, user) => {
- const profile = await UserProfiles.findOneOrFail(user.id);
-
- // Compare password
- const same = await bcrypt.compare(ps.currentPassword, profile.password!);
-
- if (!same) {
- throw new Error('incorrect password');
- }
-
- // Generate hash of password
- const salt = await bcrypt.genSalt(8);
- const hash = await bcrypt.hash(ps.newPassword, salt);
-
- await UserProfiles.update(user.id, {
- password: hash
- });
-});
diff --git a/src/server/api/endpoints/i/delete-account.ts b/src/server/api/endpoints/i/delete-account.ts
deleted file mode 100644
index 10e5adf64a..0000000000
--- a/src/server/api/endpoints/i/delete-account.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import $ from 'cafy';
-import * as bcrypt from 'bcryptjs';
-import define from '../../define';
-import { UserProfiles, Users } from '@/models/index';
-import { doPostSuspend } from '@/services/suspend-user';
-import { publishUserEvent } from '@/services/stream';
-import { createDeleteAccountJob } from '@/queue';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- password: {
- validator: $.str
- },
- }
-};
-
-export default define(meta, async (ps, user) => {
- const profile = await UserProfiles.findOneOrFail(user.id);
- const userDetailed = await Users.findOneOrFail(user.id);
- if (userDetailed.isDeleted) {
- return;
- }
-
- // Compare password
- const same = await bcrypt.compare(ps.password, profile.password!);
-
- if (!same) {
- throw new Error('incorrect password');
- }
-
- // 物理削除する前にDelete activityを送信する
- await doPostSuspend(user).catch(e => {});
-
- createDeleteAccountJob(user, {
- soft: false
- });
-
- await Users.update(user.id, {
- isDeleted: true,
- });
-
- // Terminate streaming
- publishUserEvent(user.id, 'terminate', {});
-});
diff --git a/src/server/api/endpoints/i/export-blocking.ts b/src/server/api/endpoints/i/export-blocking.ts
deleted file mode 100644
index e4797da0c1..0000000000
--- a/src/server/api/endpoints/i/export-blocking.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import define from '../../define';
-import { createExportBlockingJob } from '@/queue/index';
-import * as ms from 'ms';
-
-export const meta = {
- secure: true,
- requireCredential: true as const,
- limit: {
- duration: ms('1hour'),
- max: 1,
- },
-};
-
-export default define(meta, async (ps, user) => {
- createExportBlockingJob(user);
-});
diff --git a/src/server/api/endpoints/i/export-following.ts b/src/server/api/endpoints/i/export-following.ts
deleted file mode 100644
index b0f154cda8..0000000000
--- a/src/server/api/endpoints/i/export-following.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import define from '../../define';
-import { createExportFollowingJob } from '@/queue/index';
-import * as ms from 'ms';
-
-export const meta = {
- secure: true,
- requireCredential: true as const,
- limit: {
- duration: ms('1hour'),
- max: 1,
- },
-};
-
-export default define(meta, async (ps, user) => {
- createExportFollowingJob(user);
-});
diff --git a/src/server/api/endpoints/i/export-mute.ts b/src/server/api/endpoints/i/export-mute.ts
deleted file mode 100644
index 46d547fa53..0000000000
--- a/src/server/api/endpoints/i/export-mute.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import define from '../../define';
-import { createExportMuteJob } from '@/queue/index';
-import * as ms from 'ms';
-
-export const meta = {
- secure: true,
- requireCredential: true as const,
- limit: {
- duration: ms('1hour'),
- max: 1,
- },
-};
-
-export default define(meta, async (ps, user) => {
- createExportMuteJob(user);
-});
diff --git a/src/server/api/endpoints/i/export-notes.ts b/src/server/api/endpoints/i/export-notes.ts
deleted file mode 100644
index 441bf16896..0000000000
--- a/src/server/api/endpoints/i/export-notes.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import define from '../../define';
-import { createExportNotesJob } from '@/queue/index';
-import * as ms from 'ms';
-
-export const meta = {
- secure: true,
- requireCredential: true as const,
- limit: {
- duration: ms('1day'),
- max: 1,
- },
-};
-
-export default define(meta, async (ps, user) => {
- createExportNotesJob(user);
-});
diff --git a/src/server/api/endpoints/i/export-user-lists.ts b/src/server/api/endpoints/i/export-user-lists.ts
deleted file mode 100644
index 24043a862a..0000000000
--- a/src/server/api/endpoints/i/export-user-lists.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import define from '../../define';
-import { createExportUserListsJob } from '@/queue/index';
-import * as ms from 'ms';
-
-export const meta = {
- secure: true,
- requireCredential: true as const,
- limit: {
- duration: ms('1min'),
- max: 1,
- },
-};
-
-export default define(meta, async (ps, user) => {
- createExportUserListsJob(user);
-});
diff --git a/src/server/api/endpoints/i/favorites.ts b/src/server/api/endpoints/i/favorites.ts
deleted file mode 100644
index b79d68ae73..0000000000
--- a/src/server/api/endpoints/i/favorites.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import $ from 'cafy';
-import { ID } from '@/misc/cafy-id';
-import define from '../../define';
-import { NoteFavorites } from '@/models/index';
-import { makePaginationQuery } from '../../common/make-pagination-query';
-
-export const meta = {
- tags: ['account', 'notes', 'favorites'],
-
- requireCredential: true as const,
-
- kind: 'read:favorites',
-
- params: {
- limit: {
- validator: $.optional.num.range(1, 100),
- default: 10
- },
-
- sinceId: {
- validator: $.optional.type(ID),
- },
-
- untilId: {
- validator: $.optional.type(ID),
- },
- },
-
- res: {
- type: 'array' as const,
- optional: false as const, nullable: false as const,
- items: {
- type: 'object' as const,
- optional: false as const, nullable: false as const,
- ref: 'NoteFavorite',
- }
- },
-};
-
-export default define(meta, async (ps, user) => {
- const query = makePaginationQuery(NoteFavorites.createQueryBuilder('favorite'), ps.sinceId, ps.untilId)
- .andWhere(`favorite.userId = :meId`, { meId: user.id })
- .leftJoinAndSelect('favorite.note', 'note');
-
- const favorites = await query
- .take(ps.limit!)
- .getMany();
-
- return await NoteFavorites.packMany(favorites, user);
-});
diff --git a/src/server/api/endpoints/i/gallery/likes.ts b/src/server/api/endpoints/i/gallery/likes.ts
deleted file mode 100644
index 7a2935a5ec..0000000000
--- a/src/server/api/endpoints/i/gallery/likes.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import $ from 'cafy';
-import { ID } from '@/misc/cafy-id';
-import define from '../../../define';
-import { GalleryLikes } from '@/models/index';
-import { makePaginationQuery } from '../../../common/make-pagination-query';
-
-export const meta = {
- tags: ['account', 'gallery'],
-
- requireCredential: true as const,
-
- kind: 'read:gallery-likes',
-
- params: {
- limit: {
- validator: $.optional.num.range(1, 100),
- default: 10
- },
-
- sinceId: {
- validator: $.optional.type(ID),
- },
-
- untilId: {
- validator: $.optional.type(ID),
- },
- },
-
- res: {
- type: 'object' as const,
- optional: false as const, nullable: false as const,
- properties: {
- id: {
- type: 'string' as const,
- optional: false as const, nullable: false as const,
- format: 'id'
- },
- page: {
- type: 'object' as const,
- optional: false as const, nullable: false as const,
- ref: 'GalleryPost'
- }
- }
- }
-};
-
-export default define(meta, async (ps, user) => {
- const query = makePaginationQuery(GalleryLikes.createQueryBuilder('like'), ps.sinceId, ps.untilId)
- .andWhere(`like.userId = :meId`, { meId: user.id })
- .leftJoinAndSelect('like.post', 'post');
-
- const likes = await query
- .take(ps.limit!)
- .getMany();
-
- return await GalleryLikes.packMany(likes, user);
-});
diff --git a/src/server/api/endpoints/i/gallery/posts.ts b/src/server/api/endpoints/i/gallery/posts.ts
deleted file mode 100644
index 21bb8759fc..0000000000
--- a/src/server/api/endpoints/i/gallery/posts.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import $ from 'cafy';
-import { ID } from '@/misc/cafy-id';
-import define from '../../../define';
-import { GalleryPosts } from '@/models/index';
-import { makePaginationQuery } from '../../../common/make-pagination-query';
-
-export const meta = {
- tags: ['account', 'gallery'],
-
- requireCredential: true as const,
-
- kind: 'read:gallery',
-
- params: {
- limit: {
- validator: $.optional.num.range(1, 100),
- default: 10
- },
-
- sinceId: {
- validator: $.optional.type(ID),
- },
-
- untilId: {
- validator: $.optional.type(ID),
- },
- },
-
- res: {
- type: 'array' as const,
- optional: false as const, nullable: false as const,
- items: {
- type: 'object' as const,
- optional: false as const, nullable: false as const,
- ref: 'GalleryPost'
- }
- }
-};
-
-export default define(meta, async (ps, user) => {
- const query = makePaginationQuery(GalleryPosts.createQueryBuilder('post'), ps.sinceId, ps.untilId)
- .andWhere(`post.userId = :meId`, { meId: user.id });
-
- const posts = await query
- .take(ps.limit!)
- .getMany();
-
- return await GalleryPosts.packMany(posts, user);
-});
diff --git a/src/server/api/endpoints/i/get-word-muted-notes-count.ts b/src/server/api/endpoints/i/get-word-muted-notes-count.ts
deleted file mode 100644
index 6b9be98582..0000000000
--- a/src/server/api/endpoints/i/get-word-muted-notes-count.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import define from '../../define';
-import { MutedNotes } from '@/models/index';
-
-export const meta = {
- tags: ['account'],
-
- requireCredential: true as const,
-
- kind: 'read:account',
-
- params: {
- },
-
- res: {
- type: 'object' as const,
- optional: false as const, nullable: false as const,
- properties: {
- count: {
- type: 'number' as const,
- optional: false as const, nullable: false as const
- }
- }
- }
-};
-
-export default define(meta, async (ps, user) => {
- return {
- count: await MutedNotes.count({
- userId: user.id,
- reason: 'word'
- })
- };
-});
diff --git a/src/server/api/endpoints/i/import-blocking.ts b/src/server/api/endpoints/i/import-blocking.ts
deleted file mode 100644
index d44d0b6077..0000000000
--- a/src/server/api/endpoints/i/import-blocking.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import $ from 'cafy';
-import { ID } from '@/misc/cafy-id';
-import define from '../../define';
-import { createImportBlockingJob } from '@/queue/index';
-import * as ms from 'ms';
-import { ApiError } from '../../error';
-import { DriveFiles } from '@/models/index';
-
-export const meta = {
- secure: true,
- requireCredential: true as const,
-
- limit: {
- duration: ms('1hour'),
- max: 1,
- },
-
- params: {
- fileId: {
- validator: $.type(ID),
- }
- },
-
- errors: {
- noSuchFile: {
- message: 'No such file.',
- code: 'NO_SUCH_FILE',
- id: 'ebb53e5f-6574-9c0c-0b92-7ca6def56d7e'
- },
-
- unexpectedFileType: {
- message: 'We need csv file.',
- code: 'UNEXPECTED_FILE_TYPE',
- id: 'b6fab7d6-d945-d67c-dfdb-32da1cd12cfe'
- },
-
- tooBigFile: {
- message: 'That file is too big.',
- code: 'TOO_BIG_FILE',
- id: 'b7fbf0b1-aeef-3b21-29ef-fadd4cb72ccf'
- },
-
- emptyFile: {
- message: 'That file is empty.',
- code: 'EMPTY_FILE',
- id: '6f3a4dcc-f060-a707-4950-806fbdbe60d6'
- },
- }
-};
-
-export default define(meta, async (ps, user) => {
- const file = await DriveFiles.findOne(ps.fileId);
-
- if (file == null) throw new ApiError(meta.errors.noSuchFile);
- //if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType);
- if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile);
- if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
-
- createImportBlockingJob(user, file.id);
-});
diff --git a/src/server/api/endpoints/i/import-following.ts b/src/server/api/endpoints/i/import-following.ts
deleted file mode 100644
index b3de397661..0000000000
--- a/src/server/api/endpoints/i/import-following.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import $ from 'cafy';
-import { ID } from '@/misc/cafy-id';
-import define from '../../define';
-import { createImportFollowingJob } from '@/queue/index';
-import * as ms from 'ms';
-import { ApiError } from '../../error';
-import { DriveFiles } from '@/models/index';
-
-export const meta = {
- secure: true,
- requireCredential: true as const,
- limit: {
- duration: ms('1hour'),
- max: 1,
- },
-
- params: {
- fileId: {
- validator: $.type(ID),
- }
- },
-
- errors: {
- noSuchFile: {
- message: 'No such file.',
- code: 'NO_SUCH_FILE',
- id: 'b98644cf-a5ac-4277-a502-0b8054a709a3'
- },
-
- unexpectedFileType: {
- message: 'We need csv file.',
- code: 'UNEXPECTED_FILE_TYPE',
- id: '660f3599-bce0-4f95-9dde-311fd841c183'
- },
-
- tooBigFile: {
- message: 'That file is too big.',
- code: 'TOO_BIG_FILE',
- id: 'dee9d4ed-ad07-43ed-8b34-b2856398bc60'
- },
-
- emptyFile: {
- message: 'That file is empty.',
- code: 'EMPTY_FILE',
- id: '31a1b42c-06f7-42ae-8a38-a661c5c9f691'
- },
- }
-};
-
-export default define(meta, async (ps, user) => {
- const file = await DriveFiles.findOne(ps.fileId);
-
- if (file == null) throw new ApiError(meta.errors.noSuchFile);
- //if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType);
- if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile);
- if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
-
- createImportFollowingJob(user, file.id);
-});
diff --git a/src/server/api/endpoints/i/import-muting.ts b/src/server/api/endpoints/i/import-muting.ts
deleted file mode 100644
index c17434c587..0000000000
--- a/src/server/api/endpoints/i/import-muting.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import $ from 'cafy';
-import { ID } from '@/misc/cafy-id';
-import define from '../../define';
-import { createImportMutingJob } from '@/queue/index';
-import * as ms from 'ms';
-import { ApiError } from '../../error';
-import { DriveFiles } from '@/models/index';
-
-export const meta = {
- secure: true,
- requireCredential: true as const,
-
- limit: {
- duration: ms('1hour'),
- max: 1,
- },
-
- params: {
- fileId: {
- validator: $.type(ID),
- }
- },
-
- errors: {
- noSuchFile: {
- message: 'No such file.',
- code: 'NO_SUCH_FILE',
- id: 'e674141e-bd2a-ba85-e616-aefb187c9c2a'
- },
-
- unexpectedFileType: {
- message: 'We need csv file.',
- code: 'UNEXPECTED_FILE_TYPE',
- id: '568c6e42-c86c-ba09-c004-517f83f9f1a8'
- },
-
- tooBigFile: {
- message: 'That file is too big.',
- code: 'TOO_BIG_FILE',
- id: '9b4ada6d-d7f7-0472-0713-4f558bd1ec9c'
- },
-
- emptyFile: {
- message: 'That file is empty.',
- code: 'EMPTY_FILE',
- id: 'd2f12af1-e7b4-feac-86a3-519548f2728e'
- },
- }
-};
-
-export default define(meta, async (ps, user) => {
- const file = await DriveFiles.findOne(ps.fileId);
-
- if (file == null) throw new ApiError(meta.errors.noSuchFile);
- //if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType);
- if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile);
- if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
-
- createImportMutingJob(user, file.id);
-});
diff --git a/src/server/api/endpoints/i/import-user-lists.ts b/src/server/api/endpoints/i/import-user-lists.ts
deleted file mode 100644
index 9069a019a9..0000000000
--- a/src/server/api/endpoints/i/import-user-lists.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import $ from 'cafy';
-import { ID } from '@/misc/cafy-id';
-import define from '../../define';
-import { createImportUserListsJob } from '@/queue/index';
-import * as ms from 'ms';
-import { ApiError } from '../../error';
-import { DriveFiles } from '@/models/index';
-
-export const meta = {
- secure: true,
- requireCredential: true as const,
- limit: {
- duration: ms('1hour'),
- max: 1,
- },
-
- params: {
- fileId: {
- validator: $.type(ID),
- }
- },
-
- errors: {
- noSuchFile: {
- message: 'No such file.',
- code: 'NO_SUCH_FILE',
- id: 'ea9cc34f-c415-4bc6-a6fe-28ac40357049'
- },
-
- unexpectedFileType: {
- message: 'We need csv file.',
- code: 'UNEXPECTED_FILE_TYPE',
- id: 'a3c9edda-dd9b-4596-be6a-150ef813745c'
- },
-
- tooBigFile: {
- message: 'That file is too big.',
- code: 'TOO_BIG_FILE',
- id: 'ae6e7a22-971b-4b52-b2be-fc0b9b121fe9'
- },
-
- emptyFile: {
- message: 'That file is empty.',
- code: 'EMPTY_FILE',
- id: '99efe367-ce6e-4d44-93f8-5fae7b040356'
- },
- }
-};
-
-export default define(meta, async (ps, user) => {
- const file = await DriveFiles.findOne(ps.fileId);
-
- if (file == null) throw new ApiError(meta.errors.noSuchFile);
- //if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType);
- if (file.size > 30000) throw new ApiError(meta.errors.tooBigFile);
- if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
-
- createImportUserListsJob(user, file.id);
-});
diff --git a/src/server/api/endpoints/i/notifications.ts b/src/server/api/endpoints/i/notifications.ts
deleted file mode 100644
index 56668d03b7..0000000000
--- a/src/server/api/endpoints/i/notifications.ts
+++ /dev/null
@@ -1,138 +0,0 @@
-import $ from 'cafy';
-import { ID } from '@/misc/cafy-id';
-import { readNotification } from '../../common/read-notification';
-import define from '../../define';
-import { makePaginationQuery } from '../../common/make-pagination-query';
-import { Notifications, Followings, Mutings, Users } from '@/models/index';
-import { notificationTypes } from '@/types';
-import read from '@/services/note/read';
-import { Brackets } from 'typeorm';
-
-export const meta = {
- tags: ['account', 'notifications'],
-
- requireCredential: true as const,
-
- kind: 'read:notifications',
-
- params: {
- limit: {
- validator: $.optional.num.range(1, 100),
- default: 10
- },
-
- sinceId: {
- validator: $.optional.type(ID),
- },
-
- untilId: {
- validator: $.optional.type(ID),
- },
-
- following: {
- validator: $.optional.bool,
- default: false
- },
-
- unreadOnly: {
- validator: $.optional.bool,
- default: false
- },
-
- markAsRead: {
- validator: $.optional.bool,
- default: true
- },
-
- includeTypes: {
- validator: $.optional.arr($.str.or(notificationTypes as unknown as string[])),
- },
-
- excludeTypes: {
- validator: $.optional.arr($.str.or(notificationTypes as unknown as string[])),
- }
- },
-
- res: {
- type: 'array' as const,
- optional: false as const, nullable: false as const,
- items: {
- type: 'object' as const,
- optional: false as const, nullable: false as const,
- ref: 'Notification',
- }
- },
-};
-
-export default define(meta, async (ps, user) => {
- // includeTypes が空の場合はクエリしない
- if (ps.includeTypes && ps.includeTypes.length === 0) {
- return [];
- }
- // excludeTypes に全指定されている場合はクエリしない
- if (notificationTypes.every(type => ps.excludeTypes?.includes(type))) {
- return [];
- }
- const followingQuery = Followings.createQueryBuilder('following')
- .select('following.followeeId')
- .where('following.followerId = :followerId', { followerId: user.id });
-
- const mutingQuery = Mutings.createQueryBuilder('muting')
- .select('muting.muteeId')
- .where('muting.muterId = :muterId', { muterId: user.id });
-
- const suspendedQuery = Users.createQueryBuilder('users')
- .select('users.id')
- .where('users.isSuspended = TRUE');
-
- const query = makePaginationQuery(Notifications.createQueryBuilder('notification'), ps.sinceId, ps.untilId)
- .andWhere(`notification.notifieeId = :meId`, { meId: user.id })
- .leftJoinAndSelect('notification.notifier', 'notifier')
- .leftJoinAndSelect('notification.note', 'note')
- .leftJoinAndSelect('note.user', 'user')
- .leftJoinAndSelect('note.reply', 'reply')
- .leftJoinAndSelect('note.renote', 'renote')
- .leftJoinAndSelect('reply.user', 'replyUser')
- .leftJoinAndSelect('renote.user', 'renoteUser');
-
- query.andWhere(new Brackets(qb => { qb
- .where(`notification.notifierId NOT IN (${ mutingQuery.getQuery() })`)
- .orWhere('notification.notifierId IS NULL');
- }));
- query.setParameters(mutingQuery.getParameters());
-
- query.andWhere(new Brackets(qb => { qb
- .where(`notification.notifierId NOT IN (${ suspendedQuery.getQuery() })`)
- .orWhere('notification.notifierId IS NULL');
- }));
-
- if (ps.following) {
- query.andWhere(`((notification.notifierId IN (${ followingQuery.getQuery() })) OR (notification.notifierId = :meId))`, { meId: user.id });
- query.setParameters(followingQuery.getParameters());
- }
-
- if (ps.includeTypes && ps.includeTypes.length > 0) {
- query.andWhere(`notification.type IN (:...includeTypes)`, { includeTypes: ps.includeTypes });
- } else if (ps.excludeTypes && ps.excludeTypes.length > 0) {
- query.andWhere(`notification.type NOT IN (:...excludeTypes)`, { excludeTypes: ps.excludeTypes });
- }
-
- if (ps.unreadOnly) {
- query.andWhere(`notification.isRead = false`);
- }
-
- const notifications = await query.take(ps.limit!).getMany();
-
- // Mark all as read
- if (notifications.length > 0 && ps.markAsRead) {
- readNotification(user.id, notifications.map(x => x.id));
- }
-
- const notes = notifications.filter(notification => ['mention', 'reply', 'quote'].includes(notification.type)).map(notification => notification.note!);
-
- if (notes.length > 0) {
- read(user.id, notes);
- }
-
- return await Notifications.packMany(notifications, user.id);
-});
diff --git a/src/server/api/endpoints/i/page-likes.ts b/src/server/api/endpoints/i/page-likes.ts
deleted file mode 100644
index fa2bc31730..0000000000
--- a/src/server/api/endpoints/i/page-likes.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import $ from 'cafy';
-import { ID } from '@/misc/cafy-id';
-import define from '../../define';
-import { PageLikes } from '@/models/index';
-import { makePaginationQuery } from '../../common/make-pagination-query';
-
-export const meta = {
- tags: ['account', 'pages'],
-
- requireCredential: true as const,
-
- kind: 'read:page-likes',
-
- params: {
- limit: {
- validator: $.optional.num.range(1, 100),
- default: 10
- },
-
- sinceId: {
- validator: $.optional.type(ID),
- },
-
- untilId: {
- validator: $.optional.type(ID),
- },
- },
-
- res: {
- type: 'object' as const,
- optional: false as const, nullable: false as const,
- properties: {
- id: {
- type: 'string' as const,
- optional: false as const, nullable: false as const,
- format: 'id'
- },
- page: {
- type: 'object' as const,
- optional: false as const, nullable: false as const,
- ref: 'Page'
- }
- }
- }
-};
-
-export default define(meta, async (ps, user) => {
- const query = makePaginationQuery(PageLikes.createQueryBuilder('like'), ps.sinceId, ps.untilId)
- .andWhere(`like.userId = :meId`, { meId: user.id })
- .leftJoinAndSelect('like.page', 'page');
-
- const likes = await query
- .take(ps.limit!)
- .getMany();
-
- return await PageLikes.packMany(likes, user);
-});
diff --git a/src/server/api/endpoints/i/pages.ts b/src/server/api/endpoints/i/pages.ts
deleted file mode 100644
index ee87fffa2d..0000000000
--- a/src/server/api/endpoints/i/pages.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import $ from 'cafy';
-import { ID } from '@/misc/cafy-id';
-import define from '../../define';
-import { Pages } from '@/models/index';
-import { makePaginationQuery } from '../../common/make-pagination-query';
-
-export const meta = {
- tags: ['account', 'pages'],
-
- requireCredential: true as const,
-
- kind: 'read:pages',
-
- params: {
- limit: {
- validator: $.optional.num.range(1, 100),
- default: 10
- },
-
- sinceId: {
- validator: $.optional.type(ID),
- },
-
- untilId: {
- validator: $.optional.type(ID),
- },
- },
-
- res: {
- type: 'array' as const,
- optional: false as const, nullable: false as const,
- items: {
- type: 'object' as const,
- optional: false as const, nullable: false as const,
- ref: 'Page'
- }
- }
-};
-
-export default define(meta, async (ps, user) => {
- const query = makePaginationQuery(Pages.createQueryBuilder('page'), ps.sinceId, ps.untilId)
- .andWhere(`page.userId = :meId`, { meId: user.id });
-
- const pages = await query
- .take(ps.limit!)
- .getMany();
-
- return await Pages.packMany(pages);
-});
diff --git a/src/server/api/endpoints/i/pin.ts b/src/server/api/endpoints/i/pin.ts
deleted file mode 100644
index de94220ba9..0000000000
--- a/src/server/api/endpoints/i/pin.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import $ from 'cafy';
-import { ID } from '@/misc/cafy-id';
-import { addPinned } from '@/services/i/pin';
-import define from '../../define';
-import { ApiError } from '../../error';
-import { Users } from '@/models/index';
-
-export const meta = {
- tags: ['account', 'notes'],
-
- requireCredential: true as const,
-
- kind: 'write:account',
-
- params: {
- noteId: {
- validator: $.type(ID),
- }
- },
-
- errors: {
- noSuchNote: {
- message: 'No such note.',
- code: 'NO_SUCH_NOTE',
- id: '56734f8b-3928-431e-bf80-6ff87df40cb3'
- },
-
- pinLimitExceeded: {
- message: 'You can not pin notes any more.',
- code: 'PIN_LIMIT_EXCEEDED',
- id: '72dab508-c64d-498f-8740-a8eec1ba385a'
- },
-
- alreadyPinned: {
- message: 'That note has already been pinned.',
- code: 'ALREADY_PINNED',
- id: '8b18c2b7-68fe-4edb-9892-c0cbaeb6c913'
- },
- },
-
- res: {
- type: 'object' as const,
- optional: false as const, nullable: false as const,
- ref: 'User'
- }
-};
-
-export default define(meta, async (ps, user) => {
- await addPinned(user, ps.noteId).catch(e => {
- if (e.id === '70c4e51f-5bea-449c-a030-53bee3cce202') throw new ApiError(meta.errors.noSuchNote);
- if (e.id === '15a018eb-58e5-4da1-93be-330fcc5e4e1a') throw new ApiError(meta.errors.pinLimitExceeded);
- if (e.id === '23f0cf4e-59a3-4276-a91d-61a5891c1514') throw new ApiError(meta.errors.alreadyPinned);
- throw e;
- });
-
- return await Users.pack(user.id, user, {
- detail: true
- });
-});
diff --git a/src/server/api/endpoints/i/read-all-messaging-messages.ts b/src/server/api/endpoints/i/read-all-messaging-messages.ts
deleted file mode 100644
index 9aca7611c9..0000000000
--- a/src/server/api/endpoints/i/read-all-messaging-messages.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { publishMainStream } from '@/services/stream';
-import define from '../../define';
-import { MessagingMessages, UserGroupJoinings } from '@/models/index';
-
-export const meta = {
- tags: ['account', 'messaging'],
-
- requireCredential: true as const,
-
- kind: 'write:account',
-
- params: {
- }
-};
-
-export default define(meta, async (ps, user) => {
- // Update documents
- await MessagingMessages.update({
- recipientId: user.id,
- isRead: false
- }, {
- isRead: true
- });
-
- const joinings = await UserGroupJoinings.find({ userId: user.id });
-
- await Promise.all(joinings.map(j => MessagingMessages.createQueryBuilder().update()
- .set({
- reads: (() => `array_append("reads", '${user.id}')`) as any
- })
- .where(`groupId = :groupId`, { groupId: j.userGroupId })
- .andWhere('userId != :userId', { userId: user.id })
- .andWhere('NOT (:userId = ANY(reads))', { userId: user.id })
- .execute()));
-
- publishMainStream(user.id, 'readAllMessagingMessages');
-});
diff --git a/src/server/api/endpoints/i/read-all-unread-notes.ts b/src/server/api/endpoints/i/read-all-unread-notes.ts
deleted file mode 100644
index 2a7102a590..0000000000
--- a/src/server/api/endpoints/i/read-all-unread-notes.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { publishMainStream } from '@/services/stream';
-import define from '../../define';
-import { NoteUnreads } from '@/models/index';
-
-export const meta = {
- tags: ['account'],
-
- requireCredential: true as const,
-
- kind: 'write:account',
-
- params: {
- }
-};
-
-export default define(meta, async (ps, user) => {
- // Remove documents
- await NoteUnreads.delete({
- userId: user.id
- });
-
- // 全て既読になったイベントを発行
- publishMainStream(user.id, 'readAllUnreadMentions');
- publishMainStream(user.id, 'readAllUnreadSpecifiedNotes');
-});
diff --git a/src/server/api/endpoints/i/read-announcement.ts b/src/server/api/endpoints/i/read-announcement.ts
deleted file mode 100644
index 2f5036f953..0000000000
--- a/src/server/api/endpoints/i/read-announcement.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import $ from 'cafy';
-import { ID } from '@/misc/cafy-id';
-import define from '../../define';
-import { ApiError } from '../../error';
-import { genId } from '@/misc/gen-id';
-import { AnnouncementReads, Announcements, Users } from '@/models/index';
-import { publishMainStream } from '@/services/stream';
-
-export const meta = {
- tags: ['account'],
-
- requireCredential: true as const,
-
- kind: 'write:account',
-
- params: {
- announcementId: {
- validator: $.type(ID),
- },
- },
-
- errors: {
- noSuchAnnouncement: {
- message: 'No such announcement.',
- code: 'NO_SUCH_ANNOUNCEMENT',
- id: '184663db-df88-4bc2-8b52-fb85f0681939'
- },
- }
-};
-
-export default define(meta, async (ps, user) => {
- // Check if announcement exists
- const announcement = await Announcements.findOne(ps.announcementId);
-
- if (announcement == null) {
- throw new ApiError(meta.errors.noSuchAnnouncement);
- }
-
- // Check if already read
- const read = await AnnouncementReads.findOne({
- announcementId: ps.announcementId,
- userId: user.id
- });
-
- if (read != null) {
- return;
- }
-
- // Create read
- await AnnouncementReads.insert({
- id: genId(),
- createdAt: new Date(),
- announcementId: ps.announcementId,
- userId: user.id,
- });
-
- if (!await Users.getHasUnreadAnnouncement(user.id)) {
- publishMainStream(user.id, 'readAllAnnouncements');
- }
-});
diff --git a/src/server/api/endpoints/i/regenerate-token.ts b/src/server/api/endpoints/i/regenerate-token.ts
deleted file mode 100644
index 1cce2d37be..0000000000
--- a/src/server/api/endpoints/i/regenerate-token.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import $ from 'cafy';
-import * as bcrypt from 'bcryptjs';
-import { publishMainStream, publishUserEvent } from '@/services/stream';
-import generateUserToken from '../../common/generate-native-user-token';
-import define from '../../define';
-import { Users, UserProfiles } from '@/models/index';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- password: {
- validator: $.str
- }
- }
-};
-
-export default define(meta, async (ps, user) => {
- const profile = await UserProfiles.findOneOrFail(user.id);
-
- // Compare password
- const same = await bcrypt.compare(ps.password, profile.password!);
-
- if (!same) {
- throw new Error('incorrect password');
- }
-
- // Generate secret
- const secret = generateUserToken();
-
- await Users.update(user.id, {
- token: secret
- });
-
- // Publish event
- publishMainStream(user.id, 'myTokenRegenerated');
-
- // Terminate streaming
- setTimeout(() => {
- publishUserEvent(user.id, 'terminate', {});
- }, 5000);
-});
diff --git a/src/server/api/endpoints/i/registry/get-all.ts b/src/server/api/endpoints/i/registry/get-all.ts
deleted file mode 100644
index c8eaf83a25..0000000000
--- a/src/server/api/endpoints/i/registry/get-all.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import $ from 'cafy';
-import define from '../../../define';
-import { RegistryItems } from '@/models/index';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- scope: {
- validator: $.optional.arr($.str.match(/^[a-zA-Z0-9_]+$/)),
- default: [],
- },
- }
-};
-
-export default define(meta, async (ps, user) => {
- const query = RegistryItems.createQueryBuilder('item')
- .where('item.domain IS NULL')
- .andWhere('item.userId = :userId', { userId: user.id })
- .andWhere('item.scope = :scope', { scope: ps.scope });
-
- const items = await query.getMany();
-
- const res = {} as Record<string, any>;
-
- for (const item of items) {
- res[item.key] = item.value;
- }
-
- return res;
-});
diff --git a/src/server/api/endpoints/i/registry/get-detail.ts b/src/server/api/endpoints/i/registry/get-detail.ts
deleted file mode 100644
index 992800c44c..0000000000
--- a/src/server/api/endpoints/i/registry/get-detail.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import $ from 'cafy';
-import define from '../../../define';
-import { RegistryItems } from '@/models/index';
-import { ApiError } from '../../../error';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- key: {
- validator: $.str
- },
-
- scope: {
- validator: $.optional.arr($.str.match(/^[a-zA-Z0-9_]+$/)),
- default: [],
- },
- },
-
- errors: {
- noSuchKey: {
- message: 'No such key.',
- code: 'NO_SUCH_KEY',
- id: '97a1e8e7-c0f7-47d2-957a-92e61256e01a'
- },
- },
-};
-
-export default define(meta, async (ps, user) => {
- const query = RegistryItems.createQueryBuilder('item')
- .where('item.domain IS NULL')
- .andWhere('item.userId = :userId', { userId: user.id })
- .andWhere('item.key = :key', { key: ps.key })
- .andWhere('item.scope = :scope', { scope: ps.scope });
-
- const item = await query.getOne();
-
- if (item == null) {
- throw new ApiError(meta.errors.noSuchKey);
- }
-
- return {
- updatedAt: item.updatedAt,
- value: item.value,
- };
-});
diff --git a/src/server/api/endpoints/i/registry/get.ts b/src/server/api/endpoints/i/registry/get.ts
deleted file mode 100644
index 569c3a9280..0000000000
--- a/src/server/api/endpoints/i/registry/get.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import $ from 'cafy';
-import define from '../../../define';
-import { RegistryItems } from '@/models/index';
-import { ApiError } from '../../../error';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- key: {
- validator: $.str
- },
-
- scope: {
- validator: $.optional.arr($.str.match(/^[a-zA-Z0-9_]+$/)),
- default: [],
- },
- },
-
- errors: {
- noSuchKey: {
- message: 'No such key.',
- code: 'NO_SUCH_KEY',
- id: 'ac3ed68a-62f0-422b-a7bc-d5e09e8f6a6a'
- },
- },
-};
-
-export default define(meta, async (ps, user) => {
- const query = RegistryItems.createQueryBuilder('item')
- .where('item.domain IS NULL')
- .andWhere('item.userId = :userId', { userId: user.id })
- .andWhere('item.key = :key', { key: ps.key })
- .andWhere('item.scope = :scope', { scope: ps.scope });
-
- const item = await query.getOne();
-
- if (item == null) {
- throw new ApiError(meta.errors.noSuchKey);
- }
-
- return item.value;
-});
diff --git a/src/server/api/endpoints/i/registry/keys-with-type.ts b/src/server/api/endpoints/i/registry/keys-with-type.ts
deleted file mode 100644
index 16a4fee374..0000000000
--- a/src/server/api/endpoints/i/registry/keys-with-type.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import $ from 'cafy';
-import define from '../../../define';
-import { RegistryItems } from '@/models/index';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- scope: {
- validator: $.optional.arr($.str.match(/^[a-zA-Z0-9_]+$/)),
- default: [],
- },
- }
-};
-
-export default define(meta, async (ps, user) => {
- const query = RegistryItems.createQueryBuilder('item')
- .where('item.domain IS NULL')
- .andWhere('item.userId = :userId', { userId: user.id })
- .andWhere('item.scope = :scope', { scope: ps.scope });
-
- const items = await query.getMany();
-
- const res = {} as Record<string, string>;
-
- for (const item of items) {
- const type = typeof item.value;
- res[item.key] =
- item.value === null ? 'null' :
- Array.isArray(item.value) ? 'array' :
- type === 'number' ? 'number' :
- type === 'string' ? 'string' :
- type === 'boolean' ? 'boolean' :
- type === 'object' ? 'object' :
- null as never;
- }
-
- return res;
-});
diff --git a/src/server/api/endpoints/i/registry/keys.ts b/src/server/api/endpoints/i/registry/keys.ts
deleted file mode 100644
index 3a8aeaa195..0000000000
--- a/src/server/api/endpoints/i/registry/keys.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import $ from 'cafy';
-import define from '../../../define';
-import { RegistryItems } from '@/models/index';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- scope: {
- validator: $.optional.arr($.str.match(/^[a-zA-Z0-9_]+$/)),
- default: [],
- },
- }
-};
-
-export default define(meta, async (ps, user) => {
- const query = RegistryItems.createQueryBuilder('item')
- .select('item.key')
- .where('item.domain IS NULL')
- .andWhere('item.userId = :userId', { userId: user.id })
- .andWhere('item.scope = :scope', { scope: ps.scope });
-
- const items = await query.getMany();
-
- return items.map(x => x.key);
-});
diff --git a/src/server/api/endpoints/i/registry/remove.ts b/src/server/api/endpoints/i/registry/remove.ts
deleted file mode 100644
index 07bc23d4a6..0000000000
--- a/src/server/api/endpoints/i/registry/remove.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import $ from 'cafy';
-import define from '../../../define';
-import { RegistryItems } from '@/models/index';
-import { ApiError } from '../../../error';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- key: {
- validator: $.str
- },
-
- scope: {
- validator: $.optional.arr($.str.match(/^[a-zA-Z0-9_]+$/)),
- default: [],
- },
- },
-
- errors: {
- noSuchKey: {
- message: 'No such key.',
- code: 'NO_SUCH_KEY',
- id: '1fac4e8a-a6cd-4e39-a4a5-3a7e11f1b019'
- },
- },
-};
-
-export default define(meta, async (ps, user) => {
- const query = RegistryItems.createQueryBuilder('item')
- .where('item.domain IS NULL')
- .andWhere('item.userId = :userId', { userId: user.id })
- .andWhere('item.key = :key', { key: ps.key })
- .andWhere('item.scope = :scope', { scope: ps.scope });
-
- const item = await query.getOne();
-
- if (item == null) {
- throw new ApiError(meta.errors.noSuchKey);
- }
-
- await RegistryItems.remove(item);
-});
diff --git a/src/server/api/endpoints/i/registry/scopes.ts b/src/server/api/endpoints/i/registry/scopes.ts
deleted file mode 100644
index ecbdb05a8e..0000000000
--- a/src/server/api/endpoints/i/registry/scopes.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import define from '../../../define';
-import { RegistryItems } from '@/models/index';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- }
-};
-
-export default define(meta, async (ps, user) => {
- const query = RegistryItems.createQueryBuilder('item')
- .select('item.scope')
- .where('item.domain IS NULL')
- .andWhere('item.userId = :userId', { userId: user.id });
-
- const items = await query.getMany();
-
- const res = [] as string[][];
-
- for (const item of items) {
- if (res.some(scope => scope.join('.') === item.scope.join('.'))) continue;
- res.push(item.scope);
- }
-
- return res;
-});
diff --git a/src/server/api/endpoints/i/registry/set.ts b/src/server/api/endpoints/i/registry/set.ts
deleted file mode 100644
index f129ee1b70..0000000000
--- a/src/server/api/endpoints/i/registry/set.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import $ from 'cafy';
-import { publishMainStream } from '@/services/stream';
-import define from '../../../define';
-import { RegistryItems } from '@/models/index';
-import { genId } from '@/misc/gen-id';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- key: {
- validator: $.str.min(1)
- },
-
- value: {
- validator: $.nullable.any
- },
-
- scope: {
- validator: $.optional.arr($.str.match(/^[a-zA-Z0-9_]+$/)),
- default: [],
- },
- }
-};
-
-export default define(meta, async (ps, user) => {
- const query = RegistryItems.createQueryBuilder('item')
- .where('item.domain IS NULL')
- .andWhere('item.userId = :userId', { userId: user.id })
- .andWhere('item.key = :key', { key: ps.key })
- .andWhere('item.scope = :scope', { scope: ps.scope });
-
- const existingItem = await query.getOne();
-
- if (existingItem) {
- await RegistryItems.update(existingItem.id, {
- updatedAt: new Date(),
- value: ps.value
- });
- } else {
- await RegistryItems.insert({
- id: genId(),
- createdAt: new Date(),
- updatedAt: new Date(),
- userId: user.id,
- domain: null,
- scope: ps.scope,
- key: ps.key,
- value: ps.value
- });
- }
-
- // TODO: サードパーティアプリが傍受出来てしまうのでどうにかする
- publishMainStream(user.id, 'registryUpdated', {
- scope: ps.scope,
- key: ps.key,
- value: ps.value
- });
-});
diff --git a/src/server/api/endpoints/i/revoke-token.ts b/src/server/api/endpoints/i/revoke-token.ts
deleted file mode 100644
index bed868def4..0000000000
--- a/src/server/api/endpoints/i/revoke-token.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import $ from 'cafy';
-import define from '../../define';
-import { AccessTokens } from '@/models/index';
-import { ID } from '@/misc/cafy-id';
-import { publishUserEvent } from '@/services/stream';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- tokenId: {
- validator: $.type(ID)
- }
- }
-};
-
-export default define(meta, async (ps, user) => {
- const token = await AccessTokens.findOne(ps.tokenId);
-
- if (token) {
- await AccessTokens.delete({
- id: ps.tokenId,
- userId: user.id,
- });
-
- // Terminate streaming
- publishUserEvent(user.id, 'terminate');
- }
-});
diff --git a/src/server/api/endpoints/i/signin-history.ts b/src/server/api/endpoints/i/signin-history.ts
deleted file mode 100644
index a2c10148c6..0000000000
--- a/src/server/api/endpoints/i/signin-history.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import $ from 'cafy';
-import { ID } from '@/misc/cafy-id';
-import define from '../../define';
-import { Signins } from '@/models/index';
-import { makePaginationQuery } from '../../common/make-pagination-query';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- params: {
- limit: {
- validator: $.optional.num.range(1, 100),
- default: 10
- },
-
- sinceId: {
- validator: $.optional.type(ID),
- },
-
- untilId: {
- validator: $.optional.type(ID),
- }
- }
-};
-
-export default define(meta, async (ps, user) => {
- const query = makePaginationQuery(Signins.createQueryBuilder('signin'), ps.sinceId, ps.untilId)
- .andWhere(`signin.userId = :meId`, { meId: user.id });
-
- const history = await query.take(ps.limit!).getMany();
-
- return await Promise.all(history.map(record => Signins.pack(record)));
-});
diff --git a/src/server/api/endpoints/i/unpin.ts b/src/server/api/endpoints/i/unpin.ts
deleted file mode 100644
index dc79e255ab..0000000000
--- a/src/server/api/endpoints/i/unpin.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import $ from 'cafy';
-import { ID } from '@/misc/cafy-id';
-import { removePinned } from '@/services/i/pin';
-import define from '../../define';
-import { ApiError } from '../../error';
-import { Users } from '@/models/index';
-
-export const meta = {
- tags: ['account', 'notes'],
-
- requireCredential: true as const,
-
- kind: 'write:account',
-
- params: {
- noteId: {
- validator: $.type(ID),
- }
- },
-
- errors: {
- noSuchNote: {
- message: 'No such note.',
- code: 'NO_SUCH_NOTE',
- id: '454170ce-9d63-4a43-9da1-ea10afe81e21'
- },
- },
-
- res: {
- type: 'object' as const,
- optional: false as const, nullable: false as const,
- ref: 'User'
- }
-};
-
-export default define(meta, async (ps, user) => {
- await removePinned(user, ps.noteId).catch(e => {
- if (e.id === 'b302d4cf-c050-400a-bbb3-be208681f40c') throw new ApiError(meta.errors.noSuchNote);
- throw e;
- });
-
- return await Users.pack(user.id, user, {
- detail: true
- });
-});
diff --git a/src/server/api/endpoints/i/update-email.ts b/src/server/api/endpoints/i/update-email.ts
deleted file mode 100644
index 9b6fb9c410..0000000000
--- a/src/server/api/endpoints/i/update-email.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-import $ from 'cafy';
-import { publishMainStream } from '@/services/stream';
-import define from '../../define';
-import rndstr from 'rndstr';
-import config from '@/config/index';
-import * as ms from 'ms';
-import * as bcrypt from 'bcryptjs';
-import { Users, UserProfiles } from '@/models/index';
-import { sendEmail } from '@/services/send-email';
-import { ApiError } from '../../error';
-import { validateEmailForAccount } from '@/services/validate-email-for-account';
-
-export const meta = {
- requireCredential: true as const,
-
- secure: true,
-
- limit: {
- duration: ms('1hour'),
- max: 3
- },
-
- params: {
- password: {
- validator: $.str
- },
-
- email: {
- validator: $.optional.nullable.str
- },
- },
-
- errors: {
- incorrectPassword: {
- message: 'Incorrect password.',
- code: 'INCORRECT_PASSWORD',
- id: 'e54c1d7e-e7d6-4103-86b6-0a95069b4ad3'
- },
-
- unavailable: {
- message: 'Unavailable email address.',
- code: 'UNAVAILABLE',
- id: 'a2defefb-f220-8849-0af6-17f816099323'
- },
- }
-};
-
-export default define(meta, async (ps, user) => {
- const profile = await UserProfiles.findOneOrFail(user.id);
-
- // Compare password
- const same = await bcrypt.compare(ps.password, profile.password!);
-
- if (!same) {
- throw new ApiError(meta.errors.incorrectPassword);
- }
-
- if (ps.email != null) {
- const available = await validateEmailForAccount(ps.email);
- if (!available) {
- throw new ApiError(meta.errors.unavailable);
- }
- }
-
- await UserProfiles.update(user.id, {
- email: ps.email,
- emailVerified: false,
- emailVerifyCode: null
- });
-
- const iObj = await Users.pack(user.id, user, {
- detail: true,
- includeSecrets: true
- });
-
- // Publish meUpdated event
- publishMainStream(user.id, 'meUpdated', iObj);
-
- if (ps.email != null) {
- const code = rndstr('a-z0-9', 16);
-
- await UserProfiles.update(user.id, {
- emailVerifyCode: code
- });
-
- const link = `${config.url}/verify-email/${code}`;
-
- sendEmail(ps.email, 'Email verification',
- `To verify email, please click this link:<br><a href="${link}">${link}</a>`,
- `To verify email, please click this link: ${link}`);
- }
-
- return iObj;
-});
diff --git a/src/server/api/endpoints/i/update.ts b/src/server/api/endpoints/i/update.ts
deleted file mode 100644
index d0f201ab60..0000000000
--- a/src/server/api/endpoints/i/update.ts
+++ /dev/null
@@ -1,294 +0,0 @@
-import $ from 'cafy';
-import * as mfm from 'mfm-js';
-import { ID } from '@/misc/cafy-id';
-import { publishMainStream, publishUserEvent } from '@/services/stream';
-import acceptAllFollowRequests from '@/services/following/requests/accept-all';
-import { publishToFollowers } from '@/services/i/update';
-import define from '../../define';
-import { extractCustomEmojisFromMfm } from '@/misc/extract-custom-emojis-from-mfm';
-import { extractHashtags } from '@/misc/extract-hashtags';
-import * as langmap from 'langmap';
-import { updateUsertags } from '@/services/update-hashtag';
-import { ApiError } from '../../error';
-import { Users, DriveFiles, UserProfiles, Pages } from '@/models/index';
-import { User } from '@/models/entities/user';
-import { UserProfile } from '@/models/entities/user-profile';
-import { notificationTypes } from '@/types';
-import { normalizeForSearch } from '@/misc/normalize-for-search';
-
-export const meta = {
- tags: ['account'],
-
- requireCredential: true as const,
-
- kind: 'write:account',
-
- params: {
- name: {
- validator: $.optional.nullable.use(Users.validateName),
- },
-
- description: {
- validator: $.optional.nullable.use(Users.validateDescription),
- },
-
- lang: {
- validator: $.optional.nullable.str.or(Object.keys(langmap)),
- },
-
- location: {
- validator: $.optional.nullable.use(Users.validateLocation),
- },
-
- birthday: {
- validator: $.optional.nullable.use(Users.validateBirthday),
- },
-
- avatarId: {
- validator: $.optional.nullable.type(ID),
- },
-
- bannerId: {
- validator: $.optional.nullable.type(ID),
- },
-
- fields: {
- validator: $.optional.arr($.object()).range(1, 4),
- },
-
- isLocked: {
- validator: $.optional.bool,
- },
-
- isExplorable: {
- validator: $.optional.bool,
- },
-
- hideOnlineStatus: {
- validator: $.optional.bool,
- },
-
- publicReactions: {
- validator: $.optional.bool,
- },
-
- ffVisibility: {
- validator: $.optional.str,
- },
-
- carefulBot: {
- validator: $.optional.bool,
- },
-
- autoAcceptFollowed: {
- validator: $.optional.bool,
- },
-
- noCrawle: {
- validator: $.optional.bool,
- },
-
- isBot: {
- validator: $.optional.bool,
- },
-
- isCat: {
- validator: $.optional.bool,
- },
-
- injectFeaturedNote: {
- validator: $.optional.bool,
- },
-
- receiveAnnouncementEmail: {
- validator: $.optional.bool,
- },
-
- alwaysMarkNsfw: {
- validator: $.optional.bool,
- },
-
- pinnedPageId: {
- validator: $.optional.nullable.type(ID),
- },
-
- mutedWords: {
- validator: $.optional.arr($.arr($.str))
- },
-
- mutingNotificationTypes: {
- validator: $.optional.arr($.str.or(notificationTypes as unknown as string[]))
- },
-
- emailNotificationTypes: {
- validator: $.optional.arr($.str)
- },
- },
-
- errors: {
- noSuchAvatar: {
- message: 'No such avatar file.',
- code: 'NO_SUCH_AVATAR',
- id: '539f3a45-f215-4f81-a9a8-31293640207f'
- },
-
- noSuchBanner: {
- message: 'No such banner file.',
- code: 'NO_SUCH_BANNER',
- id: '0d8f5629-f210-41c2-9433-735831a58595'
- },
-
- avatarNotAnImage: {
- message: 'The file specified as an avatar is not an image.',
- code: 'AVATAR_NOT_AN_IMAGE',
- id: 'f419f9f8-2f4d-46b1-9fb4-49d3a2fd7191'
- },
-
- bannerNotAnImage: {
- message: 'The file specified as a banner is not an image.',
- code: 'BANNER_NOT_AN_IMAGE',
- id: '75aedb19-2afd-4e6d-87fc-67941256fa60'
- },
-
- noSuchPage: {
- message: 'No such page.',
- code: 'NO_SUCH_PAGE',
- id: '8e01b590-7eb9-431b-a239-860e086c408e'
- },
- },
-
- res: {
- type: 'object' as const,
- optional: false as const, nullable: false as const,
- ref: 'User'
- }
-};
-
-export default define(meta, async (ps, _user, token) => {
- const user = await Users.findOneOrFail(_user.id);
- const isSecure = token == null;
-
- const updates = {} as Partial<User>;
- const profileUpdates = {} as Partial<UserProfile>;
-
- const profile = await UserProfiles.findOneOrFail(user.id);
-
- if (ps.name !== undefined) updates.name = ps.name;
- if (ps.description !== undefined) profileUpdates.description = ps.description;
- if (ps.lang !== undefined) profileUpdates.lang = ps.lang;
- if (ps.location !== undefined) profileUpdates.location = ps.location;
- if (ps.birthday !== undefined) profileUpdates.birthday = ps.birthday;
- if (ps.ffVisibility !== undefined) profileUpdates.ffVisibility = ps.ffVisibility;
- if (ps.avatarId !== undefined) updates.avatarId = ps.avatarId;
- if (ps.bannerId !== undefined) updates.bannerId = ps.bannerId;
- if (ps.mutedWords !== undefined) {
- profileUpdates.mutedWords = ps.mutedWords;
- profileUpdates.enableWordMute = ps.mutedWords.length > 0;
- }
- if (ps.mutingNotificationTypes !== undefined) profileUpdates.mutingNotificationTypes = ps.mutingNotificationTypes as typeof notificationTypes[number][];
- if (typeof ps.isLocked === 'boolean') updates.isLocked = ps.isLocked;
- if (typeof ps.isExplorable === 'boolean') updates.isExplorable = ps.isExplorable;
- if (typeof ps.hideOnlineStatus === 'boolean') updates.hideOnlineStatus = ps.hideOnlineStatus;
- if (typeof ps.publicReactions === 'boolean') profileUpdates.publicReactions = ps.publicReactions;
- if (typeof ps.isBot === 'boolean') updates.isBot = ps.isBot;
- if (typeof ps.carefulBot === 'boolean') profileUpdates.carefulBot = ps.carefulBot;
- if (typeof ps.autoAcceptFollowed === 'boolean') profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed;
- if (typeof ps.noCrawle === 'boolean') profileUpdates.noCrawle = ps.noCrawle;
- if (typeof ps.isCat === 'boolean') updates.isCat = ps.isCat;
- if (typeof ps.injectFeaturedNote === 'boolean') profileUpdates.injectFeaturedNote = ps.injectFeaturedNote;
- if (typeof ps.receiveAnnouncementEmail === 'boolean') profileUpdates.receiveAnnouncementEmail = ps.receiveAnnouncementEmail;
- if (typeof ps.alwaysMarkNsfw === 'boolean') profileUpdates.alwaysMarkNsfw = ps.alwaysMarkNsfw;
- if (ps.emailNotificationTypes !== undefined) profileUpdates.emailNotificationTypes = ps.emailNotificationTypes;
-
- if (ps.avatarId) {
- const avatar = await DriveFiles.findOne(ps.avatarId);
-
- if (avatar == null || avatar.userId !== user.id) throw new ApiError(meta.errors.noSuchAvatar);
- if (!avatar.type.startsWith('image/')) throw new ApiError(meta.errors.avatarNotAnImage);
-
- updates.avatarUrl = DriveFiles.getPublicUrl(avatar, true);
-
- if (avatar.blurhash) {
- updates.avatarBlurhash = avatar.blurhash;
- }
- }
-
- if (ps.bannerId) {
- const banner = await DriveFiles.findOne(ps.bannerId);
-
- if (banner == null || banner.userId !== user.id) throw new ApiError(meta.errors.noSuchBanner);
- if (!banner.type.startsWith('image/')) throw new ApiError(meta.errors.bannerNotAnImage);
-
- updates.bannerUrl = DriveFiles.getPublicUrl(banner, false);
-
- if (banner.blurhash) {
- updates.bannerBlurhash = banner.blurhash;
- }
- }
-
- if (ps.pinnedPageId) {
- const page = await Pages.findOne(ps.pinnedPageId);
-
- if (page == null || page.userId !== user.id) throw new ApiError(meta.errors.noSuchPage);
-
- profileUpdates.pinnedPageId = page.id;
- } else if (ps.pinnedPageId === null) {
- profileUpdates.pinnedPageId = null;
- }
-
- if (ps.fields) {
- profileUpdates.fields = ps.fields
- .filter(x => typeof x.name === 'string' && x.name !== '' && typeof x.value === 'string' && x.value !== '')
- .map(x => {
- return { name: x.name, value: x.value };
- });
- }
-
- //#region emojis/tags
-
- let emojis = [] as string[];
- let tags = [] as string[];
-
- const newName = updates.name === undefined ? user.name : updates.name;
- const newDescription = profileUpdates.description === undefined ? profile.description : profileUpdates.description;
-
- if (newName != null) {
- const tokens = mfm.parsePlain(newName);
- emojis = emojis.concat(extractCustomEmojisFromMfm(tokens!));
- }
-
- if (newDescription != null) {
- const tokens = mfm.parse(newDescription);
- emojis = emojis.concat(extractCustomEmojisFromMfm(tokens!));
- tags = extractHashtags(tokens!).map(tag => normalizeForSearch(tag)).splice(0, 32);
- }
-
- updates.emojis = emojis;
- updates.tags = tags;
-
- // ハッシュタグ更新
- updateUsertags(user, tags);
- //#endregion
-
- if (Object.keys(updates).length > 0) await Users.update(user.id, updates);
- if (Object.keys(profileUpdates).length > 0) await UserProfiles.update(user.id, profileUpdates);
-
- const iObj = await Users.pack(user.id, user, {
- detail: true,
- includeSecrets: isSecure
- });
-
- // Publish meUpdated event
- publishMainStream(user.id, 'meUpdated', iObj);
- publishUserEvent(user.id, 'updateUserProfile', await UserProfiles.findOne(user.id));
-
- // 鍵垢を解除したとき、溜まっていたフォローリクエストがあるならすべて承認
- if (user.isLocked && ps.isLocked === false) {
- acceptAllFollowRequests(user);
- }
-
- // フォロワーにUpdateを配信
- publishToFollowers(user.id);
-
- return iObj;
-});
diff --git a/src/server/api/endpoints/i/user-group-invites.ts b/src/server/api/endpoints/i/user-group-invites.ts
deleted file mode 100644
index 1ebde243ca..0000000000
--- a/src/server/api/endpoints/i/user-group-invites.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import $ from 'cafy';
-import { ID } from '@/misc/cafy-id';
-import define from '../../define';
-import { UserGroupInvitations } from '@/models/index';
-import { makePaginationQuery } from '../../common/make-pagination-query';
-
-export const meta = {
- tags: ['account', 'groups'],
-
- requireCredential: true as const,
-
- kind: 'read:user-groups',
-
- params: {
- limit: {
- validator: $.optional.num.range(1, 100),
- default: 10
- },
-
- sinceId: {
- validator: $.optional.type(ID),
- },
-
- untilId: {
- validator: $.optional.type(ID),
- },
- },
-
- res: {
- type: 'array' as const,
- optional: false as const, nullable: false as const,
- items: {
- type: 'object' as const,
- optional: false as const, nullable: false as const,
- properties: {
- id: {
- type: 'string' as const,
- optional: false as const, nullable: false as const,
- format: 'id'
- },
- group: {
- type: 'object' as const,
- optional: false as const, nullable: false as const,
- ref: 'UserGroup'
- }
- }
- }
- }
-};
-
-export default define(meta, async (ps, user) => {
- const query = makePaginationQuery(UserGroupInvitations.createQueryBuilder('invitation'), ps.sinceId, ps.untilId)
- .andWhere(`invitation.userId = :meId`, { meId: user.id })
- .leftJoinAndSelect('invitation.userGroup', 'user_group');
-
- const invitations = await query
- .take(ps.limit!)
- .getMany();
-
- return await UserGroupInvitations.packMany(invitations);
-});