@hed-hog/core 0.0.319 → 0.0.322
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core.module.d.ts.map +1 -1
- package/dist/core.module.js +3 -0
- package/dist/core.module.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/mail-profile/dto/create.dto.d.ts +23 -0
- package/dist/mail-profile/dto/create.dto.d.ts.map +1 -0
- package/dist/mail-profile/dto/create.dto.js +139 -0
- package/dist/mail-profile/dto/create.dto.js.map +1 -0
- package/dist/mail-profile/dto/update.dto.d.ts +6 -0
- package/dist/mail-profile/dto/update.dto.d.ts.map +1 -0
- package/dist/mail-profile/dto/update.dto.js +9 -0
- package/dist/mail-profile/dto/update.dto.js.map +1 -0
- package/dist/mail-profile/mail-profile.controller.d.ts +94 -0
- package/dist/mail-profile/mail-profile.controller.d.ts.map +1 -0
- package/dist/mail-profile/mail-profile.controller.js +95 -0
- package/dist/mail-profile/mail-profile.controller.js.map +1 -0
- package/dist/mail-profile/mail-profile.module.d.ts +3 -0
- package/dist/mail-profile/mail-profile.module.d.ts.map +1 -0
- package/dist/mail-profile/mail-profile.module.js +31 -0
- package/dist/mail-profile/mail-profile.module.js.map +1 -0
- package/dist/mail-profile/mail-profile.service.d.ts +109 -0
- package/dist/mail-profile/mail-profile.service.d.ts.map +1 -0
- package/dist/mail-profile/mail-profile.service.js +278 -0
- package/dist/mail-profile/mail-profile.service.js.map +1 -0
- package/dist/menu/menu.controller.d.ts +3 -3
- package/dist/menu/menu.service.d.ts +3 -3
- package/dist/user/user.controller.d.ts +15 -0
- package/dist/user/user.controller.d.ts.map +1 -1
- package/dist/user/user.controller.js +22 -0
- package/dist/user/user.controller.js.map +1 -1
- package/dist/user/user.service.d.ts +15 -0
- package/dist/user/user.service.d.ts.map +1 -1
- package/dist/user/user.service.js +99 -0
- package/dist/user/user.service.js.map +1 -1
- package/hedhog/data/menu.yaml +35 -3
- package/hedhog/data/route.yaml +64 -0
- package/hedhog/frontend/app/mail/page.tsx.ejs +5 -0
- package/hedhog/frontend/app/mail/profiles/page.tsx.ejs +828 -0
- package/hedhog/frontend/app/users/page.tsx.ejs +25 -1383
- package/hedhog/frontend/app/users/permissions.tsx.ejs +109 -55
- package/hedhog/frontend/app/users/user-access-sheet.tsx.ejs +304 -0
- package/hedhog/frontend/app/users/user-sheet.tsx.ejs +1385 -0
- package/hedhog/frontend/messages/en.json +91 -0
- package/hedhog/frontend/messages/pt.json +91 -0
- package/hedhog/table/mail_profile.yaml +75 -0
- package/package.json +4 -4
- package/src/core.module.ts +3 -0
- package/src/index.ts +2 -0
- package/src/mail-profile/dto/create.dto.ts +145 -0
- package/src/mail-profile/dto/update.dto.ts +4 -0
- package/src/mail-profile/mail-profile.controller.ts +56 -0
- package/src/mail-profile/mail-profile.module.ts +18 -0
- package/src/mail-profile/mail-profile.service.ts +308 -0
- package/src/user/user.controller.ts +13 -0
- package/src/user/user.service.ts +98 -5
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
import { DeleteDTO } from '@hed-hog/api';
|
|
2
|
+
import { MailService as MailMainService } from '@hed-hog/api-mail';
|
|
3
|
+
import { PaginationDTO, PaginationService } from '@hed-hog/api-pagination';
|
|
4
|
+
import { PrismaService } from '@hed-hog/api-prisma';
|
|
5
|
+
import {
|
|
6
|
+
BadRequestException,
|
|
7
|
+
Inject,
|
|
8
|
+
Injectable,
|
|
9
|
+
NotFoundException,
|
|
10
|
+
forwardRef,
|
|
11
|
+
} from '@nestjs/common';
|
|
12
|
+
import { MailService } from '../mail/mail.service';
|
|
13
|
+
import { CreateDTO } from './dto/create.dto';
|
|
14
|
+
import { UpdateDTO } from './dto/update.dto';
|
|
15
|
+
|
|
16
|
+
@Injectable()
|
|
17
|
+
export class MailProfileService {
|
|
18
|
+
constructor(
|
|
19
|
+
@Inject(forwardRef(() => PrismaService))
|
|
20
|
+
private readonly prismaService: PrismaService,
|
|
21
|
+
@Inject(forwardRef(() => PaginationService))
|
|
22
|
+
private readonly paginationService: PaginationService,
|
|
23
|
+
@Inject(forwardRef(() => MailMainService))
|
|
24
|
+
private readonly mailMainService: MailMainService,
|
|
25
|
+
@Inject(forwardRef(() => MailService))
|
|
26
|
+
private readonly mailService: MailService,
|
|
27
|
+
) {}
|
|
28
|
+
|
|
29
|
+
async list(paginationParams: PaginationDTO) {
|
|
30
|
+
const fields = ['slug', 'name', 'provider', 'from_email', 'reply_to_email'];
|
|
31
|
+
const OR = this.prismaService.createInsensitiveSearch(fields, paginationParams);
|
|
32
|
+
|
|
33
|
+
return this.paginationService.paginate(
|
|
34
|
+
this.prismaService.mail_profile,
|
|
35
|
+
paginationParams,
|
|
36
|
+
{
|
|
37
|
+
where: OR.length > 0 ? { OR } : {},
|
|
38
|
+
select: {
|
|
39
|
+
id: true,
|
|
40
|
+
slug: true,
|
|
41
|
+
name: true,
|
|
42
|
+
provider: true,
|
|
43
|
+
from_name: true,
|
|
44
|
+
from_email: true,
|
|
45
|
+
reply_to_name: true,
|
|
46
|
+
reply_to_email: true,
|
|
47
|
+
created_at: true,
|
|
48
|
+
updated_at: true,
|
|
49
|
+
},
|
|
50
|
+
orderBy: [{ updated_at: 'desc' }, { id: 'desc' }],
|
|
51
|
+
},
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async get(id: number) {
|
|
56
|
+
const profile = await this.prismaService.mail_profile.findUnique({
|
|
57
|
+
where: { id },
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
if (!profile) {
|
|
61
|
+
throw new NotFoundException(`Mail profile with id ${id} not found.`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return profile;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async create(data: CreateDTO) {
|
|
68
|
+
await this.ensureSlugIsAvailable(data.slug);
|
|
69
|
+
this.validateProviderFields(data as unknown as Record<string, unknown>);
|
|
70
|
+
|
|
71
|
+
return this.prismaService.mail_profile.create({
|
|
72
|
+
data: this.normalizeData(data as unknown as Record<string, unknown>) as any,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async update({ id, data }: { id: number; data: UpdateDTO }) {
|
|
77
|
+
const existing = await this.prismaService.mail_profile.findUnique({
|
|
78
|
+
where: { id },
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
if (!existing) {
|
|
82
|
+
throw new NotFoundException(`Mail profile with id ${id} not found.`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (data.slug && data.slug !== existing.slug) {
|
|
86
|
+
await this.ensureSlugIsAvailable(data.slug);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const merged = {
|
|
90
|
+
...existing,
|
|
91
|
+
...data,
|
|
92
|
+
} satisfies Record<string, unknown>;
|
|
93
|
+
|
|
94
|
+
this.validateProviderFields(merged);
|
|
95
|
+
|
|
96
|
+
return this.prismaService.mail_profile.update({
|
|
97
|
+
where: { id },
|
|
98
|
+
data: this.normalizeData(merged) as any,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async delete({ ids }: DeleteDTO): Promise<{ count: number }> {
|
|
103
|
+
if (!ids?.length) {
|
|
104
|
+
throw new BadRequestException('You must select at least one item to delete.');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return this.prismaService.mail_profile.deleteMany({
|
|
108
|
+
where: {
|
|
109
|
+
id: {
|
|
110
|
+
in: ids,
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async test(data: CreateDTO) {
|
|
117
|
+
this.validateProviderFields(data as unknown as Record<string, unknown>);
|
|
118
|
+
|
|
119
|
+
const normalized = this.normalizeData(data as unknown as Record<string, unknown>);
|
|
120
|
+
const config = this.buildMailConfig(normalized);
|
|
121
|
+
const destinationEmail = normalized.from_email;
|
|
122
|
+
const sender = normalized.from_name
|
|
123
|
+
? `${normalized.from_name} <${normalized.from_email}>`
|
|
124
|
+
: normalized.from_email;
|
|
125
|
+
const replyTo = normalized.reply_to_email
|
|
126
|
+
? normalized.reply_to_name
|
|
127
|
+
? `${normalized.reply_to_name} <${normalized.reply_to_email}>`
|
|
128
|
+
: normalized.reply_to_email
|
|
129
|
+
: undefined;
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
this.mailMainService.setConfig(config);
|
|
133
|
+
|
|
134
|
+
await this.mailMainService.send({
|
|
135
|
+
to: destinationEmail,
|
|
136
|
+
from: sender,
|
|
137
|
+
replyTo,
|
|
138
|
+
subject: `[HedHog] Teste do perfil ${normalized.name}`,
|
|
139
|
+
body: `
|
|
140
|
+
<p>Este e-mail confirma que o perfil <strong>${normalized.name}</strong> foi validado com sucesso.</p>
|
|
141
|
+
<p><strong>Slug:</strong> ${normalized.slug}</p>
|
|
142
|
+
<p><strong>Provedor:</strong> ${normalized.provider}</p>
|
|
143
|
+
<p><strong>Remetente:</strong> ${sender}</p>
|
|
144
|
+
`,
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
success: true,
|
|
149
|
+
destination: destinationEmail,
|
|
150
|
+
};
|
|
151
|
+
} finally {
|
|
152
|
+
await this.mailService.reloadConfig().catch(() => undefined);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
private async ensureSlugIsAvailable(slug: string) {
|
|
157
|
+
const existing = await this.prismaService.mail_profile.findUnique({
|
|
158
|
+
where: { slug },
|
|
159
|
+
select: { id: true },
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
if (existing) {
|
|
163
|
+
throw new BadRequestException(`Mail profile with slug "${slug}" already exists.`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
private validateProviderFields(input: Record<string, unknown>) {
|
|
168
|
+
const provider = String(input.provider ?? '').toUpperCase();
|
|
169
|
+
|
|
170
|
+
if (!provider) {
|
|
171
|
+
throw new BadRequestException('Provider is required.');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (!String(input.from_email ?? '').trim()) {
|
|
175
|
+
throw new BadRequestException('Sender email is required.');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
switch (provider) {
|
|
179
|
+
case 'SMTP':
|
|
180
|
+
if (!String(input.smtp_host ?? '').trim()) {
|
|
181
|
+
throw new BadRequestException('SMTP host is required.');
|
|
182
|
+
}
|
|
183
|
+
if (!input.smtp_port) {
|
|
184
|
+
throw new BadRequestException('SMTP port is required.');
|
|
185
|
+
}
|
|
186
|
+
if (!String(input.smtp_username ?? '').trim()) {
|
|
187
|
+
throw new BadRequestException('SMTP username is required.');
|
|
188
|
+
}
|
|
189
|
+
if (!String(input.smtp_password ?? '').trim()) {
|
|
190
|
+
throw new BadRequestException('SMTP password is required.');
|
|
191
|
+
}
|
|
192
|
+
break;
|
|
193
|
+
case 'GMAIL':
|
|
194
|
+
if (!String(input.gmail_client_id ?? '').trim()) {
|
|
195
|
+
throw new BadRequestException('Gmail client ID is required.');
|
|
196
|
+
}
|
|
197
|
+
if (!String(input.gmail_client_secret ?? '').trim()) {
|
|
198
|
+
throw new BadRequestException('Gmail client secret is required.');
|
|
199
|
+
}
|
|
200
|
+
if (!String(input.gmail_refresh_token ?? '').trim()) {
|
|
201
|
+
throw new BadRequestException('Gmail refresh token is required.');
|
|
202
|
+
}
|
|
203
|
+
break;
|
|
204
|
+
case 'SES':
|
|
205
|
+
if (!String(input.ses_access_key_id ?? '').trim()) {
|
|
206
|
+
throw new BadRequestException('SES access key ID is required.');
|
|
207
|
+
}
|
|
208
|
+
if (!String(input.ses_secret_access_key ?? '').trim()) {
|
|
209
|
+
throw new BadRequestException('SES secret access key is required.');
|
|
210
|
+
}
|
|
211
|
+
if (!String(input.ses_region ?? '').trim()) {
|
|
212
|
+
throw new BadRequestException('SES region is required.');
|
|
213
|
+
}
|
|
214
|
+
break;
|
|
215
|
+
default:
|
|
216
|
+
throw new BadRequestException(`Invalid provider: ${provider}`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
private normalizeData(input: Record<string, unknown>) {
|
|
221
|
+
const provider = String(input.provider ?? '').toUpperCase();
|
|
222
|
+
|
|
223
|
+
return {
|
|
224
|
+
slug: this.normalizeString(input.slug),
|
|
225
|
+
name: this.normalizeString(input.name),
|
|
226
|
+
provider,
|
|
227
|
+
from_name: this.normalizeNullableString(input.from_name),
|
|
228
|
+
from_email: this.normalizeString(input.from_email),
|
|
229
|
+
reply_to_name: this.normalizeNullableString(input.reply_to_name),
|
|
230
|
+
reply_to_email: this.normalizeNullableString(input.reply_to_email),
|
|
231
|
+
smtp_host: provider === 'SMTP' ? this.normalizeNullableString(input.smtp_host) : null,
|
|
232
|
+
smtp_port:
|
|
233
|
+
provider === 'SMTP' && input.smtp_port !== undefined && input.smtp_port !== null
|
|
234
|
+
? Number(input.smtp_port)
|
|
235
|
+
: null,
|
|
236
|
+
smtp_secure: provider === 'SMTP' ? Boolean(input.smtp_secure) : false,
|
|
237
|
+
smtp_username:
|
|
238
|
+
provider === 'SMTP' ? this.normalizeNullableString(input.smtp_username) : null,
|
|
239
|
+
smtp_password:
|
|
240
|
+
provider === 'SMTP' ? this.normalizeNullableString(input.smtp_password) : null,
|
|
241
|
+
gmail_client_id:
|
|
242
|
+
provider === 'GMAIL' ? this.normalizeNullableString(input.gmail_client_id) : null,
|
|
243
|
+
gmail_client_secret:
|
|
244
|
+
provider === 'GMAIL'
|
|
245
|
+
? this.normalizeNullableString(input.gmail_client_secret)
|
|
246
|
+
: null,
|
|
247
|
+
gmail_refresh_token:
|
|
248
|
+
provider === 'GMAIL'
|
|
249
|
+
? this.normalizeNullableString(input.gmail_refresh_token)
|
|
250
|
+
: null,
|
|
251
|
+
ses_access_key_id:
|
|
252
|
+
provider === 'SES' ? this.normalizeNullableString(input.ses_access_key_id) : null,
|
|
253
|
+
ses_secret_access_key:
|
|
254
|
+
provider === 'SES'
|
|
255
|
+
? this.normalizeNullableString(input.ses_secret_access_key)
|
|
256
|
+
: null,
|
|
257
|
+
ses_region: provider === 'SES' ? this.normalizeNullableString(input.ses_region) : null,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
private buildMailConfig(input: ReturnType<MailProfileService['normalizeData']>) {
|
|
262
|
+
switch (input.provider) {
|
|
263
|
+
case 'SMTP':
|
|
264
|
+
return {
|
|
265
|
+
global: true,
|
|
266
|
+
type: 'SMTP' as const,
|
|
267
|
+
host: input.smtp_host ?? '',
|
|
268
|
+
port: input.smtp_port ?? 587,
|
|
269
|
+
secure: input.smtp_secure,
|
|
270
|
+
username: input.smtp_username ?? '',
|
|
271
|
+
password: input.smtp_password ?? '',
|
|
272
|
+
};
|
|
273
|
+
case 'GMAIL':
|
|
274
|
+
return {
|
|
275
|
+
global: true,
|
|
276
|
+
type: 'GMAIL' as const,
|
|
277
|
+
clientId: input.gmail_client_id ?? '',
|
|
278
|
+
clientSecret: input.gmail_client_secret ?? '',
|
|
279
|
+
refreshToken: input.gmail_refresh_token ?? '',
|
|
280
|
+
from: input.from_email,
|
|
281
|
+
};
|
|
282
|
+
case 'SES':
|
|
283
|
+
return {
|
|
284
|
+
global: true,
|
|
285
|
+
type: 'SES' as const,
|
|
286
|
+
region: input.ses_region ?? '',
|
|
287
|
+
accessKeyId: input.ses_access_key_id ?? '',
|
|
288
|
+
secretAccessKey: input.ses_secret_access_key ?? '',
|
|
289
|
+
from: input.from_email,
|
|
290
|
+
};
|
|
291
|
+
default:
|
|
292
|
+
throw new BadRequestException(`Invalid provider: ${input.provider}`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
private normalizeString(value: unknown) {
|
|
297
|
+
return String(value ?? '').trim();
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
private normalizeNullableString(value: unknown) {
|
|
301
|
+
if (value === undefined || value === null) {
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const normalized = String(value).trim();
|
|
306
|
+
return normalized.length > 0 ? normalized : null;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
@@ -113,6 +113,19 @@ export class UserController {
|
|
|
113
113
|
return this.userService.getUserRoles(userId);
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
+
@Get(':userId/menu')
|
|
117
|
+
async getUserMenus(
|
|
118
|
+
@Param('userId', ParseIntPipe) userId: number,
|
|
119
|
+
@Locale() locale: string,
|
|
120
|
+
) {
|
|
121
|
+
return this.userService.getUserMenus(locale, userId);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
@Get(':userId/route')
|
|
125
|
+
async getUserRoutes(@Param('userId', ParseIntPipe) userId: number, @Locale() locale: string) {
|
|
126
|
+
return this.userService.getUserRoutes(locale, userId);
|
|
127
|
+
}
|
|
128
|
+
|
|
116
129
|
@Post(':userId/role/:roleId')
|
|
117
130
|
async assignRoleToUser(
|
|
118
131
|
@Param('userId', ParseIntPipe) userId: number,
|
package/src/user/user.service.ts
CHANGED
|
@@ -2,11 +2,11 @@ import { getLocaleText } from '@hed-hog/api-locale';
|
|
|
2
2
|
import { PaginationService } from '@hed-hog/api-pagination';
|
|
3
3
|
import { PrismaService } from '@hed-hog/api-prisma';
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
BadRequestException,
|
|
6
|
+
Inject,
|
|
7
|
+
Injectable,
|
|
8
|
+
NotFoundException,
|
|
9
|
+
forwardRef,
|
|
10
10
|
} from '@nestjs/common';
|
|
11
11
|
import { ChallengeService } from '../challenge/challenge.service';
|
|
12
12
|
import { DeleteDTO } from '../dto/delete.dto';
|
|
@@ -372,6 +372,99 @@ export class UserService {
|
|
|
372
372
|
return this.mapRolesWithAssignment(allRoles, userRoles);
|
|
373
373
|
}
|
|
374
374
|
|
|
375
|
+
async getUserMenus(locale: string, userId: number) {
|
|
376
|
+
const roleUsers = await this.prismaService.role_user.findMany({
|
|
377
|
+
where: { user_id: userId },
|
|
378
|
+
select: { role_id: true },
|
|
379
|
+
});
|
|
380
|
+
const roleIds = roleUsers.map((ru) => ru.role_id);
|
|
381
|
+
|
|
382
|
+
const menus = await this.prismaService.menu.findMany({
|
|
383
|
+
where: {
|
|
384
|
+
role_menu: {
|
|
385
|
+
some: { role_id: { in: roleIds } },
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
include: {
|
|
389
|
+
menu_locale: {
|
|
390
|
+
where: { locale: { code: locale } },
|
|
391
|
+
select: { name: true },
|
|
392
|
+
},
|
|
393
|
+
role_menu: {
|
|
394
|
+
where: { role_id: { in: roleIds } },
|
|
395
|
+
include: {
|
|
396
|
+
role: {
|
|
397
|
+
select: {
|
|
398
|
+
slug: true,
|
|
399
|
+
role_locale: {
|
|
400
|
+
where: { locale: { code: locale } },
|
|
401
|
+
select: { name: true },
|
|
402
|
+
},
|
|
403
|
+
},
|
|
404
|
+
},
|
|
405
|
+
},
|
|
406
|
+
},
|
|
407
|
+
},
|
|
408
|
+
orderBy: { order: 'asc' },
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
return menus.map((menu) => ({
|
|
412
|
+
id: menu.id,
|
|
413
|
+
menuId: (menu as any).menu_id ?? null,
|
|
414
|
+
url: (menu as any).url,
|
|
415
|
+
icon: (menu as any).icon,
|
|
416
|
+
order: (menu as any).order,
|
|
417
|
+
name: (menu as any).menu_locale?.[0]?.name || (menu as any).url || '',
|
|
418
|
+
roles: ((menu as any).role_menu ?? []).map((rm: any) => ({
|
|
419
|
+
name: rm.role?.role_locale?.[0]?.name ?? rm.role?.slug ?? '',
|
|
420
|
+
slug: rm.role?.slug ?? '',
|
|
421
|
+
})),
|
|
422
|
+
}));
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
async getUserRoutes(locale: string, userId: number) {
|
|
426
|
+
const roleUsers = await this.prismaService.role_user.findMany({
|
|
427
|
+
where: { user_id: userId },
|
|
428
|
+
select: { role_id: true },
|
|
429
|
+
});
|
|
430
|
+
const roleIds = roleUsers.map((ru) => ru.role_id);
|
|
431
|
+
|
|
432
|
+
const routes = await this.prismaService.route.findMany({
|
|
433
|
+
where: {
|
|
434
|
+
role_route: {
|
|
435
|
+
some: { role_id: { in: roleIds } },
|
|
436
|
+
},
|
|
437
|
+
},
|
|
438
|
+
include: {
|
|
439
|
+
role_route: {
|
|
440
|
+
where: { role_id: { in: roleIds } },
|
|
441
|
+
include: {
|
|
442
|
+
role: {
|
|
443
|
+
select: {
|
|
444
|
+
slug: true,
|
|
445
|
+
role_locale: {
|
|
446
|
+
where: { locale: { code: locale } },
|
|
447
|
+
select: { name: true },
|
|
448
|
+
},
|
|
449
|
+
},
|
|
450
|
+
},
|
|
451
|
+
},
|
|
452
|
+
},
|
|
453
|
+
},
|
|
454
|
+
orderBy: [{ method: 'asc' }, { url: 'asc' }],
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
return routes.map((route) => ({
|
|
458
|
+
id: route.id,
|
|
459
|
+
url: route.url,
|
|
460
|
+
method: route.method,
|
|
461
|
+
roles: ((route as any).role_route ?? []).map((rr: any) => ({
|
|
462
|
+
name: rr.role?.role_locale?.[0]?.name ?? rr.role?.slug ?? '',
|
|
463
|
+
slug: rr.role?.slug ?? '',
|
|
464
|
+
})),
|
|
465
|
+
}));
|
|
466
|
+
}
|
|
467
|
+
|
|
375
468
|
async assignRoleToUser(locale: string, userId: number, roleId: number) {
|
|
376
469
|
await Promise.all([
|
|
377
470
|
this.validateUserExists(locale, userId),
|