| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- import { Injectable, NotFoundException, ForbiddenException, BadRequestException } from '@nestjs/common';
- import * as XLSX from 'xlsx';
- import { UserService } from '../user/user.service';
- import { TenantService } from '../tenant/tenant.service';
- @Injectable()
- export class AdminService {
- constructor(
- private readonly userService: UserService,
- private readonly tenantService: TenantService,
- ) { }
- async getTenantUsers(tenantId?: string, page?: number, limit?: number) {
- if (!tenantId) {
- return this.userService.findAll(page, limit);
- }
- return this.userService.findByTenantId(tenantId, page, limit);
- }
- async exportUsers(tenantId?: string): Promise<Buffer> {
- const { data: users } = tenantId
- ? await this.userService.findByTenantId(tenantId)
- : await this.userService.findAll();
-
- const worksheet = XLSX.utils.json_to_sheet(users.map(u => ({
- Username: u.username,
- DisplayName: u.displayName || '',
- IsAdmin: u.isAdmin ? 'Yes' : 'No',
- CreatedAt: u.createdAt,
- Password: '', // Placeholder for new users
- })));
- const workbook = XLSX.utils.book_new();
- XLSX.utils.book_append_sheet(workbook, worksheet, 'Users');
- return XLSX.write(workbook, { type: 'buffer', bookType: 'xlsx' });
- }
- async importUsers(tenantId?: string, file?: any) {
- if (!file) throw new BadRequestException('No file uploaded');
- const workbook = XLSX.read(file.buffer, { type: 'buffer' });
- const sheetName = workbook.SheetNames[0];
- const worksheet = workbook.Sheets[sheetName];
- const data = XLSX.utils.sheet_to_json(worksheet) as any[];
- const results = {
- success: 0,
- failed: 0,
- errors: [] as string[],
- };
- for (const row of data) {
- try {
- const username = (row.Username || row.username)?.toString();
- const displayName = (row.DisplayName || row.displayName || row.Name || row.name)?.toString();
- const password = (row.Password || row.password)?.toString();
- const isAdminStr = (row.IsAdmin || row.isAdmin || 'No').toString();
- const isAdmin = isAdminStr.toLowerCase() === 'yes' || isAdminStr === 'true' || isAdminStr === '1';
- if (!username) {
- throw new Error('Username is missing');
- }
- const existingUser = await this.userService.findOneByUsername(username);
- if (existingUser) {
- await this.userService.updateUser(existingUser.id, {
- displayName: displayName || existingUser.displayName,
- password: password || undefined,
- // We avoid changing isAdmin status via import for security unless explicitly required
- });
- } else {
- if (!password) {
- throw new Error(`Password missing for new user: ${username}`);
- }
- await this.userService.createUser(
- username,
- password,
- isAdmin,
- tenantId,
- displayName
- );
- }
- results.success++;
- } catch (e: any) {
- results.failed++;
- results.errors.push(`${row.Username || 'Unknown'}: ${e.message}`);
- }
- }
- return results;
- }
- async getTenantSettings(tenantId: string) {
- return this.tenantService.getSettings(tenantId);
- }
- async updateTenantSettings(tenantId: string, data: any) {
- return this.tenantService.updateSettings(tenantId, data);
- }
- // Notebook sharing approval and model assignments would go here
- async getPendingShares(tenantId: string) {
- // Mock implementation for pending shares to satisfy UI.
- // Needs proper schema/entity support in the future.
- return [];
- }
- }
|