Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { TRPCError } from "@trpc/server";
|
||||
|
||||
import { objectEntries } from "@homarr/common";
|
||||
import { decryptSecret, encryptSecret } from "@homarr/common/server";
|
||||
import type { Database } from "@homarr/db";
|
||||
import { and, asc, createId, eq, inArray, like } from "@homarr/db";
|
||||
@@ -12,7 +13,14 @@ import {
|
||||
integrationUserPermissions,
|
||||
} from "@homarr/db/schema/sqlite";
|
||||
import type { IntegrationSecretKind } from "@homarr/definitions";
|
||||
import { getPermissionsWithParents, integrationKinds, integrationSecretKindObject } from "@homarr/definitions";
|
||||
import {
|
||||
getPermissionsWithParents,
|
||||
integrationDefs,
|
||||
integrationKinds,
|
||||
integrationSecretKindObject,
|
||||
isIntegrationWithSearchSupport,
|
||||
} from "@homarr/definitions";
|
||||
import { integrationCreatorFromSecrets } from "@homarr/integrations";
|
||||
import { validation, z } from "@homarr/validation";
|
||||
|
||||
import { createTRPCRouter, permissionRequiredProcedure, protectedProcedure, publicProcedure } from "../../trpc";
|
||||
@@ -62,6 +70,54 @@ export const integrationRouter = createTRPCRouter({
|
||||
integrationKinds.indexOf(integrationA.kind) - integrationKinds.indexOf(integrationB.kind),
|
||||
);
|
||||
}),
|
||||
allThatSupportSearch: publicProcedure.query(async ({ ctx }) => {
|
||||
const groupsOfCurrentUser = await ctx.db.query.groupMembers.findMany({
|
||||
where: eq(groupMembers.userId, ctx.session?.user.id ?? ""),
|
||||
});
|
||||
|
||||
const integrationsFromDb = await ctx.db.query.integrations.findMany({
|
||||
with: {
|
||||
userPermissions: {
|
||||
where: eq(integrationUserPermissions.userId, ctx.session?.user.id ?? ""),
|
||||
},
|
||||
groupPermissions: {
|
||||
where: inArray(
|
||||
integrationGroupPermissions.groupId,
|
||||
groupsOfCurrentUser.map((group) => group.groupId),
|
||||
),
|
||||
},
|
||||
},
|
||||
where: inArray(
|
||||
integrations.kind,
|
||||
objectEntries(integrationDefs)
|
||||
.filter(([_, integration]) => integration.supportsSearch)
|
||||
.map(([kind, _]) => kind),
|
||||
),
|
||||
});
|
||||
return integrationsFromDb
|
||||
.map((integration) => {
|
||||
const permissions = integration.userPermissions
|
||||
.map(({ permission }) => permission)
|
||||
.concat(integration.groupPermissions.map(({ permission }) => permission));
|
||||
|
||||
return {
|
||||
id: integration.id,
|
||||
name: integration.name,
|
||||
kind: integration.kind,
|
||||
url: integration.url,
|
||||
permissions: {
|
||||
hasUseAccess:
|
||||
permissions.includes("use") || permissions.includes("interact") || permissions.includes("full"),
|
||||
hasInteractAccess: permissions.includes("interact") || permissions.includes("full"),
|
||||
hasFullAccess: permissions.includes("full"),
|
||||
},
|
||||
};
|
||||
})
|
||||
.sort(
|
||||
(integrationA, integrationB) =>
|
||||
integrationKinds.indexOf(integrationA.kind) - integrationKinds.indexOf(integrationB.kind),
|
||||
);
|
||||
}),
|
||||
search: protectedProcedure
|
||||
.input(z.object({ query: z.string(), limit: z.number().min(1).max(100).default(10) }))
|
||||
.query(async ({ ctx, input }) => {
|
||||
@@ -326,6 +382,33 @@ export const integrationRouter = createTRPCRouter({
|
||||
);
|
||||
});
|
||||
}),
|
||||
searchInIntegration: protectedProcedure
|
||||
.input(z.object({ integrationId: z.string(), query: z.string() }))
|
||||
.query(async ({ ctx, input }) => {
|
||||
const integration = await ctx.db.query.integrations.findFirst({
|
||||
where: eq(integrations.id, input.integrationId),
|
||||
with: {
|
||||
secrets: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!integration) {
|
||||
throw new TRPCError({
|
||||
code: "NOT_FOUND",
|
||||
message: "The requested integration does not exist",
|
||||
});
|
||||
}
|
||||
|
||||
if (!isIntegrationWithSearchSupport(integration)) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "The requested integration does not support searching",
|
||||
});
|
||||
}
|
||||
|
||||
const integrationInstance = integrationCreatorFromSecrets(integration);
|
||||
return await integrationInstance.searchAsync(input.query);
|
||||
}),
|
||||
});
|
||||
|
||||
interface UpdateSecretInput {
|
||||
|
||||
@@ -39,7 +39,19 @@ export const searchEngineRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
|
||||
return searchEngine;
|
||||
return searchEngine.type === "fromIntegration"
|
||||
? {
|
||||
...searchEngine,
|
||||
type: "fromIntegration" as const,
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
integrationId: searchEngine.integrationId!,
|
||||
}
|
||||
: {
|
||||
...searchEngine,
|
||||
type: "generic" as const,
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
urlTemplate: searchEngine.urlTemplate!,
|
||||
};
|
||||
}),
|
||||
search: protectedProcedure.input(validation.common.search).query(async ({ ctx, input }) => {
|
||||
return await ctx.db.query.searchEngines.findMany({
|
||||
@@ -53,8 +65,10 @@ export const searchEngineRouter = createTRPCRouter({
|
||||
name: input.name,
|
||||
short: input.short.toLowerCase(),
|
||||
iconUrl: input.iconUrl,
|
||||
urlTemplate: input.urlTemplate,
|
||||
urlTemplate: "urlTemplate" in input ? input.urlTemplate : null,
|
||||
description: input.description,
|
||||
type: input.type,
|
||||
integrationId: "integrationId" in input ? input.integrationId : null,
|
||||
});
|
||||
}),
|
||||
update: protectedProcedure.input(validation.searchEngine.edit).mutation(async ({ ctx, input }) => {
|
||||
@@ -74,8 +88,10 @@ export const searchEngineRouter = createTRPCRouter({
|
||||
.set({
|
||||
name: input.name,
|
||||
iconUrl: input.iconUrl,
|
||||
urlTemplate: input.urlTemplate,
|
||||
urlTemplate: "urlTemplate" in input ? input.urlTemplate : null,
|
||||
description: input.description,
|
||||
integrationId: "integrationId" in input ? input.integrationId : null,
|
||||
type: input.type,
|
||||
})
|
||||
.where(eq(searchEngines.id, input.id));
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user