Merge tag '13.5.4' into io

This commit is contained in:
Cookie Ramen 2023-02-10 23:07:06 +09:00
commit c0fd7db8b3
No known key found for this signature in database
GPG key ID: 82A8B5D42246F02D
15 changed files with 75 additions and 16 deletions

View file

@ -8,6 +8,15 @@
You should also include the user name that made the change. You should also include the user name that made the change.
--> -->
## 13.5.4 (2023/02/09)
### Improvements
- Server: UIのHTMLートなどの特別なページを除くのキャッシュ時間を15秒から30秒に
- i/notificationsのレートリミットを緩和
### Bugfixes
- fix(client): validate url to improve security
- fix(client): dateの初期値が正常に入らない時がある
## 13.5.3 (2023/02/09) ## 13.5.3 (2023/02/09)

View file

@ -129,6 +129,7 @@ unblockConfirm: "¿Quiere dejar de bloquear esta cuenta?"
suspendConfirm: "¿Quiere suspender esta cuenta?" suspendConfirm: "¿Quiere suspender esta cuenta?"
unsuspendConfirm: "¿Quiere dejar de suspender esta cuenta?" unsuspendConfirm: "¿Quiere dejar de suspender esta cuenta?"
selectList: "Seleccione una lista" selectList: "Seleccione una lista"
selectChannel: "Seleccionar canal"
selectAntenna: "Seleccionar antena" selectAntenna: "Seleccionar antena"
selectWidget: "Seleccionar widget" selectWidget: "Seleccionar widget"
editWidgets: "Editar widgets" editWidgets: "Editar widgets"

View file

@ -940,6 +940,8 @@ cannotPerformTemporaryDescription: "操作回数が制限を超過するため
preset: "プリセット" preset: "プリセット"
selectFromPresets: "プリセットから選択" selectFromPresets: "プリセットから選択"
achievements: "実績" achievements: "実績"
gotInvalidResponseError: "サーバーの応答が無効です"
gotInvalidResponseErrorDescription: "サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから再度お試しください。"
_achievements: _achievements:
earnedAt: "獲得日時" earnedAt: "獲得日時"

View file

@ -1,6 +1,6 @@
{ {
"name": "misskey", "name": "misskey",
"version": "13.5.3", "version": "13.5.4",
"codename": "nasubi", "codename": "nasubi",
"repository": { "repository": {
"type": "git", "type": "git",

View file

@ -15,8 +15,8 @@ export const meta = {
requireCredential: true, requireCredential: true,
limit: { limit: {
duration: 60000, duration: 30000,
max: 15, max: 30,
}, },
kind: 'read:notifications', kind: 'read:notifications',

View file

@ -337,7 +337,7 @@ export class ClientServerService {
const renderBase = async (reply: FastifyReply) => { const renderBase = async (reply: FastifyReply) => {
const meta = await this.metaService.fetch(); const meta = await this.metaService.fetch();
reply.header('Cache-Control', 'public, max-age=15'); reply.header('Cache-Control', 'public, max-age=30');
return await reply.view('base', { return await reply.view('base', {
img: meta.bannerUrl, img: meta.bannerUrl,
title: meta.name ?? 'Misskey', title: meta.name ?? 'Misskey',

View file

@ -35,7 +35,8 @@ html
link(rel='prefetch' href='https://xn--931a.moe/assets/info.jpg') link(rel='prefetch' href='https://xn--931a.moe/assets/info.jpg')
link(rel='prefetch' href='https://xn--931a.moe/assets/not-found.jpg') link(rel='prefetch' href='https://xn--931a.moe/assets/not-found.jpg')
link(rel='prefetch' href='https://xn--931a.moe/assets/error.jpg') link(rel='prefetch' href='https://xn--931a.moe/assets/error.jpg')
link(rel='stylesheet' href='/assets/tabler-icons/tabler-icons.min.css') //- https://github.com/misskey-dev/misskey/issues/9842
link(rel='stylesheet' href='/assets/tabler-icons/tabler-icons.min.css?v2.2.0')
link(rel='modulepreload' href=`/vite/${clientEntry.file}`) link(rel='modulepreload' href=`/vite/${clientEntry.file}`)
if !config.clientManifestExists if !config.clientManifestExists

View file

@ -42,7 +42,7 @@ import { i18n } from '@/i18n';
const props = defineProps<{ const props = defineProps<{
modelValue: string | number; modelValue: string | number;
type?: 'text' | 'number' | 'password' | 'email' | 'url' | 'date' | 'time' | 'search'; type?: 'text' | 'number' | 'password' | 'email' | 'url' | 'date' | 'time' | 'search' | 'datetime-local';
required?: boolean; required?: boolean;
readonly?: boolean; readonly?: boolean;
disabled?: boolean; disabled?: boolean;

View file

@ -35,6 +35,9 @@ export const apiWithDialog = ((
} else if (err.code.startsWith('TOO_MANY')) { } else if (err.code.startsWith('TOO_MANY')) {
title = i18n.ts.youCannotCreateAnymore; title = i18n.ts.youCannotCreateAnymore;
text = `${i18n.ts.error}: ${err.id}`; text = `${i18n.ts.error}: ${err.id}`;
} else if (err.message.startsWith('Unexpected token')) {
title = i18n.ts.gotInvalidResponseError;
text = i18n.ts.gotInvalidResponseErrorDescription;
} }
alert({ alert({
type: 'error', type: 'error',

View file

@ -73,7 +73,13 @@
</FormSection> </FormSection>
<FormSection> <FormSection>
<template #label><Mfm text="$[jelly ❤]"/> {{ i18n.ts._aboutMisskey.patrons }}</template> <template #label><Mfm text="$[jelly ❤]"/> {{ i18n.ts._aboutMisskey.patrons }}</template>
<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); grid-gap: 12px;"> <div :class="$style.patronsWithIcon">
<div v-for="patron in patronsWithIcon" :class="$style.patronWithIcon">
<img :src="patron.icon" :class="$style.patronIcon">
<span :class="$style.patronName">{{ patron.name }}</span>
</div>
</div>
<div style="margin-top: 16px; display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); grid-gap: 12px;">
<div v-for="patron in patrons" :key="patron">{{ patron }}</div> <div v-for="patron in patrons" :key="patron">{{ patron }}</div>
</div> </div>
<p>{{ i18n.ts._aboutMisskey.morePatrons }}</p> <p>{{ i18n.ts._aboutMisskey.morePatrons }}</p>
@ -99,6 +105,14 @@ import { definePageMetadata } from '@/scripts/page-metadata';
import { claimAchievement, claimedAchievements } from '@/scripts/achievements'; import { claimAchievement, claimedAchievements } from '@/scripts/achievements';
import { $i } from '@/account'; import { $i } from '@/account';
const patronsWithIcon = [{
name: 'カイヤン',
icon: 'https://misskey-hub.net/patrons/a2820716883e408cb87773e377ce7c8d.jpg',
}, {
name: 'だれかさん',
icon: 'https://misskey-hub.net/patrons/f7409b5e5a88477a9b9d740c408de125.jpg',
}];
const patrons = [ const patrons = [
'まっちゃとーにゅ', 'まっちゃとーにゅ',
'mametsuko', 'mametsuko',
@ -352,4 +366,27 @@ definePageMetadata({
.contributorUsername { .contributorUsername {
margin-left: 12px; margin-left: 12px;
} }
.patronsWithIcon {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-gap: 12px;
}
.patronWithIcon {
display: flex;
align-items: center;
padding: 12px;
background: var(--buttonBg);
border-radius: 6px;
}
.patronIcon {
width: 24px;
border-radius: 100%;
}
.patronName {
margin-left: 12px;
}
</style> </style>

View file

@ -29,7 +29,7 @@
<MkInput v-model="ad.ratio" type="number"> <MkInput v-model="ad.ratio" type="number">
<template #label>{{ i18n.ts.ratio }}</template> <template #label>{{ i18n.ts.ratio }}</template>
</MkInput> </MkInput>
<MkInput v-model="ad.expiresAt" type="date"> <MkInput v-model="ad.expiresAt" type="datetime-local">
<template #label>{{ i18n.ts.expiration }}</template> <template #label>{{ i18n.ts.expiration }}</template>
</MkInput> </MkInput>
</FormSplit> </FormSplit>
@ -61,7 +61,12 @@ import { definePageMetadata } from '@/scripts/page-metadata';
let ads: any[] = $ref([]); let ads: any[] = $ref([]);
os.api('admin/ad/list').then(adsResponse => { os.api('admin/ad/list').then(adsResponse => {
ads = adsResponse; ads = adsResponse.map(r => {
return {
...r,
expiresAt: new Date(r.expiresAt).toISOString().slice(0, 16),
};
});
}); });
function add() { function add() {

View file

@ -77,6 +77,8 @@ export default defineComponent({
accepted() { accepted() {
this.state = 'accepted'; this.state = 'accepted';
if (this.session.app.callbackUrl) { if (this.session.app.callbackUrl) {
const url = new URL(this.session.app.callbackUrl);
if (['javascript:', 'file:', 'data:', 'mailto:', 'tel:'].includes(url.protocol)) throw new Error('invalid url');
location.href = `${this.session.app.callbackUrl}?token=${this.session.token}`; location.href = `${this.session.app.callbackUrl}?token=${this.session.token}`;
} }
}, onLogin(res) { }, onLogin(res) {

View file

@ -70,7 +70,7 @@ async function accept(): Promise<void> {
state = 'accepted'; state = 'accepted';
if (props.callback) { if (props.callback) {
const cbUrl = new URL(props.callback); const cbUrl = new URL(props.callback);
if (!['http:', 'https:'].includes(cbUrl.protocol)) throw new Error('invalid url'); if (['javascript:', 'file:', 'data:', 'mailto:', 'tel:'].includes(cbUrl.protocol)) throw new Error('invalid url');
cbUrl.searchParams.set('session', props.session); cbUrl.searchParams.set('session', props.session);
location.href = cbUrl.href; location.href = cbUrl.href;
} }

View file

@ -127,12 +127,11 @@ hr {
} }
.ti { .ti {
vertical-align: -14%; vertical-align: -12%;
line-height: 1em; line-height: 1em;
&:before { &:before {
display: inline-block; font-size: 128%;
font-size: 130%;
} }
} }

View file

@ -142,10 +142,10 @@ mainRouter.on('change', () => {
document.documentElement.style.overflowY = 'scroll'; document.documentElement.style.overflowY = 'scroll';
if (window.innerWidth > 1024) { if (window.innerWidth > 1024) {
const tempUI = miLocalStorage.getItem('ui_temp') const tempUI = miLocalStorage.getItem('ui_temp');
if (tempUI) { if (tempUI) {
miLocalStorage.setItem('ui', tempUI) miLocalStorage.setItem('ui', tempUI);
miLocalStorage.removeItem('ui_temp') miLocalStorage.removeItem('ui_temp');
location.reload(); location.reload();
} }
} }