KI-AGENT: Mailkonten deaktivierbar machen und Synczeit anzeigen
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 44s
Build and Push Docker Images / build-frontend (push) Successful in 1m15s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 21s
Build and Push Docker Images / build-central-services-admin (push) Successful in 21s
Build and Push Docker Images / build-docs (push) Successful in 22s
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 44s
Build and Push Docker Images / build-frontend (push) Successful in 1m15s
Build and Push Docker Images / build-website (push) Successful in 23s
Build and Push Docker Images / build-central-services-api (push) Successful in 21s
Build and Push Docker Images / build-central-services-admin (push) Successful in 21s
Build and Push Docker Images / build-docs (push) Successful in 22s
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
import nodemailer from "nodemailer"
|
||||
import { FastifyInstance } from "fastify"
|
||||
import { and, desc, eq } from "drizzle-orm"
|
||||
import { and, desc, eq, isNotNull } from "drizzle-orm"
|
||||
|
||||
import { encrypt, decrypt } from "../utils/crypt"
|
||||
import {
|
||||
customers,
|
||||
emailEntityLinks,
|
||||
emailMessages,
|
||||
emailSyncState,
|
||||
plants,
|
||||
projects,
|
||||
userCredentials,
|
||||
@@ -54,6 +55,7 @@ export default async function emailAsUserRoutes(server: FastifyInstance) {
|
||||
userId: row.userId,
|
||||
tenantId: row.tenantId,
|
||||
type: row.type,
|
||||
emailEnabled: row.emailEnabled !== false,
|
||||
email,
|
||||
displayName: email || `Mailkonto ${String(row.id).slice(0, 8)} muss repariert werden`,
|
||||
smtpHost,
|
||||
@@ -68,6 +70,24 @@ export default async function emailAsUserRoutes(server: FastifyInstance) {
|
||||
}
|
||||
}
|
||||
|
||||
const accountResponseWithStatus = async (row: any) => {
|
||||
const syncRows = await server.db
|
||||
.select({ lastSyncedAt: emailSyncState.lastSyncedAt })
|
||||
.from(emailSyncState)
|
||||
.where(and(
|
||||
eq(emailSyncState.accountId, row.id),
|
||||
eq(emailSyncState.tenantId, row.tenantId),
|
||||
isNotNull(emailSyncState.lastSyncedAt),
|
||||
))
|
||||
.orderBy(desc(emailSyncState.lastSyncedAt))
|
||||
.limit(1)
|
||||
|
||||
return {
|
||||
...accountResponse(row),
|
||||
lastSyncedAt: syncRows[0]?.lastSyncedAt || null,
|
||||
}
|
||||
}
|
||||
|
||||
const accountCredentials = (row: any) => {
|
||||
const account = accountResponse(row)
|
||||
if (!account.credentialsReadable) {
|
||||
@@ -148,13 +168,14 @@ export default async function emailAsUserRoutes(server: FastifyInstance) {
|
||||
reply.header("Access-Control-Expose-Headers", "Authorization, Content-Disposition, Content-Type, Content-Length")
|
||||
}
|
||||
|
||||
const accountWhere = (tenantId: number, userId: string, id?: string) => {
|
||||
const accountWhere = (tenantId: number, userId: string, id?: string, enabledOnly = false) => {
|
||||
const conditions = [
|
||||
eq(userCredentials.tenantId, tenantId),
|
||||
eq(userCredentials.userId, userId),
|
||||
eq(userCredentials.type, "mail"),
|
||||
]
|
||||
if (id) conditions.push(eq(userCredentials.id, id))
|
||||
if (enabledOnly) conditions.push(eq(userCredentials.emailEnabled, true))
|
||||
return and(...conditions)
|
||||
}
|
||||
|
||||
@@ -185,6 +206,7 @@ export default async function emailAsUserRoutes(server: FastifyInstance) {
|
||||
imap_host?: string
|
||||
imap_port?: number
|
||||
imap_ssl?: boolean
|
||||
emailEnabled?: boolean
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
@@ -208,6 +230,7 @@ export default async function emailAsUserRoutes(server: FastifyInstance) {
|
||||
imapHostEncrypted: bodyValue(body, "imapHost", "imap_host") ? encrypt(bodyValue(body, "imapHost", "imap_host")) : undefined,
|
||||
imapPort: bodyValue(body, "imapPort", "imap_port"),
|
||||
imapSsl: bodyValue(body, "imapSsl", "imap_ssl"),
|
||||
emailEnabled: typeof body.emailEnabled === "boolean" ? body.emailEnabled : undefined,
|
||||
updatedAt: new Date(),
|
||||
}
|
||||
|
||||
@@ -227,6 +250,7 @@ export default async function emailAsUserRoutes(server: FastifyInstance) {
|
||||
userId: req.user.user_id,
|
||||
tenantId: req.user.tenant_id,
|
||||
type: "mail",
|
||||
emailEnabled: body.emailEnabled !== false,
|
||||
|
||||
emailEncrypted: encrypt(body.email),
|
||||
passwordEncrypted: encrypt(body.password),
|
||||
@@ -262,6 +286,7 @@ export default async function emailAsUserRoutes(server: FastifyInstance) {
|
||||
}
|
||||
|
||||
const { id } = req.params as { id?: string }
|
||||
const query = (req.query || {}) as { includeDisabled?: string | boolean }
|
||||
|
||||
// ============================================================
|
||||
// LOAD SINGLE ACCOUNT
|
||||
@@ -276,7 +301,7 @@ export default async function emailAsUserRoutes(server: FastifyInstance) {
|
||||
const row = rows[0]
|
||||
if (!row) return reply.code(404).send({ error: "Not found" })
|
||||
|
||||
return reply.send(accountResponse(row))
|
||||
return reply.send(await accountResponseWithStatus(row))
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
@@ -285,9 +310,14 @@ export default async function emailAsUserRoutes(server: FastifyInstance) {
|
||||
const rows = await server.db
|
||||
.select()
|
||||
.from(userCredentials)
|
||||
.where(accountWhere(req.user.tenant_id, req.user.user_id))
|
||||
.where(accountWhere(
|
||||
req.user.tenant_id,
|
||||
req.user.user_id,
|
||||
undefined,
|
||||
query.includeDisabled !== "true" && query.includeDisabled !== true,
|
||||
))
|
||||
|
||||
return reply.send(rows.map(accountResponse))
|
||||
return reply.send(await Promise.all(rows.map(accountResponseWithStatus)))
|
||||
|
||||
} catch (err) {
|
||||
console.error("GET /email/accounts error:", err)
|
||||
@@ -319,7 +349,7 @@ export default async function emailAsUserRoutes(server: FastifyInstance) {
|
||||
const rows = await server.db
|
||||
.select()
|
||||
.from(userCredentials)
|
||||
.where(accountWhere(req.user.tenant_id, req.user.user_id, body.account))
|
||||
.where(accountWhere(req.user.tenant_id, req.user.user_id, body.account, true))
|
||||
.limit(1)
|
||||
|
||||
const row = rows[0]
|
||||
@@ -444,6 +474,17 @@ export default async function emailAsUserRoutes(server: FastifyInstance) {
|
||||
const { id } = req.params as { id: string }
|
||||
const body = (req.body || {}) as { mailbox?: string; limit?: number }
|
||||
|
||||
const accountRows = await server.db
|
||||
.select({ emailEnabled: userCredentials.emailEnabled })
|
||||
.from(userCredentials)
|
||||
.where(accountWhere(req.user.tenant_id, req.user.user_id, id))
|
||||
.limit(1)
|
||||
|
||||
if (!accountRows[0]) return reply.code(404).send({ error: "E-Mail-Konto nicht gefunden" })
|
||||
if (!accountRows[0].emailEnabled) {
|
||||
return reply.code(409).send({ error: "Das E-Mail-Konto ist deaktiviert" })
|
||||
}
|
||||
|
||||
const result = await emailSync.syncAccount(
|
||||
req.user.tenant_id,
|
||||
req.user.user_id,
|
||||
|
||||
Reference in New Issue
Block a user