feat: switch metadata remover

This commit is contained in:
diced
2025-06-06 10:40:38 -07:00
parent d0a613ab8e
commit 4b3878d553
4 changed files with 42 additions and 56 deletions

View File

@@ -49,7 +49,6 @@
"@prisma/migrate": "^6.9.0",
"@smithy/node-http-handler": "^4.0.6",
"@tabler/icons-react": "^3.34.0",
"@xoi/gps-metadata-remover": "^2.0.0",
"argon2": "^0.43.0",
"bytes": "^3.1.2",
"clsx": "^2.1.1",
@@ -58,6 +57,7 @@
"cross-env": "^7.0.3",
"dayjs": "^1.11.13",
"dotenv": "^16.5.0",
"exif-be-gone": "^1.5.1",
"fast-glob": "^3.3.3",
"fastify": "^5.3.3",
"fastify-plugin": "^5.0.1",
@@ -89,7 +89,6 @@
"@eslint/eslintrc": "^3.3.1",
"@eslint/js": "^9.28.0",
"@types/bytes": "^3.1.5",
"@types/express": "^5.0.2",
"@types/fluent-ffmpeg": "^2.1.27",
"@types/katex": "^0.16.7",
"@types/ms": "^2.1.0",

43
pnpm-lock.yaml generated
View File

@@ -77,9 +77,6 @@ importers:
'@tabler/icons-react':
specifier: ^3.34.0
version: 3.34.0(react@19.1.0)
'@xoi/gps-metadata-remover':
specifier: ^2.0.0
version: 2.0.0
argon2:
specifier: ^0.43.0
version: 0.43.0
@@ -104,6 +101,9 @@ importers:
dotenv:
specifier: ^16.5.0
version: 16.5.0
exif-be-gone:
specifier: ^1.5.1
version: 1.5.1
fast-glob:
specifier: ^3.3.3
version: 3.3.3
@@ -192,9 +192,6 @@ importers:
'@types/bytes':
specifier: ^3.1.5
version: 3.1.5
'@types/express':
specifier: ^5.0.2
version: 5.0.2
'@types/fluent-ffmpeg':
specifier: ^2.1.27
version: 2.1.27
@@ -2086,12 +2083,6 @@ packages:
cpu: [x64]
os: [win32]
'@xoi/gps-metadata-remover@2.0.0':
resolution: {integrity: sha512-SDy5bX70IJ9nRfHG/URUo8kMMLWL4PwGdaQvC7WubjGESV5REgSN/nMQnZzSykC4Rj33xkS+O7Rs1wICzKS8Fw==}
Base64@1.3.0:
resolution: {integrity: sha512-7BjEEmnnW5pm6mBXKQ8CfQFeVjSoFnB507R86mKaJqa2i8CvosDy/dj+9RpbD0A22XQ+hGb0FHO+226C0QXRGw==}
abstract-logging@2.0.1:
resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==}
@@ -2417,15 +2408,6 @@ packages:
resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==}
engines: {node: '>=18'}
crc@4.3.2:
resolution: {integrity: sha512-uGDHf4KLLh2zsHa8D8hIQ1H/HtFQhyHrc0uhHBcoKGol/Xnb+MPYfUMw7cvON6ze/GUESTudKayDcJC5HnJv1A==}
engines: {node: '>=12'}
peerDependencies:
buffer: '>=6.0.3'
peerDependenciesMeta:
buffer:
optional: true
cross-env@7.0.3:
resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==}
engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'}
@@ -2836,6 +2818,10 @@ packages:
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
engines: {node: '>=0.8.x'}
exif-be-gone@1.5.1:
resolution: {integrity: sha512-+fV9PoomNVR5Hmp0n1c0ZVl78/GaFrpnC0t7q4F9Aey8NcL+7Lutcez8KY2Ni30NWpvgLXawqiRFFwtdo4QgFg==}
hasBin: true
extend@3.0.2:
resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
@@ -7015,17 +7001,6 @@ snapshots:
'@unrs/resolver-binding-win32-x64-msvc@1.7.11':
optional: true
'@xoi/gps-metadata-remover@2.0.0':
dependencies:
Base64: 1.3.0
crc: 4.3.2
debug: 4.4.1
transitivePeerDependencies:
- buffer
- supports-color
Base64@1.3.0: {}
abstract-logging@2.0.1: {}
acorn-jsx@5.3.2(acorn@8.14.0):
@@ -7339,8 +7314,6 @@ snapshots:
cookie@1.0.2: {}
crc@4.3.2: {}
cross-env@7.0.3:
dependencies:
cross-spawn: 7.0.6
@@ -7898,6 +7871,8 @@ snapshots:
events@3.3.0: {}
exif-be-gone@1.5.1: {}
extend@3.0.2: {}
fast-decode-uri-component@1.0.1: {}

View File

@@ -110,11 +110,17 @@ export async function handleFile({
}
let removedGps = false;
if (mimetype.startsWith('image/') && config.files.removeGpsMetadata) {
removedGps = await removeGps(file.buffer);
if (removedGps) {
logger.c('gps').debug(`removed gps metadata from ${file.filename}`);
if (mimetype.startsWith('image/') && config.files.removeGpsMetadata) {
file.buffer = await removeGps(file.buffer);
if (file.buffer.length < file.file.bytesRead) {
logger.c('gps').debug(`removed gps metadata from ${file.filename}`, {
nsize: bytes(file.buffer.length),
osize: bytes(file.file.bytesRead),
});
removedGps = true;
}
}

View File

@@ -1,21 +1,27 @@
// @ts-ignore
import * as gmr from '@xoi/gps-metadata-remover';
import ExifTransformer from 'exif-be-gone';
import { PassThrough } from 'stream';
export const removeLocation = gmr.removeLocation as (
photoUri: string,
read: ReadFunction,
write: WriteFunction,
) => Promise<boolean>;
export async function removeGps(buffer: Buffer): Promise<Buffer> {
return new Promise<Buffer>((resolve, reject) => {
const input = new PassThrough();
input.end(buffer);
export type ReadFunction = (size: number, offset: number) => Promise<Buffer>;
export type WriteFunction = (writeValue: string, entryOffset: number, encoding: string) => Promise<void>;
const transformer = new ExifTransformer();
export async function removeGps(buffer: Buffer): Promise<boolean> {
const read = (size: number, offset: number) => Promise.resolve(buffer.subarray(offset, offset + size));
const write = (writeValue: string, entryOffset: number, encoding: string) => {
buffer.write(writeValue, entryOffset, encoding as BufferEncoding);
return Promise.resolve();
};
const chunks: Buffer[] = [];
transformer.on('data', (chunk: Buffer) => {
chunks.push(chunk);
});
return removeLocation('', read, write);
transformer.once('error', (err: Error) => {
reject(err);
});
transformer.once('end', () => {
const stripped = Buffer.concat(chunks);
resolve(stripped);
});
input.pipe(transformer);
});
}