Preview arbitrary urls within a document (#5598)
This commit is contained in:
@@ -617,7 +617,7 @@ export class Environment {
|
||||
*/
|
||||
@IsOptional()
|
||||
@CannotUseWithout("IFRAMELY_URL")
|
||||
public IFRAMELY_API_KEY = process.env.IFRAMELY_API_KEY ?? "";
|
||||
public IFRAMELY_API_KEY = this.toOptionalString(process.env.IFRAMELY_API_KEY);
|
||||
|
||||
/**
|
||||
* The product name
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { User } from "@server/models";
|
||||
import { buildDocument, buildUser } from "@server/test/factories";
|
||||
import { getTestServer } from "@server/test/support";
|
||||
import { Iframely } from "@server/utils/unfurl";
|
||||
import resolvers from "@server/utils/unfurl";
|
||||
|
||||
jest.mock("@server/utils/unfurl", () => ({
|
||||
Iframely: {
|
||||
@@ -146,7 +146,7 @@ describe("#urls.unfurl", () => {
|
||||
});
|
||||
|
||||
it("should succeed with status 200 ok for a valid external url", async () => {
|
||||
(Iframely.unfurl as jest.Mock).mockResolvedValue(
|
||||
(resolvers.Iframely.unfurl as jest.Mock).mockResolvedValue(
|
||||
Promise.resolve({
|
||||
url: "https://www.flickr.com",
|
||||
type: "rich",
|
||||
@@ -167,7 +167,9 @@ describe("#urls.unfurl", () => {
|
||||
|
||||
const body = await res.json();
|
||||
|
||||
expect(Iframely.unfurl).toHaveBeenCalledWith("https://www.flickr.com");
|
||||
expect(resolvers.Iframely.unfurl).toHaveBeenCalledWith(
|
||||
"https://www.flickr.com"
|
||||
);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.url).toEqual("https://www.flickr.com");
|
||||
expect(body.type).toEqual("rich");
|
||||
@@ -181,7 +183,7 @@ describe("#urls.unfurl", () => {
|
||||
});
|
||||
|
||||
it("should succeed with status 204 no content for a non-existing external url", async () => {
|
||||
(Iframely.unfurl as jest.Mock).mockResolvedValue(
|
||||
(resolvers.Iframely.unfurl as jest.Mock).mockResolvedValue(
|
||||
Promise.resolve({
|
||||
status: 404,
|
||||
error:
|
||||
@@ -196,7 +198,9 @@ describe("#urls.unfurl", () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(Iframely.unfurl).toHaveBeenCalledWith("https://random.url");
|
||||
expect(resolvers.Iframely.unfurl).toHaveBeenCalledWith(
|
||||
"https://random.url"
|
||||
);
|
||||
expect(res.status).toEqual(204);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11,7 +11,7 @@ import { presentDocument, presentMention } from "@server/presenters/unfurls";
|
||||
import presentUnfurl from "@server/presenters/unfurls/unfurl";
|
||||
import { APIContext } from "@server/types";
|
||||
import { RateLimiterStrategy } from "@server/utils/RateLimiter";
|
||||
import { Iframely } from "@server/utils/unfurl";
|
||||
import resolvers from "@server/utils/unfurl";
|
||||
import * as T from "./schema";
|
||||
|
||||
const router = new Router();
|
||||
@@ -62,12 +62,14 @@ router.post(
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await Iframely.unfurl(url);
|
||||
if (data.error) {
|
||||
ctx.response.status = 204;
|
||||
return;
|
||||
if (resolvers.Iframely) {
|
||||
const data = await resolvers.Iframely.unfurl(url);
|
||||
return data.error
|
||||
? (ctx.response.status = 204)
|
||||
: (ctx.body = presentUnfurl(data));
|
||||
}
|
||||
ctx.body = presentUnfurl(data);
|
||||
|
||||
return (ctx.response.status = 204);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { existsSync } from "fs";
|
||||
import path from "path";
|
||||
import glob from "glob";
|
||||
import { startCase } from "lodash";
|
||||
@@ -5,20 +6,36 @@ import env from "@server/env";
|
||||
import Logger from "@server/logging/Logger";
|
||||
import { UnfurlResolver } from "@server/types";
|
||||
|
||||
const resolvers: Record<string, UnfurlResolver> = {};
|
||||
const rootDir = env.ENVIRONMENT === "test" ? "" : "build";
|
||||
|
||||
glob
|
||||
.sync(path.join(rootDir, "plugins/*/server/unfurl.js"))
|
||||
.forEach((filePath: string) => {
|
||||
const hasResolver = (plugin: string) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const config = require(path.join(process.cwd(), plugin, "plugin.json"));
|
||||
|
||||
return (
|
||||
existsSync(resolverPath(plugin)) &&
|
||||
(config.requiredEnvVars ?? []).every((name: string) => !!env[name])
|
||||
);
|
||||
};
|
||||
|
||||
const resolverPath = (plugin: string) =>
|
||||
path.join(plugin, "server", "unfurl.js");
|
||||
|
||||
const plugins = glob.sync(path.join(rootDir, "plugins/*"));
|
||||
const resolvers: Record<string, UnfurlResolver> = plugins
|
||||
.filter(hasResolver)
|
||||
.map(resolverPath)
|
||||
.reduce((resolvers, resolverPath) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const resolver: UnfurlResolver = require(path.join(
|
||||
process.cwd(),
|
||||
filePath
|
||||
resolverPath
|
||||
));
|
||||
const name = startCase(filePath.split("/")[2]);
|
||||
const name = startCase(resolverPath.split("/")[2]);
|
||||
resolvers[name] = resolver;
|
||||
Logger.debug("utils", `Registered unfurl resolver ${filePath}`);
|
||||
});
|
||||
Logger.debug("utils", `Registered unfurl resolver ${resolverPath}`);
|
||||
|
||||
export const Iframely = resolvers["Iframely"];
|
||||
return resolvers;
|
||||
}, {});
|
||||
|
||||
export default resolvers;
|
||||
|
||||
Reference in New Issue
Block a user