mirror of
https://github.com/fosrl/pangolin.git
synced 2026-08-15 08:49:59 +02:00
send email upon generate virtual api key
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
import { db, resources, users, virtualApiKeyResources } from "@server/db";
|
||||
import { and, asc, eq } from "drizzle-orm";
|
||||
import config from "@server/lib/config";
|
||||
import { sendEmail } from "@server/emails";
|
||||
import VirtualApiKeyGenerated from "@server/emails/templates/VirtualApiKeyGenerated";
|
||||
import { formatVirtualApiKeyCredential } from "@server/lib/virtualApiKey";
|
||||
|
||||
const EMAIL_GATEWAY_URL_LIMIT = 5;
|
||||
|
||||
async function listVirtualApiKeyGatewayUrls(params: {
|
||||
orgId: string;
|
||||
allResources: boolean;
|
||||
virtualApiKeyId: string;
|
||||
}): Promise<{ urls: string[]; hasMore: boolean }> {
|
||||
const rows = params.allResources
|
||||
? await db
|
||||
.select({
|
||||
fullDomain: resources.fullDomain,
|
||||
ssl: resources.ssl
|
||||
})
|
||||
.from(resources)
|
||||
.where(
|
||||
and(
|
||||
eq(resources.orgId, params.orgId),
|
||||
eq(resources.mode, "inference")
|
||||
)
|
||||
)
|
||||
.orderBy(asc(resources.name))
|
||||
.limit(EMAIL_GATEWAY_URL_LIMIT + 1)
|
||||
: await db
|
||||
.select({
|
||||
fullDomain: resources.fullDomain,
|
||||
ssl: resources.ssl
|
||||
})
|
||||
.from(virtualApiKeyResources)
|
||||
.innerJoin(
|
||||
resources,
|
||||
eq(virtualApiKeyResources.resourceId, resources.resourceId)
|
||||
)
|
||||
.where(
|
||||
eq(
|
||||
virtualApiKeyResources.virtualApiKeyId,
|
||||
params.virtualApiKeyId
|
||||
)
|
||||
)
|
||||
.orderBy(asc(resources.name))
|
||||
.limit(EMAIL_GATEWAY_URL_LIMIT + 1);
|
||||
|
||||
const urls = rows
|
||||
.map((row) =>
|
||||
row.fullDomain
|
||||
? `${row.ssl ? "https" : "http"}://${row.fullDomain}`
|
||||
: null
|
||||
)
|
||||
.filter((url): url is string => Boolean(url));
|
||||
|
||||
return {
|
||||
urls: urls.slice(0, EMAIL_GATEWAY_URL_LIMIT),
|
||||
hasMore: rows.length > EMAIL_GATEWAY_URL_LIMIT
|
||||
};
|
||||
}
|
||||
|
||||
export async function resolveVirtualApiKeyEmailRecipients(params: {
|
||||
sendEmail: boolean;
|
||||
sendToAttributedUser: boolean;
|
||||
userId: string | null | undefined;
|
||||
emails: string[];
|
||||
}): Promise<
|
||||
{ ok: true; recipients: string[] } | { ok: false; message: string }
|
||||
> {
|
||||
if (!params.sendEmail) {
|
||||
return { ok: true, recipients: [] };
|
||||
}
|
||||
|
||||
if (!config.getRawConfig().email) {
|
||||
return {
|
||||
ok: false,
|
||||
message: "Email is not configured on this server"
|
||||
};
|
||||
}
|
||||
|
||||
const recipients = new Set(
|
||||
params.emails.map((email) => email.trim().toLowerCase()).filter(Boolean)
|
||||
);
|
||||
|
||||
if (params.sendToAttributedUser) {
|
||||
if (!params.userId) {
|
||||
return {
|
||||
ok: false,
|
||||
message: "Associate a user to email the key to that user"
|
||||
};
|
||||
}
|
||||
|
||||
const [user] = await db
|
||||
.select({ email: users.email })
|
||||
.from(users)
|
||||
.where(eq(users.userId, params.userId))
|
||||
.limit(1);
|
||||
|
||||
if (!user?.email) {
|
||||
return {
|
||||
ok: false,
|
||||
message: "The associated user does not have an email address"
|
||||
};
|
||||
}
|
||||
|
||||
recipients.add(user.email.toLowerCase());
|
||||
}
|
||||
|
||||
if (recipients.size === 0) {
|
||||
return {
|
||||
ok: false,
|
||||
message: "Select at least one email recipient"
|
||||
};
|
||||
}
|
||||
|
||||
return { ok: true, recipients: [...recipients] };
|
||||
}
|
||||
|
||||
export async function sendVirtualApiKeyEmails(params: {
|
||||
recipients: string[];
|
||||
orgName: string;
|
||||
orgId: string;
|
||||
keyName: string | null;
|
||||
virtualApiKeyId: string;
|
||||
secret: string;
|
||||
allResources: boolean;
|
||||
}): Promise<void> {
|
||||
if (params.recipients.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const credential = formatVirtualApiKeyCredential(
|
||||
params.virtualApiKeyId,
|
||||
params.secret
|
||||
);
|
||||
const { urls, hasMore } = await listVirtualApiKeyGatewayUrls({
|
||||
orgId: params.orgId,
|
||||
allResources: params.allResources,
|
||||
virtualApiKeyId: params.virtualApiKeyId
|
||||
});
|
||||
const from = config.getNoReplyEmail();
|
||||
const subject = `Virtual API key for ${params.orgName}`;
|
||||
|
||||
for (const to of params.recipients) {
|
||||
await sendEmail(
|
||||
VirtualApiKeyGenerated({
|
||||
orgName: params.orgName,
|
||||
keyName: params.keyName,
|
||||
credential,
|
||||
resourceUrls: urls,
|
||||
hasMoreResources: hasMore
|
||||
}),
|
||||
{
|
||||
to,
|
||||
from,
|
||||
subject
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user