fix (backend): make sure that instance info fit in the database (close #10891)
I guess there is a better way to do this...
This commit is contained in:
parent
3f918f9dcc
commit
e1345e4e29
3 changed files with 76 additions and 21 deletions
|
@ -1,6 +1,19 @@
|
|||
import { Entity, PrimaryColumn, Index, Column } from "typeorm";
|
||||
import { id } from "../id.js";
|
||||
|
||||
export const MAX_LENGTH_INSTANCE = {
|
||||
host: 512,
|
||||
softwareName: 64,
|
||||
softwareVersion: 64,
|
||||
name: 256,
|
||||
description: 4096,
|
||||
maintainerName: 128,
|
||||
maintainerEmail: 256,
|
||||
iconUrl: 4096,
|
||||
faviconUrl: 4096,
|
||||
themeColor: 64,
|
||||
};
|
||||
|
||||
@Entity()
|
||||
export class Instance {
|
||||
@PrimaryColumn(id())
|
||||
|
@ -20,7 +33,7 @@ export class Instance {
|
|||
*/
|
||||
@Index({ unique: true })
|
||||
@Column("varchar", {
|
||||
length: 512,
|
||||
length: MAX_LENGTH_INSTANCE.host,
|
||||
comment: "The host of the Instance.",
|
||||
})
|
||||
public host: string;
|
||||
|
@ -107,14 +120,14 @@ export class Instance {
|
|||
public isSuspended: boolean;
|
||||
|
||||
@Column("varchar", {
|
||||
length: 64,
|
||||
length: MAX_LENGTH_INSTANCE.softwareName,
|
||||
nullable: true,
|
||||
comment: "The software of the Instance.",
|
||||
})
|
||||
public softwareName: string | null;
|
||||
|
||||
@Column("varchar", {
|
||||
length: 64,
|
||||
length: MAX_LENGTH_INSTANCE.softwareVersion,
|
||||
nullable: true,
|
||||
})
|
||||
public softwareVersion: string | null;
|
||||
|
@ -125,43 +138,43 @@ export class Instance {
|
|||
public openRegistrations: boolean | null;
|
||||
|
||||
@Column("varchar", {
|
||||
length: 256,
|
||||
length: MAX_LENGTH_INSTANCE.name,
|
||||
nullable: true,
|
||||
})
|
||||
public name: string | null;
|
||||
|
||||
@Column("varchar", {
|
||||
length: 4096,
|
||||
length: MAX_LENGTH_INSTANCE.description,
|
||||
nullable: true,
|
||||
})
|
||||
public description: string | null;
|
||||
|
||||
@Column("varchar", {
|
||||
length: 128,
|
||||
length: MAX_LENGTH_INSTANCE.maintainerName,
|
||||
nullable: true,
|
||||
})
|
||||
public maintainerName: string | null;
|
||||
|
||||
@Column("varchar", {
|
||||
length: 256,
|
||||
length: MAX_LENGTH_INSTANCE.maintainerEmail,
|
||||
nullable: true,
|
||||
})
|
||||
public maintainerEmail: string | null;
|
||||
|
||||
@Column("varchar", {
|
||||
length: 4096,
|
||||
length: MAX_LENGTH_INSTANCE.iconUrl,
|
||||
nullable: true,
|
||||
})
|
||||
public iconUrl: string | null;
|
||||
|
||||
@Column("varchar", {
|
||||
length: 4096,
|
||||
length: MAX_LENGTH_INSTANCE.faviconUrl,
|
||||
nullable: true,
|
||||
})
|
||||
public faviconUrl: string | null;
|
||||
|
||||
@Column("varchar", {
|
||||
length: 64,
|
||||
length: MAX_LENGTH_INSTANCE.themeColor,
|
||||
nullable: true,
|
||||
})
|
||||
public themeColor: string | null;
|
||||
|
|
|
@ -3,7 +3,10 @@ import { Window } from "happy-dom";
|
|||
import fetch from "node-fetch";
|
||||
import tinycolor from "tinycolor2";
|
||||
import { getJson, getAgentByUrl } from "@/misc/fetch.js";
|
||||
import type { Instance } from "@/models/entities/instance.js";
|
||||
import {
|
||||
type Instance,
|
||||
MAX_LENGTH_INSTANCE,
|
||||
} from "@/models/entities/instance.js";
|
||||
import { Instances } from "@/models/index.js";
|
||||
import { getFetchInstanceMetadataLock } from "@/misc/app-lock.js";
|
||||
import Logger from "@/services/logger.js";
|
||||
|
@ -53,26 +56,52 @@ export async function fetchInstanceMetadata(
|
|||
} as Record<string, any>;
|
||||
|
||||
if (info) {
|
||||
updates.softwareName = info.software?.name?.toLowerCase() || null;
|
||||
updates.softwareVersion = info.software?.version;
|
||||
updates.softwareName =
|
||||
info.software?.name
|
||||
?.toLowerCase()
|
||||
.substring(0, MAX_LENGTH_INSTANCE.softwareName) || null;
|
||||
updates.softwareVersion =
|
||||
info.software?.version?.substring(
|
||||
0,
|
||||
MAX_LENGTH_INSTANCE.softwareVersion,
|
||||
) || null;
|
||||
updates.openRegistrations = info.openRegistrations;
|
||||
updates.maintainerName = info.metadata
|
||||
? info.metadata.maintainer
|
||||
? info.metadata.maintainer.name || null
|
||||
? info.metadata.maintainer.name?.substring(
|
||||
0,
|
||||
MAX_LENGTH_INSTANCE.maintainerName,
|
||||
) || null
|
||||
: null
|
||||
: null;
|
||||
updates.maintainerEmail = info.metadata
|
||||
? info.metadata.maintainer
|
||||
? info.metadata.maintainer.email || null
|
||||
? info.metadata.maintainer.email?.substring(
|
||||
0,
|
||||
MAX_LENGTH_INSTANCE.maintainerEmail,
|
||||
) || null
|
||||
: null
|
||||
: null;
|
||||
}
|
||||
|
||||
if (name) updates.name = name;
|
||||
if (description) updates.description = description;
|
||||
if (icon || favicon) updates.iconUrl = icon || favicon;
|
||||
if (favicon) updates.faviconUrl = favicon;
|
||||
if (themeColor) updates.themeColor = themeColor;
|
||||
if (name) updates.name = name.substring(0, MAX_LENGTH_INSTANCE.name);
|
||||
if (description)
|
||||
updates.description = description.substring(
|
||||
0,
|
||||
MAX_LENGTH_INSTANCE.description,
|
||||
);
|
||||
if (icon || favicon)
|
||||
updates.iconUrl = (icon || favicon)?.substring(
|
||||
0,
|
||||
MAX_LENGTH_INSTANCE.iconUrl,
|
||||
);
|
||||
if (favicon)
|
||||
updates.faviconUrl = favicon.substring(0, MAX_LENGTH_INSTANCE.faviconUrl);
|
||||
if (themeColor)
|
||||
updates.themeColor = themeColor.substring(
|
||||
0,
|
||||
MAX_LENGTH_INSTANCE.themeColor,
|
||||
);
|
||||
|
||||
await Instances.update(instance.id, updates);
|
||||
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
import type { Instance } from "@/models/entities/instance.js";
|
||||
import {
|
||||
type Instance,
|
||||
MAX_LENGTH_INSTANCE,
|
||||
} from "@/models/entities/instance.js";
|
||||
import { Instances } from "@/models/index.js";
|
||||
import { genId } from "@/misc/gen-id.js";
|
||||
import { toPuny } from "@/misc/convert-host.js";
|
||||
import { Cache } from "@/misc/cache.js";
|
||||
import Logger from "@/services/logger.js";
|
||||
|
||||
const logger = new Logger("register-or-fetch-instance");
|
||||
const cache = new Cache<Instance>("registerOrFetchInstanceDoc", 60 * 60);
|
||||
|
||||
export async function registerOrFetchInstanceDoc(
|
||||
|
@ -11,6 +16,14 @@ export async function registerOrFetchInstanceDoc(
|
|||
): Promise<Instance> {
|
||||
const _host = toPuny(host);
|
||||
|
||||
if (_host.length > MAX_LENGTH_INSTANCE.host) {
|
||||
logger.error(
|
||||
`Instance host name must not be longer than ${MAX_LENGTH_INSTANCE.host} characters`,
|
||||
);
|
||||
logger.error(`hostname: ${_host}`);
|
||||
throw new Error("Instance host name is too long");
|
||||
}
|
||||
|
||||
const cached = await cache.get(_host);
|
||||
if (cached) return cached;
|
||||
|
||||
|
|
Loading…
Reference in a new issue