Merge branch 'develop'

This commit is contained in:
syuilo 2019-06-16 16:09:04 +09:00
commit 5cc1aab530
No known key found for this signature in database
GPG key ID: BDC4C49D06AB9D69
28 changed files with 184 additions and 113 deletions

View file

@ -16,7 +16,7 @@
</ol>
<ol class="emojis" ref="suggests" v-if="emojis.length > 0">
<li v-for="emoji in emojis" @click="complete(type, emoji.emoji)" @keydown="onKeydown" tabindex="-1">
<span class="emoji" v-if="emoji.isCustomEmoji"><img :src="emoji.url" :alt="emoji.emoji"/></span>
<span class="emoji" v-if="emoji.isCustomEmoji"><img :src="$store.state.device.disableShowingAnimatedImages ? getStaticImageUrl(emoji.url) : emoji.url" :alt="emoji.emoji"/></span>
<span class="emoji" v-else-if="!useOsDefaultEmojis"><img :src="emoji.url" :alt="emoji.emoji"/></span>
<span class="emoji" v-else>{{ emoji.emoji }}</span>
<span class="name" v-html="emoji.name.replace(q, `<b>${q}</b>`)"></span>
@ -31,6 +31,7 @@ import Vue from 'vue';
import * as emojilib from 'emojilib';
import contains from '../../../common/scripts/contains';
import { twemojiBase } from '../../../../../misc/twemoji-base';
import { getStaticImageUrl } from '../../../common/scripts/get-static-image-url';
type EmojiDef = {
emoji: string;
@ -78,6 +79,7 @@ export default Vue.extend({
data() {
return {
getStaticImageUrl,
fetching: true,
users: [],
hashtags: [],

View file

@ -257,7 +257,7 @@ export default class Reversi {
public get winner(): Color | null {
return this.isEnded ?
this.blackCount == this.whiteCount ? null :
this.opts.isLlotheo === this.blackCount > this.whiteCount ? WHITE : BLACK :
this.opts.isLlotheo === this.blackCount > this.whiteCount ? WHITE : BLACK :
undefined as never;
}
}

View file

@ -161,7 +161,7 @@ export class ASEvaluator {
subtract: (a: number, b: number) => a - b,
multiply: (a: number, b: number) => a * b,
divide: (a: number, b: number) => a / b,
remind: (a: number, b: number) => a % b,
mod: (a: number, b: number) => a % b,
strLen: (a: string) => a.length,
strPick: (a: string, b: number) => a[b - 1],
strReplace: (a: string, b: string, c: string) => a.split(b).join(c),

View file

@ -58,7 +58,7 @@ export const funcDefs: Record<string, { in: any[]; out: any; category: string; i
subtract: { in: ['number', 'number'], out: 'number', category: 'operation', icon: faMinus, },
multiply: { in: ['number', 'number'], out: 'number', category: 'operation', icon: faTimes, },
divide: { in: ['number', 'number'], out: 'number', category: 'operation', icon: faDivide, },
remind: { in: ['number', 'number'], out: 'number', category: 'operation', icon: faDivide, },
mod: { in: ['number', 'number'], out: 'number', category: 'operation', icon: faDivide, },
eq: { in: [0, 0], out: 'boolean', category: 'comparison', icon: faEquals, },
notEq: { in: [0, 0], out: 'boolean', category: 'comparison', icon: faNotEqual, },
gt: { in: ['number', 'number'], out: 'boolean', category: 'comparison', icon: faGreaterThan, },

File diff suppressed because one or more lines are too long

View file

@ -1,4 +1,4 @@
export const twemojiBase = 'https://cdn.jsdelivr.net/npm/twemoji@11.3.0';
// https://cdn.jsdelivr.net/npm/twemoji@11.3.0
// https://cdnjs.cloudflare.com/ajax/libs/twemoji/11.3.0
export const twemojiBase = 'https://cdn.jsdelivr.net/npm/twemoji@12.0.1';
// https://cdn.jsdelivr.net/npm/twemoji@12.0.1
// https://cdnjs.cloudflare.com/ajax/libs/twemoji/12.0.1
// https://twemoji.maxcdn.com

View file

@ -8,7 +8,7 @@ export type PackedMessagingMessage = SchemaType<typeof packedMessagingMessageSch
@EntityRepository(MessagingMessage)
export class MessagingMessageRepository extends Repository<MessagingMessage> {
public isValidText(text: string): boolean {
public validateText(text: string): boolean {
return text.trim().length <= 1000 && text.trim() != '';
}

View file

@ -1,3 +1,4 @@
import $ from 'cafy';
import { EntityRepository, Repository, In } from 'typeorm';
import { User, ILocalUser, IRemoteUser } from '../entities/user';
import { Emojis, Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles, UserGroupJoinings } from '..';
@ -231,29 +232,13 @@ export class UserRepository extends Repository<User> {
}
//#region Validators
public validateUsername(username: string, remote = false): boolean {
return typeof username == 'string' && (remote ? /^\w([\w-]*\w)?$/ : /^\w{1,20}$/).test(username);
}
public validatePassword(password: string): boolean {
return typeof password == 'string' && password != '';
}
public isValidName(name?: string): boolean {
return name === null || (typeof name == 'string' && name.length < 50 && name.trim() != '');
}
public isValidDescription(description: string): boolean {
return typeof description == 'string' && description.length < 500 && description.trim() != '';
}
public isValidLocation(location: string): boolean {
return typeof location == 'string' && location.length < 50 && location.trim() != '';
}
public isValidBirthday(birthday: string): boolean {
return typeof birthday == 'string' && /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/.test(birthday);
}
public validateLocalUsername = $.str.match(/^\w{1,20}$/);
public validateRemoteUsername = $.str.match(/^\w([\w-]*\w)?$/);
public validatePassword = $.str.min(1);
public validateName = $.str.min(1).max(50);
public validateDescription = $.str.min(1).max(500);
public validateLocation = $.str.min(1).max(50);
public validateBirthday = $.str.match(/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/);
//#endregion
}

View file

@ -53,12 +53,14 @@ function validatePerson(x: any, uri: string) {
return new Error('invalid person: inbox is not a string');
}
if (!Users.validateUsername(x.preferredUsername, true)) {
if (!Users.validateRemoteUsername.ok(x.preferredUsername)) {
return new Error('invalid person: invalid username');
}
if (!Users.isValidName(x.name == '' ? null : x.name)) {
return new Error('invalid person: invalid name');
if (x.name != null && x.name != '') {
if (!Users.validateName.ok(x.name)) {
return new Error('invalid person: invalid name');
}
}
if (typeof x.id !== 'string') {

View file

@ -9,7 +9,7 @@ import config from '../../config';
import { ILocalUser } from '../../models/entities/user';
import { publishApLogStream } from '../../services/stream';
import { apLogger } from './logger';
import { UserKeypairs } from '../../models';
import { UserKeypairs, Instances } from '../../models';
import { fetchMeta } from '../../misc/fetch-meta';
import { toPuny } from '../../misc/convert-host';
import { ensure } from '../../prelude/ensure';
@ -17,15 +17,30 @@ import { ensure } from '../../prelude/ensure';
export const logger = apLogger.createSubLogger('deliver');
export default async (user: ILocalUser, url: string, object: any) => {
logger.info(`--> ${url}`);
const timeout = 10 * 1000;
const { protocol, host, hostname, port, pathname, search } = new URL(url);
// ブロックしてたら中断
const meta = await fetchMeta();
if (meta.blockedHosts.includes(toPuny(host))) return;
if (meta.blockedHosts.includes(toPuny(host))) {
logger.info(`skip (blocked) ${url}`);
return;
}
// closedなら中断
const closedHosts = await Instances.find({
where: {
isMarkedAsClosed: true
},
cache: 60 * 1000
});
if (closedHosts.map(x => x.host).includes(toPuny(host))) {
logger.info(`skip (closed) ${url}`);
return;
}
logger.info(`--> ${url}`);
const data = JSON.stringify(object);

View file

@ -29,14 +29,14 @@ export const meta = {
params: {
name: {
validator: $.optional.nullable.str.pipe(Users.isValidName),
validator: $.optional.nullable.use(Users.validateName),
desc: {
'ja-JP': '名前(ハンドルネームやニックネーム)'
}
},
description: {
validator: $.optional.nullable.str.pipe(Users.isValidDescription),
validator: $.optional.nullable.use(Users.validateDescription),
desc: {
'ja-JP': 'アカウントの説明や自己紹介'
}
@ -50,14 +50,14 @@ export const meta = {
},
location: {
validator: $.optional.nullable.str.pipe(Users.isValidLocation),
validator: $.optional.nullable.use(Users.validateLocation),
desc: {
'ja-JP': '住んでいる地域、所在'
}
},
birthday: {
validator: $.optional.nullable.str.pipe(Users.isValidBirthday),
validator: $.optional.nullable.use(Users.validateBirthday),
desc: {
'ja-JP': '誕生日 (YYYY-MM-DD形式)'
}

View file

@ -44,7 +44,7 @@ export const meta = {
},
text: {
validator: $.optional.str.pipe(MessagingMessages.isValidText)
validator: $.optional.str.pipe(MessagingMessages.validateText)
},
fileId: {

View file

@ -9,7 +9,7 @@ export const meta = {
params: {
username: {
validator: $.str.pipe(Users.validateUsername)
validator: $.use(Users.validateLocalUsername)
}
}
};

View file

@ -66,7 +66,7 @@ export const meta = {
};
export default define(meta, async (ps, me) => {
const isUsername = Users.validateUsername(ps.query.replace('@', ''), !ps.localOnly);
const isUsername = ps.localOnly ? Users.validateLocalUsername.ok(ps.query.replace('@', '')) : Users.validateRemoteUsername.ok(ps.query.replace('@', ''));
let users: User[] = [];

View file

@ -58,13 +58,13 @@ export default async (ctx: Koa.BaseContext) => {
}
// Validate username
if (!Users.validateUsername(username)) {
if (!Users.validateLocalUsername.ok(username)) {
ctx.status = 400;
return;
}
// Validate password
if (!Users.validatePassword(password)) {
if (!Users.validatePassword.ok(password)) {
ctx.status = 400;
return;
}

View file

@ -17,6 +17,8 @@ export async function proxyMedia(ctx: Koa.BaseContext) {
const [type, ext] = await detectMine(path);
if (!type.startsWith('image/')) throw 403;
let image: IImage;
if ('static' in ctx.query && ['image/png', 'image/gif'].includes(type)) {

View file

@ -36,7 +36,7 @@ module.exports = async (ctx: Koa.BaseContext) => {
ctx.body = summary;
} catch (e) {
logger.error(`Failed to get preview of ${ctx.query.url}: ${e}`);
logger.warn(`Failed to get preview of ${ctx.query.url}: ${e}`);
ctx.status = 200;
ctx.set('Cache-Control', 'max-age=86400, immutable');
ctx.body = '{}';

View file

@ -149,18 +149,22 @@ export async function generateAlts(path: string, type: string, generateWeb: bool
if (generateWeb) {
logger.info(`creating web image`);
if (['image/jpeg'].includes(type)) {
webpublic = await convertToJpeg(path, 2048, 2048);
} else if (['image/webp'].includes(type)) {
webpublic = await convertToWebp(path, 2048, 2048);
} else if (['image/png'].includes(type)) {
webpublic = await convertToPng(path, 2048, 2048);
} else if (['image/apng', 'image/vnd.mozilla.apng'].includes(type)) {
webpublic = await convertToApng(path);
} else if (['image/gif'].includes(type)) {
webpublic = await convertToGif(path);
} else {
logger.info(`web image not created (not an image)`);
try {
if (['image/jpeg'].includes(type)) {
webpublic = await convertToJpeg(path, 2048, 2048);
} else if (['image/webp'].includes(type)) {
webpublic = await convertToWebp(path, 2048, 2048);
} else if (['image/png'].includes(type)) {
webpublic = await convertToPng(path, 2048, 2048);
} else if (['image/apng', 'image/vnd.mozilla.apng'].includes(type)) {
webpublic = await convertToApng(path);
} else if (['image/gif'].includes(type)) {
webpublic = await convertToGif(path);
} else {
logger.info(`web image not created (not an image)`);
}
} catch (e) {
logger.warn(`web image not created (an error occured)`, e);
}
} else {
logger.info(`web image not created (from remote)`);
@ -170,18 +174,22 @@ export async function generateAlts(path: string, type: string, generateWeb: bool
// #region thumbnail
let thumbnail: IImage | null = null;
if (['image/jpeg', 'image/webp'].includes(type)) {
thumbnail = await convertToJpeg(path, 498, 280);
} else if (['image/png'].includes(type)) {
thumbnail = await convertToPng(path, 498, 280);
} else if (['image/gif'].includes(type)) {
thumbnail = await convertToGif(path);
} else if (type.startsWith('video/')) {
try {
thumbnail = await GenerateVideoThumbnail(path);
} catch (e) {
logger.error(`GenerateVideoThumbnail failed: ${e}`);
try {
if (['image/jpeg', 'image/webp'].includes(type)) {
thumbnail = await convertToJpeg(path, 498, 280);
} else if (['image/png'].includes(type)) {
thumbnail = await convertToPng(path, 498, 280);
} else if (['image/gif'].includes(type)) {
thumbnail = await convertToGif(path);
} else if (type.startsWith('video/')) {
try {
thumbnail = await GenerateVideoThumbnail(path);
} catch (e) {
logger.error(`GenerateVideoThumbnail failed: ${e}`);
}
}
} catch (e) {
logger.warn(`thumbnail not created (an error occured)`, e);
}
// #endregion thumbnail

View file

@ -90,7 +90,7 @@ export default class Logger {
}
}
public warn(message: string, data?: Record<string, any> | null, important = false): void { // 実行を継続できるが改善すべき状況で使う
public warn(message: string, data?: Record<string, any> | null, important = false): void { // 実行を継続できるが改善すべき状況で使う
this.log('warning', message, data, important);
}