Add signature for proxied URLs; Proxy Avatar and Banner #8
4 changed files with 24 additions and 9 deletions
|
@ -96,6 +96,7 @@ type Source = {
|
|||
inboxJobMaxAttempts?: number;
|
||||
|
||||
mediaProxy?: string;
|
||||
mediaProxySecret?: string;
|
||||
proxyRemoteFiles?: boolean;
|
||||
videoThumbnailGenerator?: string;
|
||||
|
||||
|
@ -193,6 +194,7 @@ export type Config = {
|
|||
frontendEmbedEntry: string;
|
||||
frontendEmbedManifestExists: boolean;
|
||||
mediaProxy: string;
|
||||
mediaProxySecret: string;
|
||||
externalMediaProxyEnabled: boolean;
|
||||
videoThumbnailGenerator: string | null;
|
||||
redis: RedisOptions & RedisOptionsSource;
|
||||
|
@ -333,6 +335,7 @@ export function loadConfig(): Config {
|
|||
attachLdSignatureForRelays: config.attachLdSignatureForRelays ?? true,
|
||||
checkActivityPubGetSignature: config.checkActivityPubGetSignature,
|
||||
mediaProxy: externalMediaProxy ?? internalMediaProxy,
|
||||
mediaProxySecret: config.mediaProxySecret,
|
||||
externalMediaProxyEnabled: externalMediaProxy !== null && externalMediaProxy !== internalMediaProxy,
|
||||
videoThumbnailGenerator: config.videoThumbnailGenerator ?
|
||||
config.videoThumbnailGenerator.endsWith('/') ? config.videoThumbnailGenerator.substring(0, config.videoThumbnailGenerator.length - 1) : config.videoThumbnailGenerator
|
||||
|
|
|
@ -249,10 +249,13 @@ export class ApRendererService {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
public renderImage(file: MiDriveFile): IApImage {
|
||||
public renderImage(file: MiDriveFile, mode: 'avatar' | 'banner' = 'avatar'): IApImage {
|
||||
return {
|
||||
type: 'Image',
|
||||
url: this.driveFileEntityService.getPublicUrl(file),
|
||||
url: this.driveFileEntityService.getProxiedUrl(
|
||||
this.driveFileEntityService.getPublicUrl(file)
|
||||
mode,
|
||||
),
|
||||
sensitive: file.isSensitive,
|
||||
name: file.comment,
|
||||
};
|
||||
|
@ -517,8 +520,8 @@ export class ApRendererService {
|
|||
summary: profile.description ? this.mfmService.toHtml(mfm.parse(profile.description)) : null,
|
||||
_misskey_summary: profile.description,
|
||||
_misskey_followedMessage: profile.followedMessage,
|
||||
icon: avatar ? this.renderImage(avatar) : null,
|
||||
image: banner ? this.renderImage(banner) : null,
|
||||
icon: avatar ? this.renderImage(avatar, 'avatar') : null,
|
||||
image: banner ? this.renderImage(banner, 'banner') : null,
|
||||
backgroundUrl: background ? this.renderImage(background) : null,
|
||||
tag,
|
||||
manuallyApprovesFollowers: user.isLocked,
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import * as crypto from 'node:crypto';
|
||||
import { forwardRef, Inject, Injectable } from '@nestjs/common';
|
||||
import { In } from 'typeorm';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
|
@ -74,12 +75,16 @@ export class DriveFileEntityService {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
private getProxiedUrl(url: string, mode?: 'static' | 'avatar'): string {
|
||||
public getProxiedUrl(url: string, mode?: 'static' | 'avatar' | 'banner'): string {
|
||||
const signature = crypto.createHmac('sha256', this.config.mediaProxySecret)
|
||||
.update(url)
|
||||
.digest('hex')[8];
|
||||
return appendQuery(
|
||||
`${this.config.mediaProxy}/${mode ?? 'image'}.webp`,
|
||||
query({
|
||||
url,
|
||||
...(mode ? { [mode]: '1' } : {}),
|
||||
sign: signature
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
import * as fs from 'node:fs';
|
||||
import * as crypto from 'node:crypto';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { dirname } from 'node:path';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
|
@ -317,10 +318,13 @@ export class FileServerService {
|
|||
);
|
||||
}
|
||||
|
||||
if (!request.headers['user-agent']) {
|
||||
throw new StatusError('User-Agent is required', 400, 'User-Agent is required');
|
||||
} else if (request.headers['user-agent'].toLowerCase().indexOf('misskey/') !== -1) {
|
||||
throw new StatusError('Refusing to proxy a request from another proxy', 403, 'Proxy is recursive');
|
||||
const signature = crypto.createHmac('sha256', this.config.mediaProxySecret)
|
||||
.update(url)
|
||||
.digest('hex')[8];
|
||||
|
||||
if (signature !== request.params.sign) {
|
||||
reply.code(403);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create temp file
|
||||
|
|
Loading…
Reference in a new issue