KC@FlessingLabs 1.0.0: Testmodus ohne Lizenz, Installationsanleitung, Nutzungsbedingungen
Testmodus (ohne gültige Lizenz): 1 Personal-Konto, 2 Kunden; Discord-Bot, E-Mail-Posteingang (IMAP), DATEV-Export und Backups auf externe Ziele nur mit Lizenz. Mit Lizenz gelten deren Grenzen und Module (Lizenz ohne Modulliste = voller Umfang). Bestehende Daten bleiben bei Ablauf vollständig nutzbar, nur Neuanlagen über die Grenzen und die Zusatzfunktionen pausieren. - Edition zentral in @kc/platform/license (getEdition, hasFeature, assertCustomerCapacity, assertStaffCapacity), auch in der CLI durchgesetzt - Einstellungen → Lizenz zeigt die Edition, Hinweisbanner im Testmodus - README mit Installation, Update und Betrieb; systemd-Units unter ops/systemd - .env.example bereinigt (Kommentare nicht mehr hinter Werten, veraltete SMTP/Discord-Variablen entfernt; beides wird in der Oberfläche eingestellt) - LICENSE.md: Nutzungsbedingungen Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
fdd51b18e2
commit
17267b7c05
26 changed files with 368 additions and 73 deletions
|
|
@ -5,6 +5,7 @@ import { decrypt } from '@kc/platform/crypto';
|
|||
import { enqueue } from '@kc/platform/jobs';
|
||||
import { config } from '@kc/platform/config';
|
||||
import { audit } from '@kc/platform/audit';
|
||||
import { hasFeature } from '@kc/platform/license';
|
||||
|
||||
interface DiscordSettings {
|
||||
enabled: boolean; token: string | null; guildId: string | null; adminChannelId: string | null; ticketChannelId: string | null;
|
||||
|
|
@ -313,8 +314,8 @@ async function connect(s: DiscordSettings, log: (m: string) => void): Promise<vo
|
|||
/** Prüft, ob sich Token/Server/Aktivierung geändert haben, und verbindet bei Bedarf neu. Für periodischen Aufruf gedacht. */
|
||||
export async function syncDiscord(log: (m: string) => void): Promise<void> {
|
||||
const s = await loadSettings();
|
||||
cachedEnabled = s.enabled && !!s.token;
|
||||
const fp = `${s.enabled}|${s.token}|${s.guildId}`;
|
||||
cachedEnabled = s.enabled && !!s.token && (await hasFeature('discord')); // Discord-Bot nur mit Lizenz
|
||||
const fp = `${s.enabled}|${s.token}|${s.guildId}|${cachedEnabled}`; // Lizenzwechsel verbindet/trennt ebenfalls
|
||||
if (fp === lastFingerprint) return;
|
||||
lastFingerprint = fp;
|
||||
if (client) { await client.destroy().catch(() => undefined); client = null; }
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { simpleParser } from 'mailparser';
|
|||
import { pool } from '@kc/platform/db';
|
||||
import { decrypt } from '@kc/platform/crypto';
|
||||
import { enqueue } from '@kc/platform/jobs';
|
||||
import { hasFeature } from '@kc/platform/license';
|
||||
|
||||
/** Sehr einfache HTML->Text-Reduktion für Mails ohne Text-Teil. Nur zur Anzeige, nie als HTML gerendert. */
|
||||
function htmlToText(html: string): string {
|
||||
|
|
@ -27,6 +28,7 @@ export async function checkMailbox(log: (m: string) => void): Promise<void> {
|
|||
const [rows] = await pool.query('SELECT * FROM imap_settings WHERE id = 1') as any;
|
||||
const s = rows[0];
|
||||
if (!s?.enabled || !s?.host || !s?.username || !s?.secrets_enc) return;
|
||||
if (!(await hasFeature('imap'))) return; // E-Mail-Posteingang nur mit Lizenz
|
||||
const password = JSON.parse(decrypt(s.secrets_enc)).password as string;
|
||||
const client = new ImapFlow({ host: s.host, port: s.port, secure: s.secure_mode === 'tls', auth: { user: s.username, pass: password }, logger: false });
|
||||
try {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue