do not use media proxy if emoji is local
Some checks failed
Lint / pnpm_install (push) Successful in 1m30s
Publish Docker image / Build (push) Successful in 4m48s
Test (production install and build) / production (22.11.0) (push) Successful in 55s
Test (backend) / unit (22.11.0) (push) Successful in 6m51s
Lint / lint (backend) (push) Successful in 1m59s
Lint / lint (frontend) (push) Successful in 1m55s
Lint / lint (frontend-embed) (push) Successful in 2m9s
Lint / lint (frontend-shared) (push) Successful in 1m57s
Lint / lint (misskey-bubble-game) (push) Successful in 2m16s
Test (backend) / e2e (22.11.0) (push) Failing after 10m12s
Lint / lint (misskey-js) (push) Successful in 2m2s
Lint / lint (misskey-reversi) (push) Successful in 2m21s
Lint / lint (sw) (push) Successful in 2m20s
Lint / typecheck (backend) (push) Successful in 2m9s
Lint / typecheck (misskey-js) (push) Successful in 1m18s
Lint / typecheck (sw) (push) Successful in 1m28s
Some checks failed
Lint / pnpm_install (push) Successful in 1m30s
Publish Docker image / Build (push) Successful in 4m48s
Test (production install and build) / production (22.11.0) (push) Successful in 55s
Test (backend) / unit (22.11.0) (push) Successful in 6m51s
Lint / lint (backend) (push) Successful in 1m59s
Lint / lint (frontend) (push) Successful in 1m55s
Lint / lint (frontend-embed) (push) Successful in 2m9s
Lint / lint (frontend-shared) (push) Successful in 1m57s
Lint / lint (misskey-bubble-game) (push) Successful in 2m16s
Test (backend) / e2e (22.11.0) (push) Failing after 10m12s
Lint / lint (misskey-js) (push) Successful in 2m2s
Lint / lint (misskey-reversi) (push) Successful in 2m21s
Lint / lint (sw) (push) Successful in 2m20s
Lint / typecheck (backend) (push) Successful in 2m9s
Lint / typecheck (misskey-js) (push) Successful in 1m18s
Lint / typecheck (sw) (push) Successful in 1m28s
Signed-off-by: eternal-flame-AD <yume@yumechi.jp>
This commit is contained in:
parent
95d3fb08f4
commit
a1943a5247
1 changed files with 28 additions and 4 deletions
|
@ -33,7 +33,6 @@ import { OpenApiServerService } from './api/openapi/OpenApiServerService.js';
|
||||||
import { OAuth2ProviderService } from './oauth/OAuth2ProviderService.js';
|
import { OAuth2ProviderService } from './oauth/OAuth2ProviderService.js';
|
||||||
import { makeHstsHook } from './hsts.js';
|
import { makeHstsHook } from './hsts.js';
|
||||||
import { generateCSP } from './csp.js';
|
import { generateCSP } from './csp.js';
|
||||||
import * as prom from 'prom-client';
|
|
||||||
import { sanitizeRequestURI } from '@/misc/log-sanitization.js';
|
import { sanitizeRequestURI } from '@/misc/log-sanitization.js';
|
||||||
import { metricCounter, metricGauge, metricHistogram, MetricsService } from './api/MetricsService.js';
|
import { metricCounter, metricGauge, metricHistogram, MetricsService } from './api/MetricsService.js';
|
||||||
|
|
||||||
|
@ -110,6 +109,11 @@ const mLastSuccessfulRequest = metricGauge({
|
||||||
labelNames: [],
|
labelNames: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// This function is used to determine if a path is safe to redirect to.
|
||||||
|
function redirectSafePath(path: string): boolean {
|
||||||
|
return ['/files/', '/identicon/', '/proxy/', '/static-assets/', '/vite/', '/embed_vite/'].some(prefix => path.startsWith(prefix));
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ServerService implements OnApplicationShutdown {
|
export class ServerService implements OnApplicationShutdown {
|
||||||
private logger: Logger;
|
private logger: Logger;
|
||||||
|
@ -348,7 +352,7 @@ export class ServerService implements OnApplicationShutdown {
|
||||||
name: name,
|
name: name,
|
||||||
});
|
});
|
||||||
|
|
||||||
reply.header('Content-Security-Policy', 'default-src \'none\'; style-src \'unsafe-inline\'');
|
reply.header('Content-Security-Policy', 'default-src \'none\'');
|
||||||
|
|
||||||
if (emoji == null) {
|
if (emoji == null) {
|
||||||
if ('fallback' in request.query) {
|
if ('fallback' in request.query) {
|
||||||
|
@ -359,16 +363,26 @@ export class ServerService implements OnApplicationShutdown {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dbUrl = emoji?.publicUrl || emoji?.originalUrl;
|
||||||
|
const dbUrlParsed = new URL(dbUrl);
|
||||||
|
const instanceUrl = new URL(this.config.url);
|
||||||
|
if (dbUrlParsed.origin === instanceUrl.origin) {
|
||||||
|
if (!redirectSafePath(dbUrlParsed.pathname)) {
|
||||||
|
return await reply.status(508);
|
||||||
|
}
|
||||||
|
return await reply.redirect(dbUrl, 301);
|
||||||
|
}
|
||||||
|
|
||||||
let url: URL;
|
let url: URL;
|
||||||
if ('badge' in request.query) {
|
if ('badge' in request.query) {
|
||||||
url = new URL(`${this.config.mediaProxy}/emoji.png`);
|
url = new URL(`${this.config.mediaProxy}/emoji.png`);
|
||||||
// || emoji.originalUrl してるのは後方互換性のため(publicUrlはstringなので??はだめ)
|
// || emoji.originalUrl してるのは後方互換性のため(publicUrlはstringなので??はだめ)
|
||||||
url.searchParams.set('url', emoji.publicUrl || emoji.originalUrl);
|
url.searchParams.set('url', dbUrl);
|
||||||
url.searchParams.set('badge', '1');
|
url.searchParams.set('badge', '1');
|
||||||
} else {
|
} else {
|
||||||
url = new URL(`${this.config.mediaProxy}/emoji.webp`);
|
url = new URL(`${this.config.mediaProxy}/emoji.webp`);
|
||||||
// || emoji.originalUrl してるのは後方互換性のため(publicUrlはstringなので??はだめ)
|
// || emoji.originalUrl してるのは後方互換性のため(publicUrlはstringなので??はだめ)
|
||||||
url.searchParams.set('url', emoji.publicUrl || emoji.originalUrl);
|
url.searchParams.set('url', dbUrl);
|
||||||
url.searchParams.set('emoji', '1');
|
url.searchParams.set('emoji', '1');
|
||||||
if ('static' in request.query) url.searchParams.set('static', '1');
|
if ('static' in request.query) url.searchParams.set('static', '1');
|
||||||
}
|
}
|
||||||
|
@ -392,6 +406,16 @@ export class ServerService implements OnApplicationShutdown {
|
||||||
reply.header('Cache-Control', 'public, max-age=86400');
|
reply.header('Cache-Control', 'public, max-age=86400');
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
|
const dbUrl = user?.avatarUrl ?? this.userEntityService.getIdenticonUrl(user);
|
||||||
|
const dbUrlParsed = new URL(dbUrl);
|
||||||
|
const instanceUrl = new URL(this.config.url);
|
||||||
|
if (dbUrlParsed.origin === instanceUrl.origin) {
|
||||||
|
if (!redirectSafePath(dbUrlParsed.pathname)) {
|
||||||
|
return await reply.status(508);
|
||||||
|
}
|
||||||
|
return await reply.redirect(dbUrl, 301);
|
||||||
|
}
|
||||||
|
|
||||||
reply.redirect(user.avatarUrl ?? this.userEntityService.getIdenticonUrl(user));
|
reply.redirect(user.avatarUrl ?? this.userEntityService.getIdenticonUrl(user));
|
||||||
} else {
|
} else {
|
||||||
reply.redirect('/static-assets/user-unknown.png');
|
reply.redirect('/static-assets/user-unknown.png');
|
||||||
|
|
Loading…
Reference in a new issue