feat(backend): Send Clear-Site-Data header on /flush (#16517)
* feat(backend): Send Clear-Site-Data header on /flush Signed-off-by: eternal-flame-AD <yume@yumechi.jp> * simplify check on flush.pug Signed-off-by: eternal-flame-AD <yume@yumechi.jp> --------- Signed-off-by: eternal-flame-AD <yume@yumechi.jp>
This commit is contained in:
parent
047773341d
commit
a92fd8856a
|
@ -6,6 +6,7 @@
|
||||||
### Client
|
### Client
|
||||||
- Fix: RSSティッカーウィジェットが正しく動作しない問題を修正
|
- Fix: RSSティッカーウィジェットが正しく動作しない問題を修正
|
||||||
- Fix: エラー画像が横に引き伸ばされてしまう問題に対応
|
- Fix: エラー画像が横に引き伸ばされてしまう問題に対応
|
||||||
|
- Enhance: /flushページでサイトキャッシュをクリアできるようになりました
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
-
|
-
|
||||||
|
|
|
@ -201,6 +201,8 @@ export class ClientServerService {
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public createServer(fastify: FastifyInstance, options: FastifyPluginOptions, done: (err?: Error) => void) {
|
public createServer(fastify: FastifyInstance, options: FastifyPluginOptions, done: (err?: Error) => void) {
|
||||||
|
const configUrl = new URL(this.config.url);
|
||||||
|
|
||||||
fastify.register(fastifyView, {
|
fastify.register(fastifyView, {
|
||||||
root: _dirname + '/views',
|
root: _dirname + '/views',
|
||||||
engine: {
|
engine: {
|
||||||
|
@ -239,7 +241,6 @@ export class ClientServerService {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const configUrl = new URL(this.config.url);
|
|
||||||
const urlOriginWithoutPort = configUrl.origin.replace(/:\d+$/, '');
|
const urlOriginWithoutPort = configUrl.origin.replace(/:\d+$/, '');
|
||||||
|
|
||||||
const port = (process.env.VITE_PORT ?? '5173');
|
const port = (process.env.VITE_PORT ?? '5173');
|
||||||
|
@ -887,6 +888,22 @@ export class ClientServerService {
|
||||||
[, ...target.split('/').filter(x => x), ...source.split('/').filter(x => x).splice(depth)].join('/');
|
[, ...target.split('/').filter(x => x), ...source.split('/').filter(x => x).splice(depth)].join('/');
|
||||||
|
|
||||||
fastify.get('/flush', async (request, reply) => {
|
fastify.get('/flush', async (request, reply) => {
|
||||||
|
let sendHeader = true;
|
||||||
|
|
||||||
|
if (request.headers['origin']) {
|
||||||
|
const originURL = new URL(request.headers['origin']);
|
||||||
|
if (originURL.protocol !== 'https:') { // Clear-Site-Data only supports https
|
||||||
|
sendHeader = false;
|
||||||
|
}
|
||||||
|
if (originURL.host !== configUrl.host) {
|
||||||
|
sendHeader = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sendHeader) {
|
||||||
|
reply.header('Clear-Site-Data', '"*"');
|
||||||
|
}
|
||||||
|
reply.header('Set-Cookie', 'http-flush-failed=1; Path=/flush; Max-Age=60');
|
||||||
return await reply.view('flush');
|
return await reply.view('flush');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -6,41 +6,45 @@ html
|
||||||
const msg = document.getElementById('msg');
|
const msg = document.getElementById('msg');
|
||||||
const successText = `\nSuccess Flush! <a href="/">Back to Misskey</a>\n成功しました。<a href="/">Misskeyを開き直してください。</a>`;
|
const successText = `\nSuccess Flush! <a href="/">Back to Misskey</a>\n成功しました。<a href="/">Misskeyを開き直してください。</a>`;
|
||||||
|
|
||||||
message('Start flushing.');
|
if (!document.cookie) {
|
||||||
|
message('Your site data is fully cleared by your browser.');
|
||||||
|
message(successText);
|
||||||
|
} else {
|
||||||
|
message('Your browser does not support Clear-Site-Data header. Start opportunistic flushing.');
|
||||||
|
(async function() {
|
||||||
|
try {
|
||||||
|
localStorage.clear();
|
||||||
|
message('localStorage cleared.');
|
||||||
|
|
||||||
(async function() {
|
const idbPromises = ['MisskeyClient', 'keyval-store'].map((name, i, arr) => new Promise((res, rej) => {
|
||||||
try {
|
const delidb = indexedDB.deleteDatabase(name);
|
||||||
localStorage.clear();
|
delidb.onsuccess = () => res(message(`indexedDB "${name}" cleared. (${i + 1}/${arr.length})`));
|
||||||
message('localStorage cleared.');
|
delidb.onerror = e => rej(e)
|
||||||
|
}));
|
||||||
|
|
||||||
const idbPromises = ['MisskeyClient', 'keyval-store'].map((name, i, arr) => new Promise((res, rej) => {
|
await Promise.all(idbPromises);
|
||||||
const delidb = indexedDB.deleteDatabase(name);
|
|
||||||
delidb.onsuccess = () => res(message(`indexedDB "${name}" cleared. (${i + 1}/${arr.length})`));
|
|
||||||
delidb.onerror = e => rej(e)
|
|
||||||
}));
|
|
||||||
|
|
||||||
await Promise.all(idbPromises);
|
if (navigator.serviceWorker.controller) {
|
||||||
|
navigator.serviceWorker.controller.postMessage('clear');
|
||||||
|
await navigator.serviceWorker.getRegistrations()
|
||||||
|
.then(registrations => {
|
||||||
|
return Promise.all(registrations.map(registration => registration.unregister()));
|
||||||
|
})
|
||||||
|
.catch(e => { throw new Error(e) });
|
||||||
|
}
|
||||||
|
|
||||||
if (navigator.serviceWorker.controller) {
|
message(successText);
|
||||||
navigator.serviceWorker.controller.postMessage('clear');
|
} catch (e) {
|
||||||
await navigator.serviceWorker.getRegistrations()
|
message(`\n${e}\n\nFlush Failed. <a href="/flush">Please retry.</a>\n失敗しました。<a href="/flush">もう一度試してみてください。</a>`);
|
||||||
.then(registrations => {
|
message(`\nIf you retry more than 3 times, try manually clearing the browser cache or contact to instance admin.\n3回以上試しても失敗する場合、ブラウザのキャッシュを手動で消去し、それでもだめならインスタンス管理者に連絡してみてください。\n`)
|
||||||
return Promise.all(registrations.map(registration => registration.unregister()));
|
|
||||||
})
|
console.error(e);
|
||||||
.catch(e => { throw new Error(e) });
|
setTimeout(() => {
|
||||||
|
location = '/';
|
||||||
|
}, 10000)
|
||||||
}
|
}
|
||||||
|
})();
|
||||||
message(successText);
|
}
|
||||||
} catch (e) {
|
|
||||||
message(`\n${e}\n\nFlush Failed. <a href="/flush">Please retry.</a>\n失敗しました。<a href="/flush">もう一度試してみてください。</a>`);
|
|
||||||
message(`\nIf you retry more than 3 times, clear the browser cache or contact to instance admin.\n3回以上試しても失敗する場合、ブラウザのキャッシュを消去し、それでもだめならインスタンス管理者に連絡してみてください。\n`)
|
|
||||||
|
|
||||||
console.error(e);
|
|
||||||
setTimeout(() => {
|
|
||||||
location = '/';
|
|
||||||
}, 10000)
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
function message(text) {
|
function message(text) {
|
||||||
msg.insertAdjacentHTML('beforeend', `<p>[${(new Date()).toString()}] ${text.replace(/\n/g,'<br>')}</p>`)
|
msg.insertAdjacentHTML('beforeend', `<p>[${(new Date()).toString()}] ${text.replace(/\n/g,'<br>')}</p>`)
|
||||||
|
|
Loading…
Reference in New Issue