summaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2021-10-16 19:55:44 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2021-10-16 19:55:44 +0900
commit8a1f3a4c0b5732d0f08f0788d93c5934de8960c8 (patch)
treebe6fbcf3a1bbd78306d91e19ef6f3e7023f41561 /src/server
parentMerge branch 'develop' (diff)
parent12.92.0 (diff)
downloadmisskey-8a1f3a4c0b5732d0f08f0788d93c5934de8960c8.tar.gz
misskey-8a1f3a4c0b5732d0f08f0788d93c5934de8960c8.tar.bz2
misskey-8a1f3a4c0b5732d0f08f0788d93c5934de8960c8.zip
Merge branch 'develop'
Diffstat (limited to 'src/server')
-rw-r--r--src/server/api/common/signup.ts26
-rw-r--r--src/server/api/endpoints/admin/accounts/create.ts5
-rw-r--r--src/server/api/endpoints/admin/drive/files.ts2
-rw-r--r--src/server/api/endpoints/admin/queue/inbox-delayed.ts2
-rw-r--r--src/server/api/endpoints/admin/update-meta.ts8
-rw-r--r--src/server/api/endpoints/ap/get.ts8
-rw-r--r--src/server/api/endpoints/ap/show.ts8
-rw-r--r--src/server/api/endpoints/blocking/create.ts14
-rw-r--r--src/server/api/endpoints/drive/files/update.ts3
-rw-r--r--src/server/api/endpoints/drive/files/upload-from-url.ts3
-rw-r--r--src/server/api/endpoints/email-address/available.ts37
-rw-r--r--src/server/api/endpoints/i/notifications.ts11
-rw-r--r--src/server/api/endpoints/i/update.ts2
-rw-r--r--src/server/api/endpoints/meta.ts6
-rw-r--r--src/server/api/endpoints/users/groups/leave.ts50
-rw-r--r--src/server/api/index.ts2
-rw-r--r--src/server/api/private/signup-pending.ts35
-rw-r--r--src/server/api/private/signup.ts62
-rw-r--r--src/server/file/send-drive-file.ts5
-rw-r--r--src/server/index.ts4
-rw-r--r--src/server/nodeinfo.ts1
-rw-r--r--src/server/proxy/proxy-media.ts5
-rw-r--r--src/server/web/manifest.json2
23 files changed, 264 insertions, 37 deletions
diff --git a/src/server/api/common/signup.ts b/src/server/api/common/signup.ts
index eb3aa09c8c..2ba0d8e479 100644
--- a/src/server/api/common/signup.ts
+++ b/src/server/api/common/signup.ts
@@ -11,20 +11,30 @@ import { UserKeypair } from '@/models/entities/user-keypair';
import { usersChart } from '@/services/chart/index';
import { UsedUsername } from '@/models/entities/used-username';
-export async function signup(username: User['username'], password: UserProfile['password'], host: string | null = null) {
+export async function signup(opts: {
+ username: User['username'];
+ password?: string | null;
+ passwordHash?: UserProfile['password'] | null;
+ host?: string | null;
+}) {
+ const { username, password, passwordHash, host } = opts;
+ let hash = passwordHash;
+
// Validate username
if (!Users.validateLocalUsername.ok(username)) {
throw new Error('INVALID_USERNAME');
}
- // Validate password
- if (!Users.validatePassword.ok(password)) {
- throw new Error('INVALID_PASSWORD');
- }
+ if (password != null && passwordHash == null) {
+ // Validate password
+ if (!Users.validatePassword.ok(password)) {
+ throw new Error('INVALID_PASSWORD');
+ }
- // Generate hash of password
- const salt = await bcrypt.genSalt(8);
- const hash = await bcrypt.hash(password, salt);
+ // Generate hash of password
+ const salt = await bcrypt.genSalt(8);
+ hash = await bcrypt.hash(password, salt);
+ }
// Generate secret
const secret = generateUserToken();
diff --git a/src/server/api/endpoints/admin/accounts/create.ts b/src/server/api/endpoints/admin/accounts/create.ts
index 9691b9c7e3..fa15e84f77 100644
--- a/src/server/api/endpoints/admin/accounts/create.ts
+++ b/src/server/api/endpoints/admin/accounts/create.ts
@@ -35,7 +35,10 @@ export default define(meta, async (ps, _me) => {
})) === 0;
if (!noUsers && !me?.isAdmin) throw new Error('access denied');
- const { account, secret } = await signup(ps.username, ps.password);
+ const { account, secret } = await signup({
+ username: ps.username,
+ password: ps.password,
+ });
const res = await Users.pack(account, account, {
detail: true,
diff --git a/src/server/api/endpoints/admin/drive/files.ts b/src/server/api/endpoints/admin/drive/files.ts
index c0788c8e02..fe1c799805 100644
--- a/src/server/api/endpoints/admin/drive/files.ts
+++ b/src/server/api/endpoints/admin/drive/files.ts
@@ -25,7 +25,7 @@ export const meta = {
},
type: {
- validator: $.optional.nullable.str.match(/^[a-zA-Z\/\-*]+$/)
+ validator: $.optional.nullable.str.match(/^[a-zA-Z0-9\/\-*]+$/)
},
origin: {
diff --git a/src/server/api/endpoints/admin/queue/inbox-delayed.ts b/src/server/api/endpoints/admin/queue/inbox-delayed.ts
index 59e5c834ed..1925906c28 100644
--- a/src/server/api/endpoints/admin/queue/inbox-delayed.ts
+++ b/src/server/api/endpoints/admin/queue/inbox-delayed.ts
@@ -1,6 +1,6 @@
import { URL } from 'url';
import define from '../../../define';
-import { inboxQueue } from '@/queue/index';
+import { inboxQueue } from '@/queue/queues';
export const meta = {
tags: ['admin'],
diff --git a/src/server/api/endpoints/admin/update-meta.ts b/src/server/api/endpoints/admin/update-meta.ts
index 46f30fef7d..55447098dc 100644
--- a/src/server/api/endpoints/admin/update-meta.ts
+++ b/src/server/api/endpoints/admin/update-meta.ts
@@ -93,6 +93,10 @@ export const meta = {
validator: $.optional.bool,
},
+ emailRequiredForSignup: {
+ validator: $.optional.bool,
+ },
+
enableHcaptcha: {
validator: $.optional.bool,
},
@@ -374,6 +378,10 @@ export default define(meta, async (ps, me) => {
set.proxyRemoteFiles = ps.proxyRemoteFiles;
}
+ if (ps.emailRequiredForSignup !== undefined) {
+ set.emailRequiredForSignup = ps.emailRequiredForSignup;
+ }
+
if (ps.enableHcaptcha !== undefined) {
set.enableHcaptcha = ps.enableHcaptcha;
}
diff --git a/src/server/api/endpoints/ap/get.ts b/src/server/api/endpoints/ap/get.ts
index 2cffce1f16..78919f43b0 100644
--- a/src/server/api/endpoints/ap/get.ts
+++ b/src/server/api/endpoints/ap/get.ts
@@ -2,11 +2,17 @@ import $ from 'cafy';
import define from '../../define';
import Resolver from '@/remote/activitypub/resolver';
import { ApiError } from '../../error';
+import * as ms from 'ms';
export const meta = {
tags: ['federation'],
- requireCredential: false as const,
+ requireCredential: true as const,
+
+ limit: {
+ duration: ms('1hour'),
+ max: 30
+ },
params: {
uri: {
diff --git a/src/server/api/endpoints/ap/show.ts b/src/server/api/endpoints/ap/show.ts
index aa0dae070c..2280d93724 100644
--- a/src/server/api/endpoints/ap/show.ts
+++ b/src/server/api/endpoints/ap/show.ts
@@ -11,11 +11,17 @@ import { Note } from '@/models/entities/note';
import { User } from '@/models/entities/user';
import { fetchMeta } from '@/misc/fetch-meta';
import { isActor, isPost, getApId } from '@/remote/activitypub/type';
+import * as ms from 'ms';
export const meta = {
tags: ['federation'],
- requireCredential: false as const,
+ requireCredential: true as const,
+
+ limit: {
+ duration: ms('1hour'),
+ max: 30
+ },
params: {
uri: {
diff --git a/src/server/api/endpoints/blocking/create.ts b/src/server/api/endpoints/blocking/create.ts
index 1bf5cf374b..4deaa39974 100644
--- a/src/server/api/endpoints/blocking/create.ts
+++ b/src/server/api/endpoints/blocking/create.ts
@@ -43,6 +43,12 @@ export const meta = {
code: 'ALREADY_BLOCKING',
id: '787fed64-acb9-464a-82eb-afbd745b9614'
},
+
+ cannotBlockModerator: {
+ message: 'Cannot block a moderator or an admin.',
+ code: 'CANNOT_BLOCK_MODERATOR',
+ id: '8544aaef-89fb-e470-9f6c-385d38b474f5'
+ }
},
res: {
@@ -76,8 +82,12 @@ export default define(meta, async (ps, user) => {
throw new ApiError(meta.errors.alreadyBlocking);
}
- // Create blocking
- await create(blocker, blockee);
+ try {
+ await create(blocker, blockee);
+ } catch (e) {
+ if (e.id === 'e42b7890-5e4d-9d9c-d54b-cf4dd30adfb5') throw new ApiError(meta.errors.cannotBlockModerator);
+ throw e;
+ }
NoteWatchings.delete({
userId: blocker.id,
diff --git a/src/server/api/endpoints/drive/files/update.ts b/src/server/api/endpoints/drive/files/update.ts
index 1ef445625c..f277a9c3dc 100644
--- a/src/server/api/endpoints/drive/files/update.ts
+++ b/src/server/api/endpoints/drive/files/update.ts
@@ -4,6 +4,7 @@ import { publishDriveStream } from '@/services/stream';
import define from '../../../define';
import { ApiError } from '../../../error';
import { DriveFiles, DriveFolders } from '@/models/index';
+import { DB_MAX_IMAGE_COMMENT_LENGTH } from '@/misc/hard-limits';
export const meta = {
tags: ['drive'],
@@ -33,7 +34,7 @@ export const meta = {
},
comment: {
- validator: $.optional.nullable.str,
+ validator: $.optional.nullable.str.max(DB_MAX_IMAGE_COMMENT_LENGTH),
default: undefined as any,
}
},
diff --git a/src/server/api/endpoints/drive/files/upload-from-url.ts b/src/server/api/endpoints/drive/files/upload-from-url.ts
index f37f316efb..9f10a42d24 100644
--- a/src/server/api/endpoints/drive/files/upload-from-url.ts
+++ b/src/server/api/endpoints/drive/files/upload-from-url.ts
@@ -5,6 +5,7 @@ import uploadFromUrl from '@/services/drive/upload-from-url';
import define from '../../../define';
import { DriveFiles } from '@/models/index';
import { publishMainStream } from '@/services/stream';
+import { DB_MAX_IMAGE_COMMENT_LENGTH } from '@/misc/hard-limits';
export const meta = {
tags: ['drive'],
@@ -35,7 +36,7 @@ export const meta = {
},
comment: {
- validator: $.optional.nullable.str,
+ validator: $.optional.nullable.str.max(DB_MAX_IMAGE_COMMENT_LENGTH),
default: null,
},
diff --git a/src/server/api/endpoints/email-address/available.ts b/src/server/api/endpoints/email-address/available.ts
new file mode 100644
index 0000000000..65fe6f9178
--- /dev/null
+++ b/src/server/api/endpoints/email-address/available.ts
@@ -0,0 +1,37 @@
+import $ from 'cafy';
+import define from '../../define';
+import { UserProfiles } from '@/models/index';
+
+export const meta = {
+ tags: ['users'],
+
+ requireCredential: false as const,
+
+ params: {
+ emailAddress: {
+ validator: $.str
+ }
+ },
+
+ res: {
+ type: 'object' as const,
+ optional: false as const, nullable: false as const,
+ properties: {
+ available: {
+ type: 'boolean' as const,
+ optional: false as const, nullable: false as const,
+ }
+ }
+ }
+};
+
+export default define(meta, async (ps) => {
+ const exist = await UserProfiles.count({
+ emailVerified: true,
+ email: ps.emailAddress,
+ });
+
+ return {
+ available: exist === 0
+ };
+});
diff --git a/src/server/api/endpoints/i/notifications.ts b/src/server/api/endpoints/i/notifications.ts
index 3c265a10c1..fcabbbc3dd 100644
--- a/src/server/api/endpoints/i/notifications.ts
+++ b/src/server/api/endpoints/i/notifications.ts
@@ -4,7 +4,7 @@ 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 { notificationTypes } from '@/types';
import read from '@/services/note/read';
export const meta = {
@@ -33,6 +33,11 @@ export const meta = {
default: false
},
+ unreadOnly: {
+ validator: $.optional.bool,
+ default: false
+ },
+
markAsRead: {
validator: $.optional.bool,
default: true
@@ -105,6 +110,10 @@ export default define(meta, async (ps, user) => {
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
diff --git a/src/server/api/endpoints/i/update.ts b/src/server/api/endpoints/i/update.ts
index fb7e12760e..9dd637251d 100644
--- a/src/server/api/endpoints/i/update.ts
+++ b/src/server/api/endpoints/i/update.ts
@@ -13,7 +13,7 @@ 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 { notificationTypes } from '@/types';
import { normalizeForSearch } from '@/misc/normalize-for-search';
export const meta = {
diff --git a/src/server/api/endpoints/meta.ts b/src/server/api/endpoints/meta.ts
index 3f422dff07..ce21556243 100644
--- a/src/server/api/endpoints/meta.ts
+++ b/src/server/api/endpoints/meta.ts
@@ -104,6 +104,10 @@ export const meta = {
type: 'boolean' as const,
optional: false as const, nullable: false as const
},
+ emailRequiredForSignup: {
+ type: 'boolean' as const,
+ optional: false as const, nullable: false as const
+ },
enableHcaptcha: {
type: 'boolean' as const,
optional: false as const, nullable: false as const
@@ -488,6 +492,7 @@ export default define(meta, async (ps, me) => {
disableGlobalTimeline: instance.disableGlobalTimeline,
driveCapacityPerLocalUserMb: instance.localDriveCapacityMb,
driveCapacityPerRemoteUserMb: instance.remoteDriveCapacityMb,
+ emailRequiredForSignup: instance.emailRequiredForSignup,
enableHcaptcha: instance.enableHcaptcha,
hcaptchaSiteKey: instance.hcaptchaSiteKey,
enableRecaptcha: instance.enableRecaptcha,
@@ -537,6 +542,7 @@ export default define(meta, async (ps, me) => {
registration: !instance.disableRegistration,
localTimeLine: !instance.disableLocalTimeline,
globalTimeLine: !instance.disableGlobalTimeline,
+ emailRequiredForSignup: instance.emailRequiredForSignup,
elasticsearch: config.elasticsearch ? true : false,
hcaptcha: instance.enableHcaptcha,
recaptcha: instance.enableRecaptcha,
diff --git a/src/server/api/endpoints/users/groups/leave.ts b/src/server/api/endpoints/users/groups/leave.ts
new file mode 100644
index 0000000000..0e52f2abdf
--- /dev/null
+++ b/src/server/api/endpoints/users/groups/leave.ts
@@ -0,0 +1,50 @@
+import $ from 'cafy';
+import { ID } from '@/misc/cafy-id';
+import define from '../../../define';
+import { ApiError } from '../../../error';
+import { UserGroups, UserGroupJoinings } from '@/models/index';
+
+export const meta = {
+ tags: ['groups', 'users'],
+
+ requireCredential: true as const,
+
+ kind: 'write:user-groups',
+
+ params: {
+ groupId: {
+ validator: $.type(ID),
+ },
+ },
+
+ errors: {
+ noSuchGroup: {
+ message: 'No such group.',
+ code: 'NO_SUCH_GROUP',
+ id: '62780270-1f67-5dc0-daca-3eb510612e31'
+ },
+
+ youAreOwner: {
+ message: 'Your are the owner.',
+ code: 'YOU_ARE_OWNER',
+ id: 'b6d6e0c2-ef8a-9bb8-653d-79f4a3107c69'
+ },
+ }
+};
+
+export default define(meta, async (ps, me) => {
+ // Fetch the group
+ const userGroup = await UserGroups.findOne({
+ id: ps.groupId,
+ });
+
+ if (userGroup == null) {
+ throw new ApiError(meta.errors.noSuchGroup);
+ }
+
+ if (me.id === userGroup.userId) {
+ throw new ApiError(meta.errors.youAreOwner);
+ }
+
+ await UserGroupJoinings.delete({ userGroupId: userGroup.id, userId: me.id });
+});
diff --git a/src/server/api/index.ts b/src/server/api/index.ts
index db35fdf9e0..82579075eb 100644
--- a/src/server/api/index.ts
+++ b/src/server/api/index.ts
@@ -12,6 +12,7 @@ import endpoints from './endpoints';
import handler from './api-handler';
import signup from './private/signup';
import signin from './private/signin';
+import signupPending from './private/signup-pending';
import discord from './service/discord';
import github from './service/github';
import twitter from './service/twitter';
@@ -65,6 +66,7 @@ for (const endpoint of endpoints) {
router.post('/signup', signup);
router.post('/signin', signin);
+router.post('/signup-pending', signupPending);
router.use(discord.routes());
router.use(github.routes());
diff --git a/src/server/api/private/signup-pending.ts b/src/server/api/private/signup-pending.ts
new file mode 100644
index 0000000000..c0638a1cda
--- /dev/null
+++ b/src/server/api/private/signup-pending.ts
@@ -0,0 +1,35 @@
+import * as Koa from 'koa';
+import { Users, UserPendings, UserProfiles } from '@/models/index';
+import { signup } from '../common/signup';
+import signin from '../common/signin';
+
+export default async (ctx: Koa.Context) => {
+ const body = ctx.request.body;
+
+ const code = body['code'];
+
+ try {
+ const pendingUser = await UserPendings.findOneOrFail({ code });
+
+ const { account, secret } = await signup({
+ username: pendingUser.username,
+ passwordHash: pendingUser.password,
+ });
+
+ UserPendings.delete({
+ id: pendingUser.id,
+ });
+
+ const profile = await UserProfiles.findOneOrFail(account.id);
+
+ await UserProfiles.update({ userId: profile.userId }, {
+ email: pendingUser.email,
+ emailVerified: true,
+ emailVerifyCode: null,
+ });
+
+ signin(ctx, account);
+ } catch (e) {
+ ctx.throw(400, e);
+ }
+};
diff --git a/src/server/api/private/signup.ts b/src/server/api/private/signup.ts
index ef61767f65..93caaea935 100644
--- a/src/server/api/private/signup.ts
+++ b/src/server/api/private/signup.ts
@@ -1,8 +1,13 @@
import * as Koa from 'koa';
+import rndstr from 'rndstr';
+import * as bcrypt from 'bcryptjs';
import { fetchMeta } from '@/misc/fetch-meta';
import { verifyHcaptcha, verifyRecaptcha } from '@/misc/captcha';
-import { Users, RegistrationTickets } from '@/models/index';
+import { Users, RegistrationTickets, UserPendings } from '@/models/index';
import { signup } from '../common/signup';
+import config from '@/config';
+import { sendEmail } from '@/services/send-email';
+import { genId } from '@/misc/gen-id';
export default async (ctx: Koa.Context) => {
const body = ctx.request.body;
@@ -29,8 +34,16 @@ export default async (ctx: Koa.Context) => {
const password = body['password'];
const host: string | null = process.env.NODE_ENV === 'test' ? (body['host'] || null) : null;
const invitationCode = body['invitationCode'];
+ const emailAddress = body['emailAddress'];
- if (instance && instance.disableRegistration) {
+ if (instance.emailRequiredForSignup) {
+ if (emailAddress == null || typeof emailAddress != 'string') {
+ ctx.status = 400;
+ return;
+ }
+ }
+
+ if (instance.disableRegistration) {
if (invitationCode == null || typeof invitationCode != 'string') {
ctx.status = 400;
return;
@@ -48,18 +61,45 @@ export default async (ctx: Koa.Context) => {
RegistrationTickets.delete(ticket.id);
}
- try {
- const { account, secret } = await signup(username, password, host);
+ if (instance.emailRequiredForSignup) {
+ const code = rndstr('a-z0-9', 16);
+
+ // Generate hash of password
+ const salt = await bcrypt.genSalt(8);
+ const hash = await bcrypt.hash(password, salt);
- const res = await Users.pack(account, account, {
- detail: true,
- includeSecrets: true
+ await UserPendings.insert({
+ id: genId(),
+ createdAt: new Date(),
+ code,
+ email: emailAddress,
+ username: username,
+ password: hash,
});
- (res as any).token = secret;
+ const link = `${config.url}/signup-complete/${code}`;
+
+ sendEmail(emailAddress, 'Signup',
+ `To complete signup, please click this link:<br><a href="${link}">${link}</a>`,
+ `To complete signup, please click this link: ${link}`);
- ctx.body = res;
- } catch (e) {
- ctx.throw(400, e);
+ ctx.status = 204;
+ } else {
+ try {
+ const { account, secret } = await signup({
+ username, password, host
+ });
+
+ const res = await Users.pack(account, account, {
+ detail: true,
+ includeSecrets: true
+ });
+
+ (res as any).token = secret;
+
+ ctx.body = res;
+ } catch (e) {
+ ctx.throw(400, e);
+ }
}
};
diff --git a/src/server/file/send-drive-file.ts b/src/server/file/send-drive-file.ts
index a73164ed21..1908c969a5 100644
--- a/src/server/file/send-drive-file.ts
+++ b/src/server/file/send-drive-file.ts
@@ -13,6 +13,7 @@ import { downloadUrl } from '@/misc/download-url';
import { detectType } from '@/misc/get-file-info';
import { convertToJpeg, convertToPngOrJpeg } from '@/services/drive/image-processor';
import { GenerateVideoThumbnail } from '@/services/drive/generate-video-thumbnail';
+import { StatusError } from '@/misc/fetch';
//const _filename = fileURLToPath(import.meta.url);
const _filename = __filename;
@@ -83,9 +84,9 @@ export default async function(ctx: Koa.Context) {
ctx.set('Content-Type', image.type);
ctx.set('Cache-Control', 'max-age=31536000, immutable');
} catch (e) {
- serverLogger.error(e.statusCode);
+ serverLogger.error(`${e}`);
- if (typeof e.statusCode === 'number' && e.statusCode >= 400 && e.statusCode < 500) {
+ if (e instanceof StatusError && e.isClientError) {
ctx.status = e.statusCode;
ctx.set('Cache-Control', 'max-age=86400');
} else {
diff --git a/src/server/index.ts b/src/server/index.ts
index fb4e48c1c6..c891596140 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -20,7 +20,7 @@ import config from '@/config/index';
import apiServer from './api/index';
import { sum } from '@/prelude/array';
import Logger from '@/services/logger';
-import { program } from '../argv';
+import { envOption } from '../env';
import { UserProfiles, Users } from '@/models/index';
import { networkChart } from '@/services/chart/index';
import { genAvatar } from '@/misc/gen-avatar';
@@ -40,7 +40,7 @@ if (!['production', 'test'].includes(process.env.NODE_ENV || '')) {
}));
// Delay
- if (program.slow) {
+ if (envOption.slow) {
app.use(slow({
delay: 3000
}));
diff --git a/src/server/nodeinfo.ts b/src/server/nodeinfo.ts
index dec2615086..6a864fcc52 100644
--- a/src/server/nodeinfo.ts
+++ b/src/server/nodeinfo.ts
@@ -68,6 +68,7 @@ const nodeinfo2 = async () => {
disableRegistration: meta.disableRegistration,
disableLocalTimeline: meta.disableLocalTimeline,
disableGlobalTimeline: meta.disableGlobalTimeline,
+ emailRequiredForSignup: meta.emailRequiredForSignup,
enableHcaptcha: meta.enableHcaptcha,
enableRecaptcha: meta.enableRecaptcha,
maxNoteTextLength: meta.maxNoteTextLength,
diff --git a/src/server/proxy/proxy-media.ts b/src/server/proxy/proxy-media.ts
index 3bd65dfe67..9e13c0877f 100644
--- a/src/server/proxy/proxy-media.ts
+++ b/src/server/proxy/proxy-media.ts
@@ -5,6 +5,7 @@ import { IImage, convertToPng, convertToJpeg } from '@/services/drive/image-proc
import { createTemp } from '@/misc/create-temp';
import { downloadUrl } from '@/misc/download-url';
import { detectType } from '@/misc/get-file-info';
+import { StatusError } from '@/misc/fetch';
export async function proxyMedia(ctx: Koa.Context) {
const url = 'url' in ctx.query ? ctx.query.url : 'https://' + ctx.params.url;
@@ -37,9 +38,9 @@ export async function proxyMedia(ctx: Koa.Context) {
ctx.set('Cache-Control', 'max-age=31536000, immutable');
ctx.body = image.data;
} catch (e) {
- serverLogger.error(e);
+ serverLogger.error(`${e}`);
- if (typeof e.statusCode === 'number' && e.statusCode >= 400 && e.statusCode < 500) {
+ if (e instanceof StatusError && e.isClientError) {
ctx.status = e.statusCode;
} else {
ctx.status = 500;
diff --git a/src/server/web/manifest.json b/src/server/web/manifest.json
index 48030a2980..db97531bbf 100644
--- a/src/server/web/manifest.json
+++ b/src/server/web/manifest.json
@@ -2,7 +2,7 @@
"short_name": "Misskey",
"name": "Misskey",
"start_url": "/",
- "display": "standalone",
+ "display": "minimal-ui",
"background_color": "#313a42",
"theme_color": "#86b300",
"icons": [