Really huge mass update; Getting everything up-to-spec and implementing a wide range of features
This commit is contained in:
@@ -4,7 +4,7 @@ import { prisma } from "../../lib/db";
|
||||
import { makeResponse } from "../../lib/response";
|
||||
import { ERROR_MESSAGES } from "../../lib/errors";
|
||||
import { encrypt, decrypt } from "../../lib/encryption";
|
||||
import { validateGiteaUrl } from "../../services/gitea";
|
||||
import { updateWebhookSecret, validateGiteaUrl, validateGiteaToken } from "../../services/gitea";
|
||||
import { validateAwsCredentials } from "../../services/ec2";
|
||||
import { env } from "../../lib/env";
|
||||
|
||||
@@ -14,6 +14,39 @@ function requireAuth(ctr: any) {
|
||||
return auth.user;
|
||||
}
|
||||
|
||||
async function getOrCreateWebhookToken(userId: number) {
|
||||
const existing = await prisma.webhookToken.findUnique({ where: { userId } });
|
||||
if (existing) return existing;
|
||||
|
||||
const secret = randomBytes(32).toString("hex");
|
||||
return prisma.webhookToken.create({ data: { userId, token: secret } });
|
||||
}
|
||||
|
||||
async function syncRegisteredRepoWebhooks(userId: number, fullUser: any, secret: string) {
|
||||
if (!fullUser?.giteaInstanceUrl || !fullUser?.giteaPAT) {
|
||||
return { updated: 0, errors: [] as string[] };
|
||||
}
|
||||
|
||||
const configs = await prisma.repoConfig.findMany({
|
||||
where: { userId, giteaWebhookId: { not: null } },
|
||||
});
|
||||
|
||||
const webhookUrl = `${env.PP_BASE_URL}/webhook/${userId}`;
|
||||
const errors: string[] = [];
|
||||
let updated = 0;
|
||||
|
||||
for (const config of configs) {
|
||||
try {
|
||||
await updateWebhookSecret(fullUser, config.repoOwner, config.repoName, config.giteaWebhookId!, webhookUrl, secret);
|
||||
updated++;
|
||||
} catch (e: any) {
|
||||
errors.push(`${config.repoOwner}/${config.repoName}: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
return { updated, errors };
|
||||
}
|
||||
|
||||
export async function getUserSettings(ctr: any) {
|
||||
const user = requireAuth(ctr);
|
||||
if (!user) return makeResponse({ ctr, content: { code: ERROR_MESSAGES.UNAUTHORIZED.code, message: ERROR_MESSAGES.UNAUTHORIZED.message } });
|
||||
@@ -88,17 +121,38 @@ export async function updateGitea(ctr: any) {
|
||||
}
|
||||
|
||||
const data: any = { giteaInstanceUrl: cleanUrl, giteaUsername };
|
||||
if (giteaPAT) data.giteaPAT = encrypt(giteaPAT);
|
||||
if (giteaPAT) {
|
||||
const tokenCheck = await validateGiteaToken(cleanUrl, giteaPAT, giteaUsername);
|
||||
if (!tokenCheck.success) {
|
||||
return makeResponse({ ctr, content: { code: 400, message: `Gitea token rejected: ${tokenCheck.error}` } });
|
||||
}
|
||||
data.giteaPAT = encrypt(giteaPAT);
|
||||
}
|
||||
|
||||
await prisma.user.update({ where: { id: user.id }, data });
|
||||
return makeResponse({ ctr, content: { code: 200, message: `Connected to Gitea ${validation.version}`, data: { version: validation.version } } });
|
||||
const updatedUser = await prisma.user.update({ where: { id: user.id }, data });
|
||||
const webhookToken = await getOrCreateWebhookToken(user.id);
|
||||
const hookSync = await syncRegisteredRepoWebhooks(user.id, updatedUser, webhookToken.token);
|
||||
|
||||
return makeResponse({
|
||||
ctr, content: {
|
||||
code: 200,
|
||||
message: hookSync.errors.length
|
||||
? `Connected to Gitea ${validation.version}; ${hookSync.updated} webhooks updated, ${hookSync.errors.length} failed`
|
||||
: hookSync.updated > 0
|
||||
? `Connected to Gitea ${validation.version}; ${hookSync.updated} webhooks updated`
|
||||
: `Connected to Gitea ${validation.version}`,
|
||||
data: { version: validation.version, hookSync },
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function updateAws(ctr: any) {
|
||||
const user = requireAuth(ctr);
|
||||
if (!user) return makeResponse({ ctr, content: { code: 401, message: ERROR_MESSAGES.UNAUTHORIZED.message } });
|
||||
const body = await ctr.body();
|
||||
const { awsAccessKeyId, awsSecretAccessKey, awsRegion } = body || {};
|
||||
const awsAccessKeyId = typeof body?.awsAccessKeyId === "string" ? body.awsAccessKeyId.trim() : body?.awsAccessKeyId;
|
||||
const awsSecretAccessKey = typeof body?.awsSecretAccessKey === "string" ? body.awsSecretAccessKey.trim() : body?.awsSecretAccessKey;
|
||||
const awsRegion = typeof body?.awsRegion === "string" ? body.awsRegion.trim() : body?.awsRegion;
|
||||
|
||||
if (!awsAccessKeyId || !awsSecretAccessKey || !awsRegion) {
|
||||
return makeResponse({ ctr, content: { code: 400, message: "AWS credentials and region required" } });
|
||||
@@ -131,13 +185,9 @@ export async function getWebhookSecret(ctr: any) {
|
||||
const user = requireAuth(ctr);
|
||||
if (!user) return makeResponse({ ctr, content: { code: 401, message: ERROR_MESSAGES.UNAUTHORIZED.message } });
|
||||
|
||||
let token = await prisma.webhookToken.findUnique({ where: { userId: user.id } });
|
||||
if (!token) {
|
||||
const secret = randomBytes(32).toString("hex");
|
||||
token = await prisma.webhookToken.create({ data: { userId: user.id, token: secret } });
|
||||
}
|
||||
const token = await getOrCreateWebhookToken(user.id);
|
||||
|
||||
return makeResponse({ ctr, content: { code: 200, data: { token: token.token } } });
|
||||
return makeResponse({ ctr, content: { code: 200, data: { token: token.token, webhookUrl: `${env.PP_BASE_URL}/webhook/${user.id}` } } });
|
||||
}
|
||||
|
||||
export async function regenerateWebhookSecret(ctr: any) {
|
||||
@@ -156,27 +206,13 @@ export async function regenerateWebhookSecret(ctr: any) {
|
||||
return makeResponse({ ctr, content: { code: 200, message: "Secret regenerated (no Gitea hooks to update)", data: { token: newSecret } } });
|
||||
}
|
||||
|
||||
const configs = await prisma.repoConfig.findMany({
|
||||
where: { userId: user.id, giteaWebhookId: { not: null } },
|
||||
});
|
||||
|
||||
const { updateWebhookSecret } = await import("../../services/gitea");
|
||||
const webhookUrl = `${env.PP_BASE_URL}/webhook/${user.id}`;
|
||||
const errors: string[] = [];
|
||||
|
||||
for (const config of configs) {
|
||||
try {
|
||||
await updateWebhookSecret(fullUser as any, config.repoOwner, config.repoName, config.giteaWebhookId!, webhookUrl, newSecret);
|
||||
} catch (e: any) {
|
||||
errors.push(`${config.repoOwner}/${config.repoName}: ${e.message}`);
|
||||
}
|
||||
}
|
||||
const hookSync = await syncRegisteredRepoWebhooks(user.id, fullUser, newSecret);
|
||||
|
||||
return makeResponse({
|
||||
ctr, content: {
|
||||
code: 200,
|
||||
message: errors.length ? `Secret regenerated with ${errors.length} hook update errors` : "Secret regenerated and all hooks updated",
|
||||
data: { token: newSecret, errors },
|
||||
message: hookSync.errors.length ? `Secret regenerated with ${hookSync.errors.length} hook update errors` : "Secret regenerated and all hooks updated",
|
||||
data: { token: newSecret, errors: hookSync.errors, hookSync },
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user