fix(geplante-nachrichten): add /api prefix to all API paths, fix subscribe room token, unmask empty bot credentials, add Einzelnachrichten tab
This commit is contained in:
@@ -88,12 +88,12 @@ class ScheduledMessagesController {
|
||||
try {
|
||||
const { id } = req.params as Record<string, string>;
|
||||
const userId = req.user!.id;
|
||||
const { roomToken } = req.body;
|
||||
if (!roomToken) {
|
||||
res.status(400).json({ success: false, message: 'roomToken ist erforderlich' });
|
||||
const { room_token } = req.body as Record<string, string>;
|
||||
if (!room_token) {
|
||||
res.status(400).json({ success: false, message: 'room_token ist erforderlich' });
|
||||
return;
|
||||
}
|
||||
await scheduledMessagesService.subscribe(id, userId, roomToken);
|
||||
await scheduledMessagesService.subscribe(id, userId, room_token);
|
||||
res.json({ success: true });
|
||||
} catch (error) {
|
||||
logger.error('ScheduledMessagesController.subscribe error', { error, id: req.params.id });
|
||||
@@ -101,6 +101,25 @@ class ScheduledMessagesController {
|
||||
}
|
||||
}
|
||||
|
||||
async getMyBotRoom(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const userId = req.user!.id;
|
||||
const result = await scheduledMessagesService.getOrCreateBotRoom(userId);
|
||||
if (result === null) {
|
||||
res.status(400).json({ success: false, configured: false, message: 'Bot nicht konfiguriert' });
|
||||
return;
|
||||
}
|
||||
if (result === 'not_connected') {
|
||||
res.status(400).json({ success: false, connected: false, message: 'Nextcloud-Konto nicht verbunden' });
|
||||
return;
|
||||
}
|
||||
res.json({ success: true, data: { room_token: result } });
|
||||
} catch (error) {
|
||||
logger.error('ScheduledMessagesController.getMyBotRoom error', { error });
|
||||
res.status(500).json({ success: false, message: 'Bot-Raum konnte nicht ermittelt werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async unsubscribe(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const { id } = req.params as Record<string, string>;
|
||||
|
||||
@@ -20,7 +20,7 @@ function maskValue(value: string): string {
|
||||
function maskConfig(config: Record<string, string>): Record<string, string> {
|
||||
const result: Record<string, string> = {};
|
||||
for (const [k, v] of Object.entries(config)) {
|
||||
result[k] = MASKED_FIELDS.includes(k) ? maskValue(v) : v;
|
||||
result[k] = (MASKED_FIELDS.includes(k) && v) ? maskValue(v) : v;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { requirePermission } from '../middleware/rbac.middleware';
|
||||
|
||||
const router = Router();
|
||||
|
||||
// /rooms and /one-time MUST come before /:id to avoid being captured as an id param
|
||||
// /rooms, /my-bot-room and /one-time MUST come before /:id to avoid being captured as an id param
|
||||
router.get(
|
||||
'/rooms',
|
||||
authenticate,
|
||||
@@ -13,6 +13,13 @@ router.get(
|
||||
scheduledMessagesController.getRooms.bind(scheduledMessagesController),
|
||||
);
|
||||
|
||||
router.get(
|
||||
'/my-bot-room',
|
||||
authenticate,
|
||||
requirePermission('scheduled_messages:subscribe'),
|
||||
scheduledMessagesController.getMyBotRoom.bind(scheduledMessagesController),
|
||||
);
|
||||
|
||||
router.get(
|
||||
'/one-time',
|
||||
authenticate,
|
||||
|
||||
@@ -521,7 +521,37 @@ async function sendVehicleEvent(vehicleId: string): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
// ── One-Time Messages ─────────────────────────────────────────────────────────
|
||||
// ── Bot Room ──────────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Finds or creates a 1:1 Nextcloud Talk room between the bot and the given user.
|
||||
* Returns the room token, null if bot isn't configured, or 'not_connected' if the
|
||||
* user hasn't linked their Nextcloud account.
|
||||
*/
|
||||
async function getOrCreateBotRoom(userId: string): Promise<string | null | 'not_connected'> {
|
||||
const creds = await getBotCredentials();
|
||||
if (!creds) return null;
|
||||
|
||||
// Look up the user's Nextcloud login name
|
||||
const userResult = await pool.query(
|
||||
'SELECT nextcloud_login_name FROM users WHERE id = $1',
|
||||
[userId],
|
||||
);
|
||||
const nextcloudLoginName = userResult.rows[0]?.nextcloud_login_name as string | null;
|
||||
if (!nextcloudLoginName) return 'not_connected';
|
||||
|
||||
// Use createRoom(type=1) — Nextcloud returns existing 1:1 if it already exists
|
||||
const { token } = await nextcloudService.createRoom(
|
||||
1,
|
||||
nextcloudLoginName,
|
||||
undefined,
|
||||
creds.username,
|
||||
creds.appPassword,
|
||||
);
|
||||
return token;
|
||||
}
|
||||
|
||||
|
||||
|
||||
interface OneTimeMessage {
|
||||
id: string;
|
||||
@@ -598,6 +628,7 @@ const scheduledMessagesService = {
|
||||
getSubscriptionsForUser,
|
||||
buildAndSend,
|
||||
sendVehicleEvent,
|
||||
getOrCreateBotRoom,
|
||||
getOneTimeMessages,
|
||||
createOneTimeMessage,
|
||||
deleteOneTimeMessage,
|
||||
|
||||
Reference in New Issue
Block a user