Secured mutations with an api-key. When in production mode it should return null if an API key is not provided or is incorrect.
All checks were successful
Main / build-and-push-docker-image (20.x) (push) Successful in 5m6s

This commit is contained in:
2025-12-10 16:42:21 -05:00
parent 678d1e7b5e
commit 30b4f65ec6
3 changed files with 156 additions and 78 deletions

View File

@@ -8,8 +8,6 @@ interface NextContext {
params: Promise<Record<string, string>>;
}
console.log(process.env);
const environment = process.env.NODE_ENV || "development";
const isValidApiKey = (apiKey: string): boolean => {

View File

@@ -1,6 +1,9 @@
import prisma from "@/lib/prismaClient";
import { BigIntResolver } from "graphql-scalars";
const envMutationKey = process.env.MUTATION_KEY || "";
const env = process.env.NODE_ENV || "development";
// Prisma
export const resolvers = {
// scalars
@@ -39,76 +42,114 @@ export const resolvers = {
})
},
Mutation: {
init: async () =>
// _parent: unknown,
// data: { newWeek: boolean; newMonth: boolean }
// _ctx: unknown
{
const date = new Date().toISOString();
let count = 0;
if ((await prisma.dailyStats.count()) === 0) {
await prisma.dailyStats.create({ data: { createdAt: date } });
count++;
}
if ((await prisma.totalStats.count()) === 0) {
await prisma.totalStats.create({ data: { createdAt: date } });
count++;
}
return `${count} tables have been initialized with data.`;
},
cronJob: async () =>
// _parent: unknown,
// data: { newWeek: boolean; newMonth: boolean }
// _ctx: unknown
{
const date = new Date().toISOString();
await prisma.dailyStats.create({ data: { createdAt: date } });
const allStats = await prisma.dailyStats.findMany({});
const calculatedStats = allStats.reduce(
(acc, curr) => {
const links = (acc.linksDeleted += curr.linksDeleted);
const commands = (acc.commandResponses += curr.commandResponses);
const triggers = (acc.timesTriggered += curr.timesTriggered);
return {
linksDeleted: links,
commandResponses: commands,
timesTriggered: triggers
};
},
{
linksDeleted: 0,
commandResponses: 0,
timesTriggered: 0
}
);
const totalStats = await prisma.totalStats.findFirst({
orderBy: {
createdAt: "desc"
}
});
return await prisma.totalStats.update({
where: {
createdAt: totalStats?.createdAt
},
data: {
...calculatedStats
}
});
},
addGroup: async (
init: async (
_parent: unknown,
data: { groupID: number; groupName: string; groupUsername: string }
data: { mutationKey?: string }
// _ctx: unknown
) => {
const { groupID, groupName, groupUsername } = data;
const { mutationKey } = data;
if (env !== "development") {
if (!mutationKey) {
return null;
}
if (mutationKey !== envMutationKey) {
return null;
}
}
const date = new Date().toISOString();
let count = 0;
if ((await prisma.dailyStats.count()) === 0) {
await prisma.dailyStats.create({ data: { createdAt: date } });
count++;
}
if ((await prisma.totalStats.count()) === 0) {
await prisma.totalStats.create({ data: { createdAt: date } });
count++;
}
return `${count} tables have been initialized with data.`;
},
cronJob: async (
_parent: unknown,
data: { mutationKey?: string }
// _ctx: unknown
) => {
const { mutationKey } = data;
if (env !== "development") {
if (!mutationKey) {
return null;
}
if (mutationKey !== envMutationKey) {
return null;
}
}
const date = new Date().toISOString();
await prisma.dailyStats.create({ data: { createdAt: date } });
const allStats = await prisma.dailyStats.findMany({});
const calculatedStats = allStats.reduce(
(acc, curr) => {
const links = (acc.linksDeleted += curr.linksDeleted);
const commands = (acc.commandResponses += curr.commandResponses);
const triggers = (acc.timesTriggered += curr.timesTriggered);
return {
linksDeleted: links,
commandResponses: commands,
timesTriggered: triggers
};
},
{
linksDeleted: 0,
commandResponses: 0,
timesTriggered: 0
}
);
const totalStats = await prisma.totalStats.findFirst({
orderBy: {
createdAt: "desc"
}
});
return await prisma.totalStats.update({
where: {
createdAt: totalStats?.createdAt
},
data: {
...calculatedStats
}
});
},
addGroup: async (
_parent: unknown,
data: {
groupID: number;
groupName: string;
groupUsername: string;
mutationKey?: string;
}
// _ctx: unknown
) => {
const { groupID, groupName, groupUsername, mutationKey } = data;
if (env !== "development") {
if (!mutationKey) {
return null;
}
if (mutationKey !== envMutationKey) {
return null;
}
}
const existingGroup = await prisma.groups.findFirst({
where: { telegramID: groupID }
@@ -139,10 +180,20 @@ export const resolvers = {
},
incrementGroup: async (
_parent: unknown,
data: { groupID: number; linksDeleted: number }
data: { groupID: number; linksDeleted: number; mutationKey?: string }
// _ctx: unknown
) => {
const { groupID, linksDeleted } = data;
const { groupID, linksDeleted, mutationKey } = data;
if (env !== "development") {
if (!mutationKey) {
return null;
}
if (mutationKey !== envMutationKey) {
return null;
}
}
return await prisma.groups.update({
where: { telegramID: groupID },
@@ -151,10 +202,25 @@ export const resolvers = {
},
increment: async (
_parent: unknown,
data: { link: boolean; command: boolean; trigger: boolean }
data: {
link: boolean;
command: boolean;
trigger: boolean;
mutationKey?: string;
}
// _ctx: unknown
) => {
const { link, command, trigger } = data;
const { link, command, trigger, mutationKey } = data;
if (env !== "development") {
if (!mutationKey) {
return null;
}
if (mutationKey !== envMutationKey) {
return null;
}
}
return await prisma.dailyStats
.findFirst({

View File

@@ -11,11 +11,25 @@ const typeDefs = /* GraphQL */ `
getTotalStats: TotalStats!
}
type Mutation {
init: String!
cronJob: TotalStats!
addGroup(groupID: BigInt, groupName: String, groupUsername: String): Groups!
incrementGroup(groupID: BigInt, linksDeleted: Int): Groups!
increment(link: Boolean, command: Boolean, trigger: Boolean): DailyStats!
init(mutationKey: String): String
cronJob(mutationKey: String): TotalStats
addGroup(
groupID: BigInt!
groupName: String!
groupUsername: String
mutationKey: String
): Groups
incrementGroup(
groupID: BigInt!
linksDeleted: Int!
mutationKey: String
): Groups
increment(
link: Boolean
command: Boolean
trigger: Boolean
mutationKey: String
): DailyStats
}
type Groups {