This commit is contained in:
@@ -11,6 +11,7 @@ import { AdminRole } from './admin-role';
|
||||
import {
|
||||
CreateAdminSshKeyDto,
|
||||
CreateAdminDto,
|
||||
ListAdminsQuery,
|
||||
ResetAdminPasswordDto,
|
||||
UpdateAdminAppPermissionsDto,
|
||||
UpdateAdminRoleDto,
|
||||
@@ -43,9 +44,29 @@ export class AdminsService {
|
||||
});
|
||||
}
|
||||
|
||||
async list() {
|
||||
const admins = await this.prisma.admin.findMany({
|
||||
async list(query: ListAdminsQuery = {}) {
|
||||
const page = toPositiveInt(query.page, 1);
|
||||
const limit = Math.min(toPositiveInt(query.limit, 20), 100);
|
||||
const keyword = query.keyword?.trim();
|
||||
const where = {
|
||||
...(query.role ? { role: query.role as AdminRole } : {}),
|
||||
...(query.state === 'active' ? { isActive: true } : query.state === 'inactive' ? { isActive: false } : {}),
|
||||
...(keyword
|
||||
? {
|
||||
OR: [
|
||||
{ email: { contains: keyword, mode: 'insensitive' as const } },
|
||||
{ name: { contains: keyword, mode: 'insensitive' as const } },
|
||||
],
|
||||
}
|
||||
: {}),
|
||||
};
|
||||
|
||||
const [admins, total] = await this.prisma.$transaction([
|
||||
this.prisma.admin.findMany({
|
||||
where,
|
||||
orderBy: [{ role: 'asc' }, { createdAt: 'desc' }],
|
||||
skip: (page - 1) * limit,
|
||||
take: limit,
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
@@ -73,7 +94,9 @@ export class AdminsService {
|
||||
select: { appId: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
}),
|
||||
this.prisma.admin.count({ where }),
|
||||
]);
|
||||
|
||||
const users = await this.authPrisma.user.findMany({
|
||||
where: { email: { in: admins.map((admin) => admin.email) } },
|
||||
@@ -89,13 +112,19 @@ export class AdminsService {
|
||||
?? this.configService.get<string>('AUTH_EXTERNAL_URL')
|
||||
?? 'https://auth.autonomystudio.net';
|
||||
|
||||
return admins.map((admin) => {
|
||||
return {
|
||||
admins: admins.map((admin, index) => {
|
||||
const user = userByEmail.get(admin.email);
|
||||
return {
|
||||
...admin,
|
||||
no: total - ((page - 1) * limit + index),
|
||||
avatarUrl: getUserAvatarUrl(user?.id ?? '', user?.profileImageMime, authBaseUrl),
|
||||
};
|
||||
});
|
||||
}),
|
||||
total,
|
||||
page,
|
||||
limit,
|
||||
};
|
||||
}
|
||||
|
||||
async create(body: CreateAdminDto) {
|
||||
@@ -124,7 +153,12 @@ export class AdminsService {
|
||||
}
|
||||
|
||||
async updateStatus(id: string, body: UpdateAdminStatusDto) {
|
||||
await this.ensureExists(id);
|
||||
const existing = await this.ensureExists(id);
|
||||
|
||||
await this.giteaService.updateUserLoginDisabled(
|
||||
createGiteaUsername(existing.email),
|
||||
!body.isActive,
|
||||
);
|
||||
|
||||
const admin = await this.prisma.admin.update({
|
||||
where: { id },
|
||||
@@ -345,6 +379,12 @@ function hashPassword(password: string) {
|
||||
return `scrypt:${salt}:${hash}`;
|
||||
}
|
||||
|
||||
function toPositiveInt(value: string | number | undefined, fallback: number) {
|
||||
const parsed = Number(value);
|
||||
if (!Number.isFinite(parsed) || parsed < 1) return fallback;
|
||||
return Math.floor(parsed);
|
||||
}
|
||||
|
||||
function createGiteaUsername(email: string) {
|
||||
const account = email.split('@')[0] || email;
|
||||
const username = account
|
||||
|
||||
Reference in New Issue
Block a user