Merge tag '13.5.4' into io
This commit is contained in:
commit
c0fd7db8b3
|
@ -8,6 +8,15 @@
|
|||
|
||||
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)
|
||||
|
||||
|
|
|
@ -129,6 +129,7 @@ unblockConfirm: "¿Quiere dejar de bloquear esta cuenta?"
|
|||
suspendConfirm: "¿Quiere suspender esta cuenta?"
|
||||
unsuspendConfirm: "¿Quiere dejar de suspender esta cuenta?"
|
||||
selectList: "Seleccione una lista"
|
||||
selectChannel: "Seleccionar canal"
|
||||
selectAntenna: "Seleccionar antena"
|
||||
selectWidget: "Seleccionar widget"
|
||||
editWidgets: "Editar widgets"
|
||||
|
|
|
@ -940,6 +940,8 @@ cannotPerformTemporaryDescription: "操作回数が制限を超過するため
|
|||
preset: "プリセット"
|
||||
selectFromPresets: "プリセットから選択"
|
||||
achievements: "実績"
|
||||
gotInvalidResponseError: "サーバーの応答が無効です"
|
||||
gotInvalidResponseErrorDescription: "サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから再度お試しください。"
|
||||
|
||||
_achievements:
|
||||
earnedAt: "獲得日時"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "misskey",
|
||||
"version": "13.5.3",
|
||||
"version": "13.5.4",
|
||||
"codename": "nasubi",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
|
@ -15,8 +15,8 @@ export const meta = {
|
|||
requireCredential: true,
|
||||
|
||||
limit: {
|
||||
duration: 60000,
|
||||
max: 15,
|
||||
duration: 30000,
|
||||
max: 30,
|
||||
},
|
||||
|
||||
kind: 'read:notifications',
|
||||
|
|
|
@ -337,7 +337,7 @@ export class ClientServerService {
|
|||
|
||||
const renderBase = async (reply: FastifyReply) => {
|
||||
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', {
|
||||
img: meta.bannerUrl,
|
||||
title: meta.name ?? 'Misskey',
|
||||
|
|
|
@ -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/not-found.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}`)
|
||||
|
||||
if !config.clientManifestExists
|
||||
|
|
|
@ -42,7 +42,7 @@ import { i18n } from '@/i18n';
|
|||
|
||||
const props = defineProps<{
|
||||
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;
|
||||
readonly?: boolean;
|
||||
disabled?: boolean;
|
||||
|
|
|
@ -35,6 +35,9 @@ export const apiWithDialog = ((
|
|||
} else if (err.code.startsWith('TOO_MANY')) {
|
||||
title = i18n.ts.youCannotCreateAnymore;
|
||||
text = `${i18n.ts.error}: ${err.id}`;
|
||||
} else if (err.message.startsWith('Unexpected token')) {
|
||||
title = i18n.ts.gotInvalidResponseError;
|
||||
text = i18n.ts.gotInvalidResponseErrorDescription;
|
||||
}
|
||||
alert({
|
||||
type: 'error',
|
||||
|
|
|
@ -73,7 +73,13 @@
|
|||
</FormSection>
|
||||
<FormSection>
|
||||
<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>
|
||||
<p>{{ i18n.ts._aboutMisskey.morePatrons }}</p>
|
||||
|
@ -99,6 +105,14 @@ import { definePageMetadata } from '@/scripts/page-metadata';
|
|||
import { claimAchievement, claimedAchievements } from '@/scripts/achievements';
|
||||
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 = [
|
||||
'まっちゃとーにゅ',
|
||||
'mametsuko',
|
||||
|
@ -352,4 +366,27 @@ definePageMetadata({
|
|||
.contributorUsername {
|
||||
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>
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
<MkInput v-model="ad.ratio" type="number">
|
||||
<template #label>{{ i18n.ts.ratio }}</template>
|
||||
</MkInput>
|
||||
<MkInput v-model="ad.expiresAt" type="date">
|
||||
<MkInput v-model="ad.expiresAt" type="datetime-local">
|
||||
<template #label>{{ i18n.ts.expiration }}</template>
|
||||
</MkInput>
|
||||
</FormSplit>
|
||||
|
@ -61,7 +61,12 @@ import { definePageMetadata } from '@/scripts/page-metadata';
|
|||
let ads: any[] = $ref([]);
|
||||
|
||||
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() {
|
||||
|
|
|
@ -77,6 +77,8 @@ export default defineComponent({
|
|||
accepted() {
|
||||
this.state = 'accepted';
|
||||
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}`;
|
||||
}
|
||||
}, onLogin(res) {
|
||||
|
|
|
@ -70,7 +70,7 @@ async function accept(): Promise<void> {
|
|||
state = 'accepted';
|
||||
if (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);
|
||||
location.href = cbUrl.href;
|
||||
}
|
||||
|
|
|
@ -127,12 +127,11 @@ hr {
|
|||
}
|
||||
|
||||
.ti {
|
||||
vertical-align: -14%;
|
||||
vertical-align: -12%;
|
||||
line-height: 1em;
|
||||
|
||||
&:before {
|
||||
display: inline-block;
|
||||
font-size: 130%;
|
||||
font-size: 128%;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -142,10 +142,10 @@ mainRouter.on('change', () => {
|
|||
document.documentElement.style.overflowY = 'scroll';
|
||||
|
||||
if (window.innerWidth > 1024) {
|
||||
const tempUI = miLocalStorage.getItem('ui_temp')
|
||||
const tempUI = miLocalStorage.getItem('ui_temp');
|
||||
if (tempUI) {
|
||||
miLocalStorage.setItem('ui', tempUI)
|
||||
miLocalStorage.removeItem('ui_temp')
|
||||
miLocalStorage.setItem('ui', tempUI);
|
||||
miLocalStorage.removeItem('ui_temp');
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue