File size: 6,893 Bytes
e9d5b7d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179

"use server";

import { getDb } from "@/lib/mongodb";
import { getLoggedInUser } from "@/lib/actions/auth";
import type { PlatformApiKeyInput, UpdateUserCoinsAdminInput, UpdateUserRoleAdminInput } from "@/lib/schemas";
import type { User, Deployment } from "@/lib/types";
import { ObjectId } from "mongodb";
import { revalidatePath } from "next/cache";

const API_KEY_ID = "platformApiKey";

async function isAdmin(): Promise<boolean> {
  const user = await getLoggedInUser();
  return !!user && user.role === 'admin';
}

export async function getPlatformApiKey(): Promise<{ success: boolean; apiKey?: string; message?: string }> {
  // Removed isAdmin() check here. Reading the system's API key for operational purposes
  // (like a deployment) should not require the current actor to be an admin.
  // The SETTING of the key (updatePlatformApiKey) IS correctly admin-gated.
  try {
    const db = await getDb();
    const settingsCollection = db.collection("settings");
    const apiKeyDoc = await settingsCollection.findOne({ _id: API_KEY_ID });

    if (apiKeyDoc && apiKeyDoc.value && typeof apiKeyDoc.value === 'string' && apiKeyDoc.value.trim() !== "") {
      return { success: true, apiKey: apiKeyDoc.value };
    }
    // If keyDoc doesn't exist, or value is null/empty, treat as not configured.
    return { success: true, apiKey: "" }; // Return empty string to indicate not set or empty
  } catch (error) {
    console.error("Error fetching platform API key:", error);
    return { success: false, message: "Failed to fetch API key." };
  }
}

export async function updatePlatformApiKey(data: PlatformApiKeyInput): Promise<{ success: boolean; message: string }> {
  if (!(await isAdmin())) {
    return { success: false, message: "Unauthorized access." };
  }

  try {
    const db = await getDb();
    const settingsCollection = db.collection("settings");

    await settingsCollection.updateOne(
      { _id: API_KEY_ID },
      { $set: { value: data.apiKey } },
      { upsert: true }
    );
    revalidatePath("/admin/dashboard");
    return { success: true, message: "Platform API Key updated successfully." };
  } catch (error) {
    console.error("Error updating platform API key:", error);
    return { success: false, message: "Failed to update API key." };
  }
}

export async function getAllUsersForAdmin(): Promise<{ success: boolean; users?: User[]; message?: string }> {
  if (!(await isAdmin())) {
    return { success: false, message: "Unauthorized access." };
  }
  try {
    const db = await getDb();
    const usersArray = await db.collection<User>("users").find({}, { projection: { passwordHash: 0 } }).sort({createdAt: -1}).toArray();

    const users: User[] = usersArray.map(u => ({
        ...u,
        _id: u._id.toString(),
        lastCoinClaim: u.lastCoinClaim ? new Date(u.lastCoinClaim) : null,
        createdAt: u.createdAt ? new Date(u.createdAt) : new Date(0),
    }));
    return { success: true, users };
  } catch (error) {
    console.error("Error fetching all users:", error);
    return { success: false, message: "Failed to fetch users." };
  }
}

export async function updateUserRoleAdmin(data: UpdateUserRoleAdminInput): Promise<{ success: boolean; message: string }> {
    const adminUser = await getLoggedInUser();
    if (!adminUser || adminUser.role !== 'admin') {
        return { success: false, message: "Unauthorized access." };
    }

    if (adminUser._id === data.userId && data.newRole === 'user') {
         const dbCheck = await getDb();
         const adminCount = await dbCheck.collection<User>("users").countDocuments({ role: 'admin' });
         if (adminCount <= 1) {
            return { success: false, message: "Cannot change the role of the only admin." };
         }
    }

    try {
        const db = await getDb();
        const usersCollection = db.collection<User>("users");
        const result = await usersCollection.updateOne(
            { _id: data.userId },
            { $set: { role: data.newRole } }
        );

        if (result.modifiedCount === 0) {
            return { success: false, message: "User not found or role already set to this value." };
        }
        revalidatePath("/admin/dashboard");
        revalidatePath("/admin/stats");
        return { success: true, message: "User role updated successfully." };
    } catch (error) {
        console.error("Error updating user role:", error);
        return { success: false, message: "Failed to update user role." };
    }
}

export async function updateUserCoinsAdmin(data: UpdateUserCoinsAdminInput): Promise<{ success: boolean; message: string }> {
    if (!(await isAdmin())) {
        return { success: false, message: "Unauthorized access." };
    }
    try {
        const db = await getDb();
        const usersCollection = db.collection<User>("users");

        const result = await usersCollection.updateOne(
            { _id: data.userId },
            { $inc: { coins: data.coinAdjustment } }
        );

        if (result.modifiedCount === 0 && result.matchedCount === 0) {
             return { success: false, message: "User not found." };
        }
        revalidatePath("/admin/dashboard");
        revalidatePath("/admin/stats");
        return { success: true, message: `User coins adjusted by ${data.coinAdjustment}.` };
    } catch (error) {
        console.error("Error adjusting user coins:", error);
        return { success: false, message: "Failed to adjust user coins." };
    }
}


export async function deleteUserAdmin(userId: string): Promise<{ success: boolean; message: string }> {
   if (!(await isAdmin())) {
    return { success: false, message: "Unauthorized access." };
  }
  console.log(`Admin trying to delete user ${userId}`);
  return { success: false, message: "User deletion not yet implemented." };
}

export async function getPlatformStats(): Promise<{
  success: boolean;
  stats?: { totalUsers: number; totalDeployments: number; totalCoinsInSystem: number; };
  message?: string;
}> {
  if (!(await isAdmin())) {
    return { success: false, message: "Unauthorized access." };
  }
  try {
    const db = await getDb();
    const usersCollection = db.collection<User>("users");
    const deploymentsCollection = db.collection<Deployment>("deployments");

    const totalUsers = await usersCollection.countDocuments();
    const totalDeployments = await deploymentsCollection.countDocuments();

    const coinAggregation = await usersCollection.aggregate([
      { $group: { _id: null, totalCoins: { $sum: "$coins" } } }
    ]).toArray();
    const totalCoinsInSystem = coinAggregation[0]?.totalCoins || 0;

    return {
      success: true,
      stats: { totalUsers, totalDeployments, totalCoinsInSystem },
    };
  } catch (error) {
    console.error("Error fetching platform stats:", error);
    return { success: false, message: "Failed to fetch platform statistics." };
  }
}