Matomo integration (#7009)
This commit is contained in:
@@ -7,16 +7,16 @@ import { Integration } from "@server/models";
|
||||
export default function present(
|
||||
env: Environment,
|
||||
options: {
|
||||
analytics?: Integration<IntegrationType.Analytics> | null;
|
||||
analytics?: Integration<IntegrationType.Analytics>[];
|
||||
rootShareId?: string | null;
|
||||
} = {}
|
||||
): PublicEnv {
|
||||
return {
|
||||
ROOT_SHARE_ID: options.rootShareId || undefined,
|
||||
analytics: {
|
||||
service: options.analytics?.service,
|
||||
settings: options.analytics?.settings,
|
||||
},
|
||||
analytics: (options.analytics ?? []).map((integration) => ({
|
||||
service: integration?.service,
|
||||
settings: integration?.settings,
|
||||
})),
|
||||
...env.public,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -51,7 +51,12 @@ export const IntegrationsCreateSchema = BaseSchema.extend({
|
||||
channelId: z.string(),
|
||||
})
|
||||
)
|
||||
.or(z.object({ measurementId: z.string() }))
|
||||
.or(
|
||||
z.object({
|
||||
measurementId: z.string(),
|
||||
instanceUrl: z.string().url().optional(),
|
||||
})
|
||||
)
|
||||
.or(z.object({ serviceTeamId: z.string() }))
|
||||
.optional(),
|
||||
}),
|
||||
@@ -74,7 +79,12 @@ export const IntegrationsUpdateSchema = BaseSchema.extend({
|
||||
channelId: z.string(),
|
||||
})
|
||||
)
|
||||
.or(z.object({ measurementId: z.string() }))
|
||||
.or(
|
||||
z.object({
|
||||
measurementId: z.string(),
|
||||
instanceUrl: z.string().url().optional(),
|
||||
})
|
||||
)
|
||||
.or(z.object({ serviceTeamId: z.string() }))
|
||||
.optional(),
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ export const renderApp = async (
|
||||
canonical?: string;
|
||||
shortcutIcon?: string;
|
||||
rootShareId?: string;
|
||||
analytics?: Integration | null;
|
||||
analytics?: Integration<IntegrationType.Analytics>[];
|
||||
} = {}
|
||||
) => {
|
||||
const {
|
||||
@@ -66,6 +66,19 @@ export const renderApp = async (
|
||||
return next();
|
||||
}
|
||||
|
||||
if (!env.isCloudHosted) {
|
||||
options.analytics?.forEach((integration) => {
|
||||
if (integration.settings?.instanceUrl) {
|
||||
const parsed = new URL(integration.settings?.instanceUrl);
|
||||
const csp = ctx.response.get("Content-Security-Policy");
|
||||
ctx.set(
|
||||
"Content-Security-Policy",
|
||||
csp.replace("script-src", `script-src ${parsed.hostname}`)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const { shareId } = ctx.params;
|
||||
const page = await readIndexFile();
|
||||
const environment = `
|
||||
@@ -112,7 +125,8 @@ export const renderShare = async (ctx: Context, next: Next) => {
|
||||
// Find the share record if publicly published so that the document title
|
||||
// can be be returned in the server-rendered HTML. This allows it to appear in
|
||||
// unfurls with more reliablity
|
||||
let share, document, team, analytics;
|
||||
let share, document, team;
|
||||
let analytics: Integration<IntegrationType.Analytics>[] = [];
|
||||
|
||||
try {
|
||||
team = await getTeamFromContext(ctx);
|
||||
@@ -131,7 +145,7 @@ export const renderShare = async (ctx: Context, next: Next) => {
|
||||
}
|
||||
document = result.document;
|
||||
|
||||
analytics = await Integration.findOne({
|
||||
analytics = await Integration.findAll({
|
||||
where: {
|
||||
teamId: document.teamId,
|
||||
type: IntegrationType.Analytics,
|
||||
|
||||
@@ -147,13 +147,13 @@ router.get("*", shareDomains(), async (ctx, next) => {
|
||||
}
|
||||
|
||||
const analytics = team
|
||||
? await Integration.findOne({
|
||||
? await Integration.findAll({
|
||||
where: {
|
||||
teamId: team.id,
|
||||
type: IntegrationType.Analytics,
|
||||
},
|
||||
})
|
||||
: undefined;
|
||||
: [];
|
||||
|
||||
return renderApp(ctx, next, {
|
||||
analytics,
|
||||
|
||||
Reference in New Issue
Block a user