VIBN Frontend for Coolify deployment
This commit is contained in:
84
app/api/keys/get/route.ts
Normal file
84
app/api/keys/get/route.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Internal API to get decrypted key value
|
||||
* This endpoint is used by Vibn internally, not exposed to frontend
|
||||
*/
|
||||
|
||||
import { NextResponse } from 'next/server';
|
||||
import { getAdminAuth, getAdminDb } from '@/lib/firebase/admin';
|
||||
import { FieldValue } from 'firebase-admin/firestore';
|
||||
import * as crypto from 'crypto';
|
||||
|
||||
const ENCRYPTION_KEY = process.env.ENCRYPTION_KEY || 'vibn-default-encryption-key-change-me!!';
|
||||
const ALGORITHM = 'aes-256-cbc';
|
||||
|
||||
function decrypt(encrypted: string, ivHex: string): string {
|
||||
const key = crypto.createHash('sha256').update(ENCRYPTION_KEY).digest();
|
||||
const iv = Buffer.from(ivHex, 'hex');
|
||||
const decipher = crypto.createDecipheriv(ALGORITHM, key, iv);
|
||||
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
|
||||
decrypted += decipher.final('utf8');
|
||||
return decrypted;
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const authHeader = request.headers.get('Authorization');
|
||||
if (!authHeader?.startsWith('Bearer ')) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
|
||||
const idToken = authHeader.split('Bearer ')[1];
|
||||
const adminAuth = getAdminAuth();
|
||||
const adminDb = getAdminDb();
|
||||
|
||||
let userId: string;
|
||||
try {
|
||||
const decodedToken = await adminAuth.verifyIdToken(idToken);
|
||||
userId = decodedToken.uid;
|
||||
} catch (error) {
|
||||
return NextResponse.json({ error: 'Invalid token' }, { status: 401 });
|
||||
}
|
||||
|
||||
const { service } = await request.json();
|
||||
|
||||
if (!service) {
|
||||
return NextResponse.json({ error: 'Service is required' }, { status: 400 });
|
||||
}
|
||||
|
||||
// Get the key
|
||||
const keysSnapshot = await adminDb
|
||||
.collection('userKeys')
|
||||
.where('userId', '==', userId)
|
||||
.where('service', '==', service)
|
||||
.limit(1)
|
||||
.get();
|
||||
|
||||
if (keysSnapshot.empty) {
|
||||
return NextResponse.json({ error: 'Key not found', hasKey: false }, { status: 404 });
|
||||
}
|
||||
|
||||
const keyDoc = keysSnapshot.docs[0];
|
||||
const keyData = keyDoc.data();
|
||||
|
||||
// Decrypt the key
|
||||
const decryptedKey = decrypt(keyData.encryptedKey, keyData.iv);
|
||||
|
||||
// Update last used timestamp
|
||||
await keyDoc.ref.update({
|
||||
lastUsed: FieldValue.serverTimestamp(),
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
hasKey: true,
|
||||
keyValue: decryptedKey,
|
||||
service: keyData.service,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error getting key:', error);
|
||||
return NextResponse.json(
|
||||
{ error: 'Failed to get key', details: error instanceof Error ? error.message : String(error) },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user