Enhance API with OIDC support, including login and callback endpoints. Update environment variables for OIDC configuration in .env.example. Add new features to the catalog service for listing software families, Minecraft versions, and deployment regions. Implement server management actions such as kill, delete, and update in the servers module. Integrate feature flags for maintenance mode in server operations. Update pnpm-lock.yaml with new dependencies and versions.
Some checks failed
CI / Node — lint, typecheck, test, build (push) Failing after 12s
CI / Go — node-agent tests (push) Failing after 9s
CI / Go — edge-gateway build (push) Successful in 17s

This commit is contained in:
TheOnlyMace
2026-07-05 18:39:53 +02:00
parent bf36cb3159
commit 50cd4b3ffd
225 changed files with 17824 additions and 436 deletions

View File

@@ -0,0 +1,17 @@
{
"name": "@hexahost/email-templates",
"version": "0.0.1",
"private": true,
"main": "./src/index.ts",
"types": "./src/index.ts",
"exports": {
".": "./src/index.ts"
},
"scripts": {
"typecheck": "tsc --noEmit",
"lint": "tsc --noEmit"
},
"devDependencies": {
"typescript": "^5.7.3"
}
}

View File

@@ -0,0 +1,102 @@
export type EmailLocale = 'de' | 'en';
export interface EmailTemplateInput {
appName: string;
locale?: EmailLocale;
}
export interface LinkEmailInput extends EmailTemplateInput {
url: string;
}
const copy = {
de: {
verifySubject: (app: string) => `E-Mail bestätigen ${app}`,
verifyHtml: (app: string, url: string) =>
`<p>Willkommen bei ${app}!</p><p><a href="${url}">E-Mail-Adresse bestätigen</a></p><p>Der Link ist 24 Stunden gültig.</p>`,
resetSubject: (app: string) => `Passwort zurücksetzen ${app}`,
resetHtml: (app: string, url: string) =>
`<p>Du hast ein Passwort-Reset für ${app} angefordert.</p><p><a href="${url}">Neues Passwort setzen</a></p><p>Falls du das nicht warst, ignoriere diese E-Mail.</p>`,
serverReadySubject: (app: string, name: string) => `Server bereit ${name} ${app}`,
serverReadyHtml: (app: string, name: string) =>
`<p>Dein Server <strong>${name}</strong> ist bereit.</p><p>Öffne das Panel in ${app}, um zu starten.</p>`,
backupSuccessSubject: (app: string, name: string) => `Backup erfolgreich ${name}`,
backupSuccessHtml: (app: string, name: string) =>
`<p>Das Backup für <strong>${name}</strong> wurde erfolgreich erstellt.</p>`,
backupFailedSubject: (app: string, name: string) => `Backup fehlgeschlagen ${name}`,
backupFailedHtml: (app: string, name: string) =>
`<p>Das Backup für <strong>${name}</strong> ist fehlgeschlagen. Bitte prüfe das Panel in ${app}.</p>`,
},
en: {
verifySubject: (app: string) => `Verify your email ${app}`,
verifyHtml: (app: string, url: string) =>
`<p>Welcome to ${app}!</p><p><a href="${url}">Verify your email address</a></p><p>This link expires in 24 hours.</p>`,
resetSubject: (app: string) => `Reset your password ${app}`,
resetHtml: (app: string, url: string) =>
`<p>You requested a password reset for ${app}.</p><p><a href="${url}">Set a new password</a></p><p>If you did not request this, ignore this email.</p>`,
serverReadySubject: (app: string, name: string) => `Server ready ${name} ${app}`,
serverReadyHtml: (app: string, name: string) =>
`<p>Your server <strong>${name}</strong> is ready.</p><p>Open the panel in ${app} to get started.</p>`,
backupSuccessSubject: (app: string, name: string) => `Backup successful ${name}`,
backupSuccessHtml: (app: string, name: string) =>
`<p>The backup for <strong>${name}</strong> completed successfully.</p>`,
backupFailedSubject: (app: string, name: string) => `Backup failed ${name}`,
backupFailedHtml: (app: string, name: string) =>
`<p>The backup for <strong>${name}</strong> failed. Please check the panel in ${app}.</p>`,
},
} as const;
function localeOf(input: EmailTemplateInput): EmailLocale {
return input.locale === 'de' ? 'de' : 'en';
}
export function renderVerifyEmail(input: LinkEmailInput): { subject: string; html: string } {
const locale = localeOf(input);
const t = copy[locale];
return {
subject: t.verifySubject(input.appName),
html: t.verifyHtml(input.appName, input.url),
};
}
export function renderResetEmail(input: LinkEmailInput): { subject: string; html: string } {
const locale = localeOf(input);
const t = copy[locale];
return {
subject: t.resetSubject(input.appName),
html: t.resetHtml(input.appName, input.url),
};
}
export function renderServerReadyEmail(
input: EmailTemplateInput & { serverName: string },
): { subject: string; html: string } {
const locale = localeOf(input);
const t = copy[locale];
return {
subject: t.serverReadySubject(input.appName, input.serverName),
html: t.serverReadyHtml(input.appName, input.serverName),
};
}
export function renderBackupSuccessEmail(
input: EmailTemplateInput & { serverName: string },
): { subject: string; html: string } {
const locale = localeOf(input);
const t = copy[locale];
return {
subject: t.backupSuccessSubject(input.appName, input.serverName),
html: t.backupSuccessHtml(input.appName, input.serverName),
};
}
export function renderBackupFailedEmail(
input: EmailTemplateInput & { serverName: string },
): { subject: string; html: string } {
const locale = localeOf(input);
const t = copy[locale];
return {
subject: t.backupFailedSubject(input.appName, input.serverName),
html: t.backupFailedHtml(input.appName, input.serverName),
};
}

View File

@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"]
}