diff options
| author | 饺子w (Yumechi) <35571479+eternal-flame-AD@users.noreply.github.com> | 2025-09-04 23:55:37 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-05 13:55:37 +0900 |
| commit | a92fd8856a77e8a80e8e9294a091e08f12f86c3f (patch) | |
| tree | 840d708491e249f156b4ef65202c9a4433e0c17c /packages/backend/src/server | |
| parent | fix(frontend): エラー画像が横に引き伸ばされてしまう問題... (diff) | |
| download | misskey-a92fd8856a77e8a80e8e9294a091e08f12f86c3f.tar.gz misskey-a92fd8856a77e8a80e8e9294a091e08f12f86c3f.tar.bz2 misskey-a92fd8856a77e8a80e8e9294a091e08f12f86c3f.zip | |
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>
Diffstat (limited to 'packages/backend/src/server')
| -rw-r--r-- | packages/backend/src/server/web/ClientServerService.ts | 19 | ||||
| -rw-r--r-- | packages/backend/src/server/web/views/flush.pug | 64 |
2 files changed, 52 insertions, 31 deletions
diff --git a/packages/backend/src/server/web/ClientServerService.ts b/packages/backend/src/server/web/ClientServerService.ts index b515a0c0c8..3cd83efa1a 100644 --- a/packages/backend/src/server/web/ClientServerService.ts +++ b/packages/backend/src/server/web/ClientServerService.ts @@ -201,6 +201,8 @@ export class ClientServerService { @bindThis public createServer(fastify: FastifyInstance, options: FastifyPluginOptions, done: (err?: Error) => void) { + const configUrl = new URL(this.config.url); + fastify.register(fastifyView, { root: _dirname + '/views', engine: { @@ -239,7 +241,6 @@ export class ClientServerService { done(); }); } else { - const configUrl = new URL(this.config.url); const urlOriginWithoutPort = configUrl.origin.replace(/:\d+$/, ''); 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('/'); 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'); }); diff --git a/packages/backend/src/server/web/views/flush.pug b/packages/backend/src/server/web/views/flush.pug index a73a45212f..7884495d08 100644 --- a/packages/backend/src/server/web/views/flush.pug +++ b/packages/backend/src/server/web/views/flush.pug @@ -6,41 +6,45 @@ html const msg = document.getElementById('msg'); 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() { - try { - localStorage.clear(); - message('localStorage cleared.'); + const idbPromises = ['MisskeyClient', 'keyval-store'].map((name, i, arr) => new Promise((res, rej) => { + const delidb = indexedDB.deleteDatabase(name); + delidb.onsuccess = () => res(message(`indexedDB "${name}" cleared. (${i + 1}/${arr.length})`)); + delidb.onerror = e => rej(e) + })); - const idbPromises = ['MisskeyClient', 'keyval-store'].map((name, i, arr) => new Promise((res, rej) => { - 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); - 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) { - 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) }); - } - - 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`) + 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, try manually clearing the browser cache or contact to instance admin.\n3回以上試しても失敗する場合、ブラウザのキャッシュを手動で消去し、それでもだめならインスタンス管理者に連絡してみてください。\n`) - console.error(e); - setTimeout(() => { - location = '/'; - }, 10000) - } - })(); + console.error(e); + setTimeout(() => { + location = '/'; + }, 10000) + } + })(); + } function message(text) { msg.insertAdjacentHTML('beforeend', `<p>[${(new Date()).toString()}] ${text.replace(/\n/g,'<br>')}</p>`) |