rl-core-api 0.18.10 → 0.19.1
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/auth/decorators/allowPendingPassword.decorator.d.ts +3 -0
- package/dist/core/auth/decorators/allowPendingPassword.decorator.js +7 -0
- package/dist/core/auth/guards/passwordPolicy.guard.d.ts +8 -0
- package/dist/core/auth/guards/passwordPolicy.guard.js +39 -0
- package/dist/core/config/env.schema.d.ts +2 -2
- package/dist/core/config/env.schema.js +33 -3
- package/dist/core/context/requestLog.context.d.ts +1 -0
- package/dist/core/context/requestLog.context.js +7 -1
- package/dist/core/database/migrations/1789603200000-AuthTokenClient.d.ts +6 -0
- package/dist/core/database/migrations/1789603200000-AuthTokenClient.js +16 -0
- package/dist/core/database/migrations/index.js +2 -0
- package/dist/core/export/export.controller.js +0 -2
- package/dist/core/filters/appErrorCode.enum.d.ts +2 -1
- package/dist/core/filters/appErrorCode.enum.js +1 -0
- package/dist/core/images/imageFetch.service.js +79 -15
- package/dist/core/images/images.controller.js +0 -2
- package/dist/core/images/images.service.d.ts +1 -0
- package/dist/core/images/images.service.js +13 -3
- package/dist/core/queue/queueAdmin.controller.js +0 -2
- package/dist/core/utils/codedError.util.d.ts +2 -1
- package/dist/core/utils/codedError.util.js +8 -0
- package/dist/features/audit/audit.module.js +5 -1
- package/dist/features/audit/domain/audit.service.d.ts +5 -2
- package/dist/features/audit/domain/audit.service.js +8 -4
- package/dist/features/audit/infra/repositories/requestLog.repository.d.ts +1 -1
- package/dist/features/audit/infra/repositories/requestLog.repository.js +11 -2
- package/dist/features/audit/presentation/audit.controller.d.ts +2 -1
- package/dist/features/audit/presentation/audit.controller.js +8 -7
- package/dist/features/audit/presentation/audit.interceptor.js +2 -2
- package/dist/features/auth/auth.module.js +4 -0
- package/dist/features/auth/domain/auth.service.d.ts +1 -2
- package/dist/features/auth/domain/auth.service.js +2 -2
- package/dist/features/auth/domain/enums/tokenClient.enum.d.ts +7 -0
- package/dist/features/auth/domain/enums/tokenClient.enum.js +13 -0
- package/dist/features/auth/domain/token.service.d.ts +1 -1
- package/dist/features/auth/domain/token.service.js +7 -1
- package/dist/features/auth/infra/schema/authToken.schema.d.ts +2 -0
- package/dist/features/auth/infra/schema/authToken.schema.js +4 -0
- package/dist/features/auth/presentation/auth.controller.d.ts +2 -2
- package/dist/features/auth/presentation/auth.controller.js +10 -7
- package/dist/features/auth/presentation/commands/password.command.d.ts +3 -0
- package/dist/features/auth/presentation/commands/password.command.js +9 -1
- package/dist/features/notifications/presentation/notifications.controller.js +0 -2
- package/dist/features/rbac/domain/rbac.catalog.js +5 -1
- package/dist/features/rbac/domain/rbac.service.d.ts +3 -1
- package/dist/features/rbac/domain/rbac.service.js +30 -2
- package/dist/features/rbac/presentation/rbac.controller.d.ts +1 -1
- package/dist/features/rbac/presentation/rbac.controller.js +4 -5
- package/dist/features/users/domain/users.service.d.ts +3 -1
- package/dist/features/users/domain/users.service.js +5 -1
- package/dist/features/users/presentation/users.controller.js +7 -17
- package/dist/index.d.ts +2 -0
- package/dist/index.js +8 -4
- package/package.json +1 -1
|
@@ -15,8 +15,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
exports.AuditController = void 0;
|
|
16
16
|
const common_1 = require("@nestjs/common");
|
|
17
17
|
const swagger_1 = require("@nestjs/swagger");
|
|
18
|
+
const currentUser_decorator_1 = require("../../../core/auth/decorators/currentUser.decorator");
|
|
18
19
|
const requirePermission_decorator_1 = require("../../../core/auth/decorators/requirePermission.decorator");
|
|
19
|
-
const
|
|
20
|
+
const permissionScope_util_1 = require("../../../core/auth/permissionScope.util");
|
|
20
21
|
const filterSchema_response_1 = require("../../../core/query/filterSchema.response");
|
|
21
22
|
const pagination_util_1 = require("../../../core/utils/pagination.util");
|
|
22
23
|
const audit_service_1 = require("../domain/audit.service");
|
|
@@ -27,8 +28,8 @@ let AuditController = class AuditController {
|
|
|
27
28
|
constructor(audit) {
|
|
28
29
|
this.audit = audit;
|
|
29
30
|
}
|
|
30
|
-
requests(query) {
|
|
31
|
-
return this.audit.listRequests(query);
|
|
31
|
+
requests(query, actor) {
|
|
32
|
+
return this.audit.listRequests(query, actor);
|
|
32
33
|
}
|
|
33
34
|
requestsFilterSchema() {
|
|
34
35
|
return (0, filterSchema_response_1.toFilterSchema)(audit_filters_1.REQUEST_LOGS_FILTER_CATALOG);
|
|
@@ -43,16 +44,17 @@ let AuditController = class AuditController {
|
|
|
43
44
|
exports.AuditController = AuditController;
|
|
44
45
|
__decorate([
|
|
45
46
|
(0, common_1.Get)("requests"),
|
|
46
|
-
(0, requirePermission_decorator_1.
|
|
47
|
+
(0, requirePermission_decorator_1.RequireAnyPermission)(...(0, permissionScope_util_1.anyOrTeam)("audit:read")),
|
|
47
48
|
(0, swagger_1.ApiOkResponse)({ type: log_response_1.PaginatedRequestLogsResponse }),
|
|
48
49
|
__param(0, (0, common_1.Query)()),
|
|
50
|
+
__param(1, (0, currentUser_decorator_1.CurrentUser)()),
|
|
49
51
|
__metadata("design:type", Function),
|
|
50
|
-
__metadata("design:paramtypes", [pagination_util_1.PaginationQuery]),
|
|
52
|
+
__metadata("design:paramtypes", [pagination_util_1.PaginationQuery, Object]),
|
|
51
53
|
__metadata("design:returntype", Promise)
|
|
52
54
|
], AuditController.prototype, "requests", null);
|
|
53
55
|
__decorate([
|
|
54
56
|
(0, common_1.Get)("requests/filter-schema"),
|
|
55
|
-
(0, requirePermission_decorator_1.
|
|
57
|
+
(0, requirePermission_decorator_1.RequireAnyPermission)(...(0, permissionScope_util_1.anyOrTeam)("audit:read")),
|
|
56
58
|
(0, swagger_1.ApiOkResponse)({ type: filterSchema_response_1.FilterFieldResponse, isArray: true }),
|
|
57
59
|
__metadata("design:type", Function),
|
|
58
60
|
__metadata("design:paramtypes", []),
|
|
@@ -78,7 +80,6 @@ __decorate([
|
|
|
78
80
|
exports.AuditController = AuditController = __decorate([
|
|
79
81
|
(0, swagger_1.ApiTags)("Audit"),
|
|
80
82
|
(0, swagger_1.ApiBearerAuth)(),
|
|
81
|
-
(0, common_1.UseGuards)(permissions_guard_1.PermissionsGuard),
|
|
82
83
|
(0, common_1.Controller)({ path: "audit", version: "1" }),
|
|
83
84
|
__metadata("design:paramtypes", [audit_service_1.AuditService])
|
|
84
85
|
], AuditController);
|
|
@@ -60,7 +60,7 @@ let AuditInterceptor = class AuditInterceptor {
|
|
|
60
60
|
outcome: requestOutcome_enum_1.RequestOutcome.SUCCESS,
|
|
61
61
|
action,
|
|
62
62
|
method,
|
|
63
|
-
path: req.path,
|
|
63
|
+
path: (0, requestLog_context_1.redactPath)(req.path),
|
|
64
64
|
route: (0, requestLog_context_1.routePathOf)(req),
|
|
65
65
|
statusCode: res.statusCode,
|
|
66
66
|
durationMs,
|
|
@@ -78,7 +78,7 @@ let AuditInterceptor = class AuditInterceptor {
|
|
|
78
78
|
outcome: requestOutcome_enum_1.RequestOutcome.ABORTED,
|
|
79
79
|
action,
|
|
80
80
|
method,
|
|
81
|
-
path: req.path,
|
|
81
|
+
path: (0, requestLog_context_1.redactPath)(req.path),
|
|
82
82
|
route: (0, requestLog_context_1.routePathOf)(req),
|
|
83
83
|
durationMs: Date.now() - start,
|
|
84
84
|
userId: logContext.userId,
|
|
@@ -12,6 +12,8 @@ const core_1 = require("@nestjs/core");
|
|
|
12
12
|
const jwt_1 = require("@nestjs/jwt");
|
|
13
13
|
const passport_1 = require("@nestjs/passport");
|
|
14
14
|
const jwtAuth_guard_1 = require("../../core/auth/guards/jwtAuth.guard");
|
|
15
|
+
const passwordPolicy_guard_1 = require("../../core/auth/guards/passwordPolicy.guard");
|
|
16
|
+
const permissions_guard_1 = require("../../core/auth/guards/permissions.guard");
|
|
15
17
|
const env_service_1 = require("../../core/config/env.service");
|
|
16
18
|
const wsAuth_service_1 = require("../../core/websocket/wsAuth.service");
|
|
17
19
|
const wsUserResolver_interface_1 = require("../../core/websocket/wsUserResolver.interface");
|
|
@@ -46,6 +48,8 @@ exports.AuthModule = AuthModule = __decorate([
|
|
|
46
48
|
domain_1.TwoFactorService,
|
|
47
49
|
presentation_1.JwtStrategy,
|
|
48
50
|
{ provide: core_1.APP_GUARD, useClass: jwtAuth_guard_1.JwtAuthGuard },
|
|
51
|
+
{ provide: core_1.APP_GUARD, useClass: permissions_guard_1.PermissionsGuard },
|
|
52
|
+
{ provide: core_1.APP_GUARD, useClass: passwordPolicy_guard_1.PasswordPolicyGuard },
|
|
49
53
|
domain_1.WsUserResolverService,
|
|
50
54
|
{ provide: wsUserResolver_interface_1.WS_USER_RESOLVER, useExisting: domain_1.WsUserResolverService },
|
|
51
55
|
wsAuth_service_1.WsAuthService,
|
|
@@ -4,7 +4,6 @@ import { EnvService } from "../../../core/config/env.service";
|
|
|
4
4
|
import { MailerService } from "../../../core/mailer/mailer.service";
|
|
5
5
|
import { PasswordTokenPurpose, PasswordTokenStatus, TokenService } from "./token.service";
|
|
6
6
|
import { TotpSetup, TwoFactorService } from "./twoFactor.service";
|
|
7
|
-
import { ClientType } from "../presentation/commands/clientType.enum";
|
|
8
7
|
import { LoginCommand } from "../presentation/commands/login.command";
|
|
9
8
|
import { VerifyTwoFactorCommand } from "../presentation/commands/twoFactor.command";
|
|
10
9
|
import { RbacService } from "../../rbac/domain/rbac.service";
|
|
@@ -67,7 +66,7 @@ export declare class AuthService {
|
|
|
67
66
|
}>;
|
|
68
67
|
verifyTwoFactor(dto: VerifyTwoFactorCommand, ctx: RequestCtx): Promise<VerifiedSession>;
|
|
69
68
|
regenerateBackupCodes(userId: string, code: string): Promise<string[]>;
|
|
70
|
-
refresh(rawToken: string | undefined, ctx: RequestCtx
|
|
69
|
+
refresh(rawToken: string | undefined, ctx: RequestCtx): Promise<RefreshedTokens>;
|
|
71
70
|
loginWithDevice(rawToken: string | undefined, ctx: RequestCtx): Promise<DeviceSession>;
|
|
72
71
|
listTrustedDevices(userId: string): Promise<TrustedDevice[]>;
|
|
73
72
|
forgetTrustedDevice(userId: string, family: string): Promise<void>;
|
|
@@ -178,11 +178,11 @@ let AuthService = class AuthService {
|
|
|
178
178
|
await this.users.save(user);
|
|
179
179
|
return generated.plain;
|
|
180
180
|
}
|
|
181
|
-
async refresh(rawToken, ctx
|
|
181
|
+
async refresh(rawToken, ctx) {
|
|
182
182
|
if (!rawToken) {
|
|
183
183
|
throw new common_1.UnauthorizedException("Refresh token ausente");
|
|
184
184
|
}
|
|
185
|
-
const { userId, rawToken: newRefresh } = await this.tokens.rotateRefreshToken(rawToken, ctx
|
|
185
|
+
const { userId, rawToken: newRefresh } = await this.tokens.rotateRefreshToken(rawToken, ctx);
|
|
186
186
|
const user = await this.users.findById(userId);
|
|
187
187
|
if (!user.isActive) {
|
|
188
188
|
throw accountInactive();
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ClientType } from "../../presentation/commands/clientType.enum";
|
|
2
|
+
export declare enum TokenClient {
|
|
3
|
+
WEB = 0,
|
|
4
|
+
MOBILE = 1
|
|
5
|
+
}
|
|
6
|
+
export declare const toTokenClient: (client: ClientType) => TokenClient;
|
|
7
|
+
export declare const toClientType: (client: TokenClient) => ClientType;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toClientType = exports.toTokenClient = exports.TokenClient = void 0;
|
|
4
|
+
const clientType_enum_1 = require("../../presentation/commands/clientType.enum");
|
|
5
|
+
var TokenClient;
|
|
6
|
+
(function (TokenClient) {
|
|
7
|
+
TokenClient[TokenClient["WEB"] = 0] = "WEB";
|
|
8
|
+
TokenClient[TokenClient["MOBILE"] = 1] = "MOBILE";
|
|
9
|
+
})(TokenClient || (exports.TokenClient = TokenClient = {}));
|
|
10
|
+
const toTokenClient = (client) => client === clientType_enum_1.ClientType.MOBILE ? TokenClient.MOBILE : TokenClient.WEB;
|
|
11
|
+
exports.toTokenClient = toTokenClient;
|
|
12
|
+
const toClientType = (client) => client === TokenClient.MOBILE ? clientType_enum_1.ClientType.MOBILE : clientType_enum_1.ClientType.WEB;
|
|
13
|
+
exports.toClientType = toClientType;
|
|
@@ -41,7 +41,7 @@ export declare class TokenService {
|
|
|
41
41
|
rotateRefreshToken(rawToken: string, ctx?: {
|
|
42
42
|
ipAddress?: string;
|
|
43
43
|
userAgent?: string;
|
|
44
|
-
}
|
|
44
|
+
}): Promise<RotationResult>;
|
|
45
45
|
issueDeviceToken(userId: string, ctx?: {
|
|
46
46
|
ipAddress?: string;
|
|
47
47
|
userAgent?: string;
|
|
@@ -16,6 +16,7 @@ const typeorm_1 = require("typeorm");
|
|
|
16
16
|
const uuid_1 = require("uuid");
|
|
17
17
|
const env_service_1 = require("../../../core/config/env.service");
|
|
18
18
|
const hash_util_1 = require("../../../core/utils/hash.util");
|
|
19
|
+
const tokenClient_enum_1 = require("./enums/tokenClient.enum");
|
|
19
20
|
const authToken_repository_1 = require("../infra/repositories/authToken.repository");
|
|
20
21
|
const authToken_schema_1 = require("../infra/schema/authToken.schema");
|
|
21
22
|
const clientType_enum_1 = require("../presentation/commands/clientType.enum");
|
|
@@ -42,6 +43,7 @@ let TokenService = TokenService_1 = class TokenService {
|
|
|
42
43
|
tokenHash: (0, hash_util_1.sha256)(params.rawToken),
|
|
43
44
|
type: params.type,
|
|
44
45
|
family: params.family ?? null,
|
|
46
|
+
client: params.client ? (0, tokenClient_enum_1.toTokenClient)(params.client) : null,
|
|
45
47
|
expiresAt: params.expiresAt,
|
|
46
48
|
ipAddress: params.ipAddress,
|
|
47
49
|
userAgent: params.userAgent,
|
|
@@ -63,13 +65,14 @@ let TokenService = TokenService_1 = class TokenService {
|
|
|
63
65
|
rawToken,
|
|
64
66
|
type: authToken_schema_1.TokenType.REFRESH_TOKEN,
|
|
65
67
|
family: fam,
|
|
68
|
+
client,
|
|
66
69
|
expiresAt: this.minutesFromNow(this.refreshMinutes(client)),
|
|
67
70
|
ipAddress: ctx?.ipAddress,
|
|
68
71
|
userAgent: ctx?.userAgent,
|
|
69
72
|
});
|
|
70
73
|
return { rawToken, family: fam };
|
|
71
74
|
}
|
|
72
|
-
async rotateRefreshToken(rawToken, ctx
|
|
75
|
+
async rotateRefreshToken(rawToken, ctx) {
|
|
73
76
|
const tokenHash = (0, hash_util_1.sha256)(rawToken);
|
|
74
77
|
const stored = await this.repo.findOne({
|
|
75
78
|
where: { tokenHash, type: authToken_schema_1.TokenType.REFRESH_TOKEN },
|
|
@@ -89,6 +92,9 @@ let TokenService = TokenService_1 = class TokenService {
|
|
|
89
92
|
}
|
|
90
93
|
stored.used = true;
|
|
91
94
|
await this.repo.save(stored);
|
|
95
|
+
const client = stored.client === null || stored.client === undefined
|
|
96
|
+
? clientType_enum_1.ClientType.WEB
|
|
97
|
+
: (0, tokenClient_enum_1.toClientType)(stored.client);
|
|
92
98
|
const { rawToken: newRaw, family } = await this.issueRefreshToken(stored.userId, stored.family ?? undefined, ctx, client);
|
|
93
99
|
return { userId: stored.userId, rawToken: newRaw, family };
|
|
94
100
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BaseEntity } from "../../../../core/database/base.schema";
|
|
2
|
+
import { TokenClient } from "../../domain/enums/tokenClient.enum";
|
|
2
3
|
export declare enum TokenType {
|
|
3
4
|
PASSWORD_RESET = 0,
|
|
4
5
|
FIRST_ACCESS = 1,
|
|
@@ -12,6 +13,7 @@ export declare class AuthToken extends BaseEntity {
|
|
|
12
13
|
tokenHash: string;
|
|
13
14
|
type: TokenType;
|
|
14
15
|
family?: string | null;
|
|
16
|
+
client?: TokenClient | null;
|
|
15
17
|
expiresAt: Date;
|
|
16
18
|
used: boolean;
|
|
17
19
|
revoked: boolean;
|
|
@@ -46,6 +46,10 @@ __decorate([
|
|
|
46
46
|
(0, typeorm_1.Column)({ name: "family", type: "char", length: 36, nullable: true }),
|
|
47
47
|
__metadata("design:type", Object)
|
|
48
48
|
], AuthToken.prototype, "family", void 0);
|
|
49
|
+
__decorate([
|
|
50
|
+
(0, typeorm_1.Column)({ type: "tinyint", unsigned: true, nullable: true }),
|
|
51
|
+
__metadata("design:type", Object)
|
|
52
|
+
], AuthToken.prototype, "client", void 0);
|
|
49
53
|
__decorate([
|
|
50
54
|
(0, typeorm_1.Column)({ name: "expires_at", type: "datetime" }),
|
|
51
55
|
__metadata("design:type", Date)
|
|
@@ -9,7 +9,7 @@ import { DeviceSession, TrustedDevice } from "../domain/auth.service";
|
|
|
9
9
|
import { TotpSetup } from "../domain/twoFactor.service";
|
|
10
10
|
import { DeviceLoginCommand } from "./commands/deviceLogin.command";
|
|
11
11
|
import { LoginCommand } from "./commands/login.command";
|
|
12
|
-
import { ForgotPasswordCommand, ResetPasswordCommand } from "./commands/password.command";
|
|
12
|
+
import { ForgotPasswordCommand, InspectPasswordTokenCommand, ResetPasswordCommand } from "./commands/password.command";
|
|
13
13
|
import { LogoutCommand, RefreshTokenCommand } from "./commands/refreshToken.command";
|
|
14
14
|
import { PendingTokenCommand, RegenerateBackupCommand, VerifyTwoFactorCommand } from "./commands/twoFactor.command";
|
|
15
15
|
export interface VerifyResponse {
|
|
@@ -54,7 +54,7 @@ export declare class AuthController {
|
|
|
54
54
|
forgotPassword(dto: ForgotPasswordCommand): Promise<{
|
|
55
55
|
ok: boolean;
|
|
56
56
|
}>;
|
|
57
|
-
inspectPasswordToken(
|
|
57
|
+
inspectPasswordToken(dto: InspectPasswordTokenCommand): Promise<PasswordTokenCheck>;
|
|
58
58
|
resetPassword(dto: ResetPasswordCommand): Promise<{
|
|
59
59
|
ok: boolean;
|
|
60
60
|
}>;
|
|
@@ -17,6 +17,7 @@ const common_1 = require("@nestjs/common");
|
|
|
17
17
|
const swagger_1 = require("@nestjs/swagger");
|
|
18
18
|
const throttler_1 = require("@nestjs/throttler");
|
|
19
19
|
const cookie_util_1 = require("../../../core/auth/cookie.util");
|
|
20
|
+
const allowPendingPassword_decorator_1 = require("../../../core/auth/decorators/allowPendingPassword.decorator");
|
|
20
21
|
const currentUser_decorator_1 = require("../../../core/auth/decorators/currentUser.decorator");
|
|
21
22
|
const public_decorator_1 = require("../../../core/auth/decorators/public.decorator");
|
|
22
23
|
const jwtAuth_guard_1 = require("../../../core/auth/guards/jwtAuth.guard");
|
|
@@ -64,8 +65,7 @@ let AuthController = class AuthController {
|
|
|
64
65
|
async refresh(dto, req, res) {
|
|
65
66
|
const cookies = req.cookies;
|
|
66
67
|
const raw = dto.refreshToken ?? cookies?.[cookie_util_1.REFRESH_COOKIE];
|
|
67
|
-
const
|
|
68
|
-
const tokens = await this.auth.refresh(raw, ctxFrom(req), client);
|
|
68
|
+
const tokens = await this.auth.refresh(raw, ctxFrom(req));
|
|
69
69
|
if (dto.refreshToken) {
|
|
70
70
|
return { ok: true, ...tokens };
|
|
71
71
|
}
|
|
@@ -104,8 +104,8 @@ let AuthController = class AuthController {
|
|
|
104
104
|
await this.auth.forgotPassword(dto.email);
|
|
105
105
|
return { ok: true };
|
|
106
106
|
}
|
|
107
|
-
inspectPasswordToken(
|
|
108
|
-
return this.auth.inspectPasswordToken(token);
|
|
107
|
+
inspectPasswordToken(dto) {
|
|
108
|
+
return this.auth.inspectPasswordToken(dto.token);
|
|
109
109
|
}
|
|
110
110
|
async resetPassword(dto) {
|
|
111
111
|
await this.auth.resetPassword(dto.token, dto.newPassword);
|
|
@@ -231,6 +231,7 @@ __decorate([
|
|
|
231
231
|
__decorate([
|
|
232
232
|
(0, common_1.UseGuards)(jwtAuth_guard_1.JwtAuthGuard),
|
|
233
233
|
(0, swagger_1.ApiBearerAuth)(),
|
|
234
|
+
(0, allowPendingPassword_decorator_1.AllowPendingPassword)(),
|
|
234
235
|
(0, common_1.Get)("profile"),
|
|
235
236
|
(0, swagger_1.ApiOperation)({ summary: "Dados do usuário autenticado + permissões" }),
|
|
236
237
|
(0, swagger_1.ApiOkResponse)({ type: sessionUser_response_1.SessionUserResponse }),
|
|
@@ -242,6 +243,7 @@ __decorate([
|
|
|
242
243
|
__decorate([
|
|
243
244
|
(0, common_1.UseGuards)(jwtAuth_guard_1.JwtAuthGuard),
|
|
244
245
|
(0, swagger_1.ApiBearerAuth)(),
|
|
246
|
+
(0, allowPendingPassword_decorator_1.AllowPendingPassword)(),
|
|
245
247
|
(0, common_1.Get)("my-permissions"),
|
|
246
248
|
(0, swagger_1.ApiOperation)({
|
|
247
249
|
summary: "Lista os códigos de permissão e papéis do usuário",
|
|
@@ -280,13 +282,14 @@ __decorate([
|
|
|
280
282
|
__decorate([
|
|
281
283
|
(0, public_decorator_1.Public)(),
|
|
282
284
|
(0, throttler_1.Throttle)({ default: { limit: 20, ttl: 60_000 } }),
|
|
283
|
-
(0, common_1.
|
|
285
|
+
(0, common_1.Post)("password-token/inspect"),
|
|
286
|
+
(0, common_1.HttpCode)(200),
|
|
284
287
|
(0, swagger_1.ApiOperation)({
|
|
285
288
|
summary: "Verifica a validade do link de senha sem consumi-lo",
|
|
286
289
|
}),
|
|
287
|
-
__param(0, (0, common_1.
|
|
290
|
+
__param(0, (0, common_1.Body)()),
|
|
288
291
|
__metadata("design:type", Function),
|
|
289
|
-
__metadata("design:paramtypes", [
|
|
292
|
+
__metadata("design:paramtypes", [password_command_1.InspectPasswordTokenCommand]),
|
|
290
293
|
__metadata("design:returntype", Promise)
|
|
291
294
|
], AuthController.prototype, "inspectPasswordToken", null);
|
|
292
295
|
__decorate([
|
|
@@ -9,7 +9,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.ResetPasswordCommand = exports.ForgotPasswordCommand = void 0;
|
|
12
|
+
exports.ResetPasswordCommand = exports.InspectPasswordTokenCommand = exports.ForgotPasswordCommand = void 0;
|
|
13
13
|
const swagger_1 = require("@nestjs/swagger");
|
|
14
14
|
const class_validator_1 = require("class-validator");
|
|
15
15
|
const password_constants_1 = require("../../../../core/utils/password.constants");
|
|
@@ -21,6 +21,14 @@ __decorate([
|
|
|
21
21
|
(0, class_validator_1.IsEmail)(),
|
|
22
22
|
__metadata("design:type", String)
|
|
23
23
|
], ForgotPasswordCommand.prototype, "email", void 0);
|
|
24
|
+
class InspectPasswordTokenCommand {
|
|
25
|
+
}
|
|
26
|
+
exports.InspectPasswordTokenCommand = InspectPasswordTokenCommand;
|
|
27
|
+
__decorate([
|
|
28
|
+
(0, swagger_1.ApiProperty)(),
|
|
29
|
+
(0, class_validator_1.IsString)(),
|
|
30
|
+
__metadata("design:type", String)
|
|
31
|
+
], InspectPasswordTokenCommand.prototype, "token", void 0);
|
|
24
32
|
class ResetPasswordCommand {
|
|
25
33
|
}
|
|
26
34
|
exports.ResetPasswordCommand = ResetPasswordCommand;
|
|
@@ -17,7 +17,6 @@ const common_1 = require("@nestjs/common");
|
|
|
17
17
|
const swagger_1 = require("@nestjs/swagger");
|
|
18
18
|
const currentUser_decorator_1 = require("../../../core/auth/decorators/currentUser.decorator");
|
|
19
19
|
const requirePermission_decorator_1 = require("../../../core/auth/decorators/requirePermission.decorator");
|
|
20
|
-
const permissions_guard_1 = require("../../../core/auth/guards/permissions.guard");
|
|
21
20
|
const pagination_util_1 = require("../../../core/utils/pagination.util");
|
|
22
21
|
const notifications_service_1 = require("../domain/notifications.service");
|
|
23
22
|
const createNotification_command_1 = require("./commands/createNotification.command");
|
|
@@ -124,7 +123,6 @@ __decorate([
|
|
|
124
123
|
exports.NotificationsController = NotificationsController = __decorate([
|
|
125
124
|
(0, swagger_1.ApiTags)("Notifications"),
|
|
126
125
|
(0, swagger_1.ApiBearerAuth)(),
|
|
127
|
-
(0, common_1.UseGuards)(permissions_guard_1.PermissionsGuard),
|
|
128
126
|
(0, common_1.Controller)({ path: "notifications", version: "1" }),
|
|
129
127
|
__metadata("design:paramtypes", [notifications_service_1.NotificationsService,
|
|
130
128
|
notifications_publisher_1.NotificationsPublisher])
|
|
@@ -103,6 +103,10 @@ exports.PERMISSIONS = [
|
|
|
103
103
|
{ code: "groups:update:any", description: "Atualizar grupos" },
|
|
104
104
|
{ code: "groups:delete:any", description: "Remover grupos" },
|
|
105
105
|
{ code: "audit:read:any", description: "Ler logs de auditoria" },
|
|
106
|
+
{
|
|
107
|
+
code: "audit:read:team",
|
|
108
|
+
description: "Ler logs de auditoria das pessoas da própria equipe",
|
|
109
|
+
},
|
|
106
110
|
{
|
|
107
111
|
code: "audit:read-trail:any",
|
|
108
112
|
description: "Ler trilha de auditoria de dados (old/new data) — restrito a administradores",
|
|
@@ -170,7 +174,7 @@ exports.ROLES = [
|
|
|
170
174
|
"users:invite:team",
|
|
171
175
|
"users:reset-password:team",
|
|
172
176
|
"users:deactivate:team",
|
|
173
|
-
"audit:read:
|
|
177
|
+
"audit:read:team",
|
|
174
178
|
"notifications:read:own",
|
|
175
179
|
],
|
|
176
180
|
},
|
|
@@ -74,8 +74,10 @@ export declare class RbacService {
|
|
|
74
74
|
createGroup(dto: CreateGroupCommand, actorPermissions?: string[]): Promise<Group>;
|
|
75
75
|
updateGroup(id: string, dto: UpdateGroupCommand, actorPermissions?: string[]): Promise<Group>;
|
|
76
76
|
private resolveGrantableRoles;
|
|
77
|
+
assertGroupsGrantable(groupIds: string[], actorPermissions?: string[]): Promise<void>;
|
|
78
|
+
private assertCanAssignManager;
|
|
77
79
|
private assertParentIsValid;
|
|
78
80
|
deleteGroup(id: string): Promise<void>;
|
|
79
|
-
addUserToGroup(groupId: string, userId: string): Promise<void>;
|
|
81
|
+
addUserToGroup(groupId: string, userId: string, actorPermissions?: string[]): Promise<void>;
|
|
80
82
|
removeUserFromGroup(groupId: string, userId: string): Promise<void>;
|
|
81
83
|
}
|
|
@@ -452,6 +452,9 @@ let RbacService = class RbacService {
|
|
|
452
452
|
async createGroup(dto, actorPermissions) {
|
|
453
453
|
const roles = await this.resolveGrantableRoles(dto.roleIds, actorPermissions);
|
|
454
454
|
await this.assertParentIsValid(null, dto.parentId ?? null);
|
|
455
|
+
if (dto.managerId) {
|
|
456
|
+
this.assertCanAssignManager(actorPermissions);
|
|
457
|
+
}
|
|
455
458
|
const group = this.groupRepo.create({
|
|
456
459
|
name: dto.name,
|
|
457
460
|
description: dto.description,
|
|
@@ -468,6 +471,9 @@ let RbacService = class RbacService {
|
|
|
468
471
|
if (dto.parentId !== undefined) {
|
|
469
472
|
await this.assertParentIsValid(id, dto.parentId ?? null);
|
|
470
473
|
}
|
|
474
|
+
if (dto.managerId !== undefined && dto.managerId !== group.managerId) {
|
|
475
|
+
this.assertCanAssignManager(actorPermissions);
|
|
476
|
+
}
|
|
471
477
|
if (dto.name !== undefined) {
|
|
472
478
|
group.name = dto.name;
|
|
473
479
|
}
|
|
@@ -508,6 +514,21 @@ let RbacService = class RbacService {
|
|
|
508
514
|
this.assertGrantableByActor(roles.flatMap((role) => role.permissions ?? []), actorPermissions);
|
|
509
515
|
return roles;
|
|
510
516
|
}
|
|
517
|
+
async assertGroupsGrantable(groupIds, actorPermissions) {
|
|
518
|
+
if (groupIds.length === 0) {
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
const groups = await this.groupRepo.find({
|
|
522
|
+
where: { id: (0, typeorm_1.In)(groupIds) },
|
|
523
|
+
relations: { roles: { permissions: true } },
|
|
524
|
+
});
|
|
525
|
+
this.assertGrantableByActor(groups.flatMap((group) => (group.roles ?? []).flatMap((role) => role.permissions ?? [])), actorPermissions);
|
|
526
|
+
}
|
|
527
|
+
assertCanAssignManager(actorPermissions) {
|
|
528
|
+
if (!(actorPermissions ?? []).includes("users:promote:any")) {
|
|
529
|
+
throw new common_1.ForbiddenException("Definir o gerente de um grupo é restrito a administradores");
|
|
530
|
+
}
|
|
531
|
+
}
|
|
511
532
|
async assertParentIsValid(groupId, parentId) {
|
|
512
533
|
if (!parentId) {
|
|
513
534
|
return;
|
|
@@ -527,8 +548,15 @@ let RbacService = class RbacService {
|
|
|
527
548
|
const group = await this.getGroup(id);
|
|
528
549
|
await this.groupRepo.softRemove(group);
|
|
529
550
|
}
|
|
530
|
-
async addUserToGroup(groupId, userId) {
|
|
531
|
-
const group = await this.
|
|
551
|
+
async addUserToGroup(groupId, userId, actorPermissions) {
|
|
552
|
+
const group = await this.groupRepo.findOne({
|
|
553
|
+
where: { id: groupId },
|
|
554
|
+
relations: { roles: { permissions: true } },
|
|
555
|
+
});
|
|
556
|
+
if (!group) {
|
|
557
|
+
throw new common_1.NotFoundException("Grupo não encontrado");
|
|
558
|
+
}
|
|
559
|
+
this.assertGrantableByActor((group.roles ?? []).flatMap((role) => role.permissions ?? []), actorPermissions);
|
|
532
560
|
const user = await this.userRepo.findOne({
|
|
533
561
|
where: { id: userId },
|
|
534
562
|
relations: { groups: true },
|
|
@@ -44,7 +44,7 @@ export declare class RbacController {
|
|
|
44
44
|
createGroup(dto: CreateGroupCommand, actor: AuthenticatedUser): Promise<Group>;
|
|
45
45
|
updateGroup(id: string, dto: UpdateGroupCommand, actor: AuthenticatedUser): Promise<Group>;
|
|
46
46
|
deleteGroup(id: string): Promise<void>;
|
|
47
|
-
addUserToGroup(id: string, userId: string): Promise<void>;
|
|
47
|
+
addUserToGroup(id: string, userId: string, actor: AuthenticatedUser): Promise<void>;
|
|
48
48
|
removeUserFromGroup(id: string, userId: string): Promise<void>;
|
|
49
49
|
roles(): Promise<Role[]>;
|
|
50
50
|
role(id: string): Promise<Role>;
|
|
@@ -17,7 +17,6 @@ const common_1 = require("@nestjs/common");
|
|
|
17
17
|
const swagger_1 = require("@nestjs/swagger");
|
|
18
18
|
const currentUser_decorator_1 = require("../../../core/auth/decorators/currentUser.decorator");
|
|
19
19
|
const requirePermission_decorator_1 = require("../../../core/auth/decorators/requirePermission.decorator");
|
|
20
|
-
const permissions_guard_1 = require("../../../core/auth/guards/permissions.guard");
|
|
21
20
|
const auditable_decorator_1 = require("../../audit/presentation/decorators/auditable.decorator");
|
|
22
21
|
const rbac_service_1 = require("../domain/rbac.service");
|
|
23
22
|
const createAction_command_1 = require("./commands/createAction.command");
|
|
@@ -104,8 +103,8 @@ let RbacController = class RbacController {
|
|
|
104
103
|
deleteGroup(id) {
|
|
105
104
|
return this.rbac.deleteGroup(id);
|
|
106
105
|
}
|
|
107
|
-
addUserToGroup(id, userId) {
|
|
108
|
-
return this.rbac.addUserToGroup(id, userId);
|
|
106
|
+
addUserToGroup(id, userId, actor) {
|
|
107
|
+
return this.rbac.addUserToGroup(id, userId, actor.permissions);
|
|
109
108
|
}
|
|
110
109
|
removeUserFromGroup(id, userId) {
|
|
111
110
|
return this.rbac.removeUserFromGroup(id, userId);
|
|
@@ -351,8 +350,9 @@ __decorate([
|
|
|
351
350
|
(0, requirePermission_decorator_1.RequirePermission)("groups:update:any"),
|
|
352
351
|
__param(0, (0, common_1.Param)("id", common_1.ParseUUIDPipe)),
|
|
353
352
|
__param(1, (0, common_1.Param)("userId", common_1.ParseUUIDPipe)),
|
|
353
|
+
__param(2, (0, currentUser_decorator_1.CurrentUser)()),
|
|
354
354
|
__metadata("design:type", Function),
|
|
355
|
-
__metadata("design:paramtypes", [String, String]),
|
|
355
|
+
__metadata("design:paramtypes", [String, String, Object]),
|
|
356
356
|
__metadata("design:returntype", Promise)
|
|
357
357
|
], RbacController.prototype, "addUserToGroup", null);
|
|
358
358
|
__decorate([
|
|
@@ -483,7 +483,6 @@ __decorate([
|
|
|
483
483
|
exports.RbacController = RbacController = __decorate([
|
|
484
484
|
(0, swagger_1.ApiTags)("RBAC"),
|
|
485
485
|
(0, swagger_1.ApiBearerAuth)(),
|
|
486
|
-
(0, common_1.UseGuards)(permissions_guard_1.PermissionsGuard),
|
|
487
486
|
(0, common_1.Controller)({ path: "rbac", version: "1" }),
|
|
488
487
|
__metadata("design:paramtypes", [rbac_service_1.RbacService])
|
|
489
488
|
], RbacController);
|
|
@@ -4,6 +4,7 @@ import { EnvService } from "../../../core/config/env.service";
|
|
|
4
4
|
import { MailerService } from "../../../core/mailer/mailer.service";
|
|
5
5
|
import { Paginated, PaginationQuery } from "../../../core/utils/pagination.util";
|
|
6
6
|
import { TokenService } from "../../auth/domain/token.service";
|
|
7
|
+
import { RbacService } from "../../rbac/domain/rbac.service";
|
|
7
8
|
import { TeamScopeService } from "../../rbac/domain/teamScope.service";
|
|
8
9
|
import { GroupRepository } from "../../rbac/infra/repositories/group.repository";
|
|
9
10
|
import { RoleRepository } from "../../rbac/infra/repositories/role.repository";
|
|
@@ -19,11 +20,12 @@ export declare class UsersService {
|
|
|
19
20
|
private readonly roleRepo;
|
|
20
21
|
private readonly groupRepo;
|
|
21
22
|
private readonly teamScope;
|
|
23
|
+
private readonly rbac;
|
|
22
24
|
private readonly env;
|
|
23
25
|
private readonly mailer;
|
|
24
26
|
private readonly tokens;
|
|
25
27
|
private readonly events;
|
|
26
|
-
constructor(userRepo: UserRepository, historyRepo: PasswordHistoryRepository, roleRepo: RoleRepository, groupRepo: GroupRepository, teamScope: TeamScopeService, env: EnvService, mailer: MailerService, tokens: TokenService, events: EventEmitter2);
|
|
28
|
+
constructor(userRepo: UserRepository, historyRepo: PasswordHistoryRepository, roleRepo: RoleRepository, groupRepo: GroupRepository, teamScope: TeamScopeService, rbac: RbacService, env: EnvService, mailer: MailerService, tokens: TokenService, events: EventEmitter2);
|
|
27
29
|
findByEmail(email: string): Promise<User | null>;
|
|
28
30
|
findById(id: string): Promise<User>;
|
|
29
31
|
findByIdForActor(id: string, actor: Actor): Promise<User>;
|
|
@@ -22,6 +22,7 @@ const codedError_util_1 = require("../../../core/utils/codedError.util");
|
|
|
22
22
|
const hash_util_1 = require("../../../core/utils/hash.util");
|
|
23
23
|
const pagination_util_1 = require("../../../core/utils/pagination.util");
|
|
24
24
|
const token_service_1 = require("../../auth/domain/token.service");
|
|
25
|
+
const rbac_service_1 = require("../../rbac/domain/rbac.service");
|
|
25
26
|
const teamScope_service_1 = require("../../rbac/domain/teamScope.service");
|
|
26
27
|
const group_repository_1 = require("../../rbac/infra/repositories/group.repository");
|
|
27
28
|
const role_repository_1 = require("../../rbac/infra/repositories/role.repository");
|
|
@@ -30,12 +31,13 @@ const user_repository_1 = require("../infra/repositories/user.repository");
|
|
|
30
31
|
const PASSWORD_HISTORY_LIMIT = 3;
|
|
31
32
|
const PASSWORD_REUSED_MESSAGE = "Esta senha já foi utilizada. Escolha uma senha que você ainda não usou neste sistema";
|
|
32
33
|
let UsersService = class UsersService {
|
|
33
|
-
constructor(userRepo, historyRepo, roleRepo, groupRepo, teamScope, env, mailer, tokens, events) {
|
|
34
|
+
constructor(userRepo, historyRepo, roleRepo, groupRepo, teamScope, rbac, env, mailer, tokens, events) {
|
|
34
35
|
this.userRepo = userRepo;
|
|
35
36
|
this.historyRepo = historyRepo;
|
|
36
37
|
this.roleRepo = roleRepo;
|
|
37
38
|
this.groupRepo = groupRepo;
|
|
38
39
|
this.teamScope = teamScope;
|
|
40
|
+
this.rbac = rbac;
|
|
39
41
|
this.env = env;
|
|
40
42
|
this.mailer = mailer;
|
|
41
43
|
this.tokens = tokens;
|
|
@@ -102,6 +104,7 @@ let UsersService = class UsersService {
|
|
|
102
104
|
if (!isAdmin) {
|
|
103
105
|
await this.teamScope.assertOwnsGroups(actor, dto.groupIds);
|
|
104
106
|
}
|
|
107
|
+
await this.rbac.assertGroupsGrantable(dto.groupIds, actor.permissions);
|
|
105
108
|
return this.groupRepo.findBy({ id: (0, typeorm_1.In)(dto.groupIds) });
|
|
106
109
|
}
|
|
107
110
|
if (isAdmin) {
|
|
@@ -342,6 +345,7 @@ exports.UsersService = UsersService = __decorate([
|
|
|
342
345
|
role_repository_1.RoleRepository,
|
|
343
346
|
group_repository_1.GroupRepository,
|
|
344
347
|
teamScope_service_1.TeamScopeService,
|
|
348
|
+
rbac_service_1.RbacService,
|
|
345
349
|
env_service_1.EnvService,
|
|
346
350
|
mailer_service_1.MailerService,
|
|
347
351
|
token_service_1.TokenService,
|