KEYCLOAK AUTH FIX: Phase 4 - Email & Files Endpoints
**UPDATED ENDPOINTS (11 additional):** - email/send.ts (CRITICAL: was using old auth) - email/fetch-thread.ts (CRITICAL: was using old auth) - email/fetch-thread-v2.ts (CRITICAL: was using old auth) - email/generate-eoi-document.ts (CRITICAL: was using old auth) - files/upload.ts (CRITICAL: was using old auth) - files/list.ts (SECURITY ISSUE: had NO auth) - files/download.ts (SECURITY ISSUE: had NO auth) - files/delete.ts (SECURITY ISSUE: had NO auth) - files/create-folder.ts (SECURITY ISSUE: had NO auth) - files/preview.ts (SECURITY ISSUE: had NO auth) - files/rename.ts (SECURITY ISSUE: had NO auth) **AUTHENTICATION:** All now support dual auth: - x-tag header (webhooks/external calls) - Keycloak session (logged-in users) **PROGRESS:** 28/47 endpoints completed (~60%) **NEXT:** Continue with remaining proxy, test & debug endpoints **CRITICAL SECURITY FIXES:** Found 6 file endpoints with NO authentication - major vulnerability patched!
This commit is contained in:
parent
4abf74e750
commit
a17c6ed162
|
|
@ -1,3 +1,4 @@
|
|||
import { requireAuth } from '~/server/utils/auth';
|
||||
import { getCredentialsFromSession, decryptCredentials } from '~/server/utils/encryption';
|
||||
import { getCachedEmails, syncEmailsWithRetry, getSyncMetadata } from '~/server/utils/email-sync';
|
||||
|
||||
|
|
@ -23,11 +24,8 @@ interface EmailThread {
|
|||
}
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const xTagHeader = getRequestHeader(event, "x-tag");
|
||||
|
||||
if (!xTagHeader || (xTagHeader !== "094ut234" && xTagHeader !== "pjnvü1230")) {
|
||||
throw createError({ statusCode: 401, statusMessage: "unauthenticated" });
|
||||
}
|
||||
// Check authentication (x-tag header OR Keycloak session)
|
||||
await requireAuth(event);
|
||||
|
||||
try {
|
||||
const body = await readBody(event);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import Imap from 'imap';
|
||||
import { simpleParser } from 'mailparser';
|
||||
import { requireAuth } from '~/server/utils/auth';
|
||||
import { getCredentialsFromSession, decryptCredentials } from '~/server/utils/encryption';
|
||||
import { listFiles, getFileStats, getMinioClient, uploadFile } from '~/server/utils/minio';
|
||||
import { getIMAPPool } from '~/server/utils/imap-pool';
|
||||
|
|
@ -18,11 +19,8 @@ interface EmailMessage {
|
|||
}
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const xTagHeader = getRequestHeader(event, "x-tag");
|
||||
|
||||
if (!xTagHeader || (xTagHeader !== "094ut234" && xTagHeader !== "pjnvü1230")) {
|
||||
throw createError({ statusCode: 401, statusMessage: "unauthenticated" });
|
||||
}
|
||||
// Check authentication (x-tag header OR Keycloak session)
|
||||
await requireAuth(event);
|
||||
|
||||
try {
|
||||
const body = await readBody(event);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { requireAuth } from '~/server/utils/auth';
|
||||
import { getInterestById, updateInterest } from '~/server/utils/nocodb';
|
||||
|
||||
// Helper function to create embedded signing URLs
|
||||
|
|
@ -32,13 +33,9 @@ interface DocumensoResponse {
|
|||
export default defineEventHandler(async (event) => {
|
||||
console.log('[generate-eoi] ========== EOI GENERATION REQUEST RECEIVED ==========');
|
||||
|
||||
const xTagHeader = getRequestHeader(event, "x-tag");
|
||||
console.log('[generate-eoi] x-tag header:', xTagHeader);
|
||||
|
||||
if (!xTagHeader || (xTagHeader !== "094ut234" && xTagHeader !== "pjnvü1230")) {
|
||||
console.log('[generate-eoi] Authentication failed');
|
||||
throw createError({ statusCode: 401, statusMessage: "unauthenticated" });
|
||||
}
|
||||
// Check authentication (x-tag header OR Keycloak session)
|
||||
await requireAuth(event);
|
||||
console.log('[generate-eoi] Request authenticated');
|
||||
|
||||
try {
|
||||
const body = await readBody(event);
|
||||
|
|
@ -177,13 +174,17 @@ export default defineEventHandler(async (event) => {
|
|||
});
|
||||
}
|
||||
|
||||
// Get linked berths
|
||||
// Get linked berths - use the same auth as this request (either x-tag or session)
|
||||
const xTagHeader = getRequestHeader(event, "x-tag");
|
||||
const requestHeaders: Record<string, string> = {};
|
||||
if (xTagHeader) {
|
||||
requestHeaders["x-tag"] = xTagHeader;
|
||||
}
|
||||
|
||||
const berthsResponse = await $fetch<{ list: Array<{ 'Mooring Number': string }> }>(
|
||||
"/api/get-interest-berths",
|
||||
{
|
||||
headers: {
|
||||
"x-tag": xTagHeader,
|
||||
},
|
||||
headers: requestHeaders,
|
||||
params: {
|
||||
interestId: interestId,
|
||||
linkType: "berths",
|
||||
|
|
|
|||
|
|
@ -1,17 +1,14 @@
|
|||
import nodemailer from 'nodemailer';
|
||||
import { requireAuth } from '~/server/utils/auth';
|
||||
import { getCredentialsFromSession, decryptCredentials } from '~/server/utils/encryption';
|
||||
import { uploadFile, getMinioClient } from '~/server/utils/minio';
|
||||
import { updateInterest } from '~/server/utils/nocodb';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const xTagHeader = getRequestHeader(event, "x-tag");
|
||||
// Check authentication (x-tag header OR Keycloak session)
|
||||
await requireAuth(event);
|
||||
|
||||
console.log('[Email Send] Request received with x-tag:', xTagHeader);
|
||||
|
||||
if (!xTagHeader || (xTagHeader !== "094ut234" && xTagHeader !== "pjnvü1230")) {
|
||||
console.error('[Email Send] Authentication failed - invalid x-tag');
|
||||
throw createError({ statusCode: 401, statusMessage: "unauthenticated" });
|
||||
}
|
||||
console.log('[Email Send] Request authenticated');
|
||||
|
||||
try {
|
||||
const body = await readBody(event);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
import { requireAuth } from '~/server/utils/auth';
|
||||
import { createFolder } from '~/server/utils/minio';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
// Check authentication (x-tag header OR Keycloak session)
|
||||
await requireAuth(event);
|
||||
|
||||
try {
|
||||
const body = await readBody(event);
|
||||
const { folderPath } = body;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
import { requireAuth } from '~/server/utils/auth';
|
||||
import { deleteFile, deleteFolder, getMinioClient } from '~/server/utils/minio';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
// Check authentication (x-tag header OR Keycloak session)
|
||||
await requireAuth(event);
|
||||
|
||||
try {
|
||||
const body = await readBody(event);
|
||||
const { fileName, isFolder, bucket } = body;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
import { requireAuth } from '~/server/utils/auth';
|
||||
import { getDownloadUrl } from '~/server/utils/minio';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
// Check authentication (x-tag header OR Keycloak session)
|
||||
await requireAuth(event);
|
||||
|
||||
try {
|
||||
const query = getQuery(event);
|
||||
const fileName = query.fileName as string;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
import { requireAuth } from '~/server/utils/auth';
|
||||
import { listFiles } from '~/server/utils/minio';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
// Check authentication (x-tag header OR Keycloak session)
|
||||
await requireAuth(event);
|
||||
|
||||
try {
|
||||
const query = getQuery(event);
|
||||
const prefix = (query.prefix as string) || '';
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
import { requireAuth } from '~/server/utils/auth';
|
||||
import { getPreviewUrl } from '~/server/utils/minio';
|
||||
import mime from 'mime-types';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
// Check authentication (x-tag header OR Keycloak session)
|
||||
await requireAuth(event);
|
||||
|
||||
try {
|
||||
const query = getQuery(event);
|
||||
const fileName = query.fileName as string;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
import { requireAuth } from '~/server/utils/auth';
|
||||
import { renameFile, renameFolder } from '~/server/utils/minio';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
// Check authentication (x-tag header OR Keycloak session)
|
||||
await requireAuth(event);
|
||||
|
||||
try {
|
||||
const body = await readBody(event);
|
||||
const { oldName, newName, isFolder } = body;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
import { requireAuth } from '~/server/utils/auth';
|
||||
import { uploadFile, getMinioClient } from '~/server/utils/minio';
|
||||
import formidable from 'formidable';
|
||||
import { promises as fs } from 'fs';
|
||||
import mime from 'mime-types';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const xTagHeader = getRequestHeader(event, "x-tag");
|
||||
|
||||
if (!xTagHeader || (xTagHeader !== "094ut234" && xTagHeader !== "pjnvü1230")) {
|
||||
throw createError({ statusCode: 401, statusMessage: "unauthenticated" });
|
||||
}
|
||||
// Check authentication (x-tag header OR Keycloak session)
|
||||
await requireAuth(event);
|
||||
|
||||
try {
|
||||
// Get the current path and bucket from query params
|
||||
|
|
|
|||
Loading…
Reference in New Issue