@hedhog/admin 0.0.104 → 0.0.106
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +141 -141
- package/dist/admin.module.d.ts.map +1 -1
- package/dist/admin.module.js +8 -7
- package/dist/admin.module.js.map +1 -1
- package/dist/auth/auth.service.d.ts +1 -1
- package/dist/auth/auth.service.d.ts.map +1 -1
- package/dist/auth/auth.service.js +8 -8
- package/dist/auth/auth.service.js.map +1 -1
- package/dist/auth/auth.service.spec.js +16 -16
- package/dist/auth/auth.service.spec.js.map +1 -1
- package/dist/dto/with-locale.dto.d.ts +4 -0
- package/dist/dto/with-locale.dto.d.ts.map +1 -0
- package/dist/dto/{with-locales.dto.js → with-locale.dto.js} +5 -5
- package/dist/dto/with-locale.dto.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/locale/locale.controller.d.ts +1 -1
- package/dist/locale/locale.controller.d.ts.map +1 -1
- package/dist/locale/locale.controller.js +4 -4
- package/dist/locale/locale.controller.js.map +1 -1
- package/dist/locale/locale.middleware.d.ts +1 -1
- package/dist/locale/locale.middleware.d.ts.map +1 -1
- package/dist/locale/locale.middleware.js +2 -2
- package/dist/locale/locale.middleware.js.map +1 -1
- package/dist/locale/locale.service.d.ts +6 -6
- package/dist/locale/locale.service.d.ts.map +1 -1
- package/dist/locale/locale.service.js +43 -43
- package/dist/locale/locale.service.js.map +1 -1
- package/dist/locale/locale.service.spec.js +14 -14
- package/dist/locale/locale.service.spec.js.map +1 -1
- package/dist/menu/menu.controller.js +3 -3
- package/dist/menu/menu.controller.js.map +1 -1
- package/dist/menu/menu.service.d.ts +3 -3
- package/dist/menu/menu.service.d.ts.map +1 -1
- package/dist/menu/menu.service.js +35 -35
- package/dist/menu/menu.service.js.map +1 -1
- package/dist/menu/menu.service.spec.js +33 -37
- package/dist/menu/menu.service.spec.js.map +1 -1
- package/dist/role/dto/create.dto.d.ts +2 -2
- package/dist/role/dto/create.dto.d.ts.map +1 -1
- package/dist/role/dto/create.dto.js +2 -2
- package/dist/role/dto/create.dto.js.map +1 -1
- package/dist/role/guards/role.guard.js +4 -4
- package/dist/role/guards/role.guard.js.map +1 -1
- package/dist/role/role.controller.d.ts.map +1 -1
- package/dist/role/role.controller.js +9 -9
- package/dist/role/role.controller.js.map +1 -1
- package/dist/role/role.service.d.ts +2 -2
- package/dist/role/role.service.d.ts.map +1 -1
- package/dist/role/role.service.js +35 -35
- package/dist/role/role.service.js.map +1 -1
- package/dist/role/role.service.spec.d.ts +0 -1
- package/dist/role/role.service.spec.js +400 -340
- package/dist/role/role.service.spec.js.map +1 -1
- package/dist/route/route.controller.js +3 -3
- package/dist/route/route.controller.js.map +1 -1
- package/dist/route/route.service.d.ts +2 -2
- package/dist/route/route.service.d.ts.map +1 -1
- package/dist/route/route.service.js +19 -19
- package/dist/route/route.service.js.map +1 -1
- package/dist/route/route.service.spec.js +27 -27
- package/dist/route/route.service.spec.js.map +1 -1
- package/dist/screen/screen.controller.d.ts +1 -1
- package/dist/screen/screen.controller.d.ts.map +1 -1
- package/dist/screen/screen.controller.js +8 -8
- package/dist/screen/screen.controller.js.map +1 -1
- package/dist/screen/screen.service.d.ts +3 -3
- package/dist/screen/screen.service.d.ts.map +1 -1
- package/dist/screen/screen.service.js +18 -18
- package/dist/screen/screen.service.js.map +1 -1
- package/dist/screen/screen.service.spec.js +16 -16
- package/dist/screen/screen.service.spec.js.map +1 -1
- package/dist/setting/dto/setting.dto.d.ts +9 -0
- package/dist/setting/dto/setting.dto.d.ts.map +1 -0
- package/dist/setting/dto/{settings.dto.js → setting.dto.js} +6 -6
- package/dist/setting/dto/setting.dto.js.map +1 -0
- package/dist/setting/{settings.controller.d.ts → setting.controller.d.ts} +8 -8
- package/dist/setting/setting.controller.d.ts.map +1 -0
- package/dist/setting/{settings.controller.js → setting.controller.js} +26 -26
- package/dist/setting/setting.controller.js.map +1 -0
- package/dist/setting/setting.module.d.ts +3 -0
- package/dist/setting/setting.module.d.ts.map +1 -0
- package/dist/setting/{settings.module.js → setting.module.js} +6 -6
- package/dist/setting/setting.module.js.map +1 -0
- package/dist/setting/{settings.service.d.ts → setting.service.d.ts} +6 -6
- package/dist/setting/setting.service.d.ts.map +1 -0
- package/dist/setting/{settings.service.js → setting.service.js} +44 -44
- package/dist/setting/setting.service.js.map +1 -0
- package/dist/setting/setting.service.spec.d.ts +2 -0
- package/dist/setting/setting.service.spec.d.ts.map +1 -0
- package/dist/setting/{settings.service.spec.js → setting.service.spec.js} +17 -17
- package/dist/setting/setting.service.spec.js.map +1 -0
- package/dist/user/user.controller.d.ts +2 -2
- package/dist/user/user.controller.d.ts.map +1 -1
- package/dist/user/user.controller.js +8 -8
- package/dist/user/user.controller.js.map +1 -1
- package/dist/user/user.service.d.ts +3 -3
- package/dist/user/user.service.d.ts.map +1 -1
- package/dist/user/user.service.js +10 -10
- package/dist/user/user.service.js.map +1 -1
- package/dist/user/user.service.spec.js +62 -49
- package/dist/user/user.service.spec.js.map +1 -1
- package/package.json +2 -2
- package/src/admin.module.ts +37 -0
- package/src/auth/auth.controller.ts +48 -0
- package/src/auth/auth.module.ts +39 -0
- package/src/auth/auth.service.spec.ts +196 -0
- package/src/auth/auth.service.ts +175 -0
- package/src/auth/decorators/public.decorator.ts +4 -0
- package/src/auth/decorators/user.decorator.ts +17 -0
- package/src/auth/dto/forget.dto.ts +6 -0
- package/src/auth/dto/login.dto.ts +15 -0
- package/src/auth/dto/otp.dto.ts +11 -0
- package/src/auth/enums/multifactor-type.enum.ts +4 -0
- package/src/auth/guards/auth.guard.ts +50 -0
- package/src/auth/types/user.type.ts +8 -0
- package/src/dto/delete.dto.ts +8 -0
- package/src/dto/update-ids.dto.ts +9 -0
- package/src/dto/with-locale.dto.ts +8 -0
- package/src/index.ts +34 -0
- package/src/locale/dto/create.dto.ts +12 -0
- package/src/locale/dto/delete.dto.ts +8 -0
- package/src/locale/dto/set-enabled.dto.ts +9 -0
- package/src/locale/dto/update.dto.ts +15 -0
- package/src/locale/index.ts +4 -0
- package/src/locale/locale.controller.ts +79 -0
- package/src/locale/locale.decorator.ts +8 -0
- package/src/locale/locale.middleware.ts +34 -0
- package/src/locale/locale.module.ts +23 -0
- package/src/locale/locale.service.spec.ts +193 -0
- package/src/locale/locale.service.ts +366 -0
- package/src/menu/dto/create.dto.ts +25 -0
- package/src/menu/dto/order.dto.ts +8 -0
- package/src/menu/dto/update.dto.ts +19 -0
- package/src/menu/menu.controller.ts +106 -0
- package/src/menu/menu.module.ts +18 -0
- package/src/menu/menu.service.spec.ts +247 -0
- package/src/menu/menu.service.ts +263 -0
- package/src/role/decorators/role.decorator.ts +4 -0
- package/src/role/dto/create.dto.ts +7 -0
- package/src/role/dto/update.dto.ts +4 -0
- package/src/role/guards/role.guard.ts +122 -0
- package/src/role/role.controller.ts +126 -0
- package/src/role/role.module.ts +28 -0
- package/src/role/role.service.spec.ts +417 -0
- package/src/role/role.service.ts +302 -0
- package/src/route/dto/create.dto.ts +13 -0
- package/src/route/dto/update.dto.ts +15 -0
- package/src/route/route.controller.ts +91 -0
- package/src/route/route.module.ts +18 -0
- package/src/route/route.service.spec.ts +299 -0
- package/src/route/route.service.ts +164 -0
- package/src/screen/dto/create.dto.ts +19 -0
- package/src/screen/dto/update.dto.ts +19 -0
- package/src/screen/screen.controller.ts +93 -0
- package/src/screen/screen.module.ts +18 -0
- package/src/screen/screen.service.spec.ts +298 -0
- package/src/screen/screen.service.ts +181 -0
- package/src/setting/dto/create.dto.ts +1 -0
- package/src/setting/dto/setting-user.dto.ts +6 -0
- package/src/setting/dto/setting.dto.ts +17 -0
- package/src/setting/dto/update.dto.ts +3 -0
- package/src/setting/setting.controller.ts +100 -0
- package/src/setting/setting.module.ts +18 -0
- package/src/setting/setting.service.spec.ts +183 -0
- package/src/setting/setting.service.ts +346 -0
- package/src/types/http-method.ts +8 -0
- package/src/user/constants/user.constants.ts +1 -0
- package/src/user/dto/create.dto.ts +24 -0
- package/src/user/dto/update.dto.ts +41 -0
- package/src/user/user.controller.ts +75 -0
- package/src/user/user.module.ts +18 -0
- package/src/user/user.service.spec.ts +294 -0
- package/src/user/user.service.ts +129 -0
- package/tsconfig.lib.json +9 -0
- package/tsconfig.production.json +20 -0
- package/dist/dto/with-locales.dto.d.ts +0 -4
- package/dist/dto/with-locales.dto.d.ts.map +0 -1
- package/dist/dto/with-locales.dto.js.map +0 -1
- package/dist/setting/dto/settings.dto.d.ts +0 -9
- package/dist/setting/dto/settings.dto.d.ts.map +0 -1
- package/dist/setting/dto/settings.dto.js.map +0 -1
- package/dist/setting/settings.controller.d.ts.map +0 -1
- package/dist/setting/settings.controller.js.map +0 -1
- package/dist/setting/settings.module.d.ts +0 -3
- package/dist/setting/settings.module.d.ts.map +0 -1
- package/dist/setting/settings.module.js.map +0 -1
- package/dist/setting/settings.service.d.ts.map +0 -1
- package/dist/setting/settings.service.js.map +0 -1
- package/dist/setting/settings.service.spec.d.ts +0 -2
- package/dist/setting/settings.service.spec.d.ts.map +0 -1
- package/dist/setting/settings.service.spec.js.map +0 -1
@@ -1,12 +1,12 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
const testing_1 = require("@nestjs/testing");
|
4
|
-
const user_service_1 = require("./user.service");
|
5
|
-
const prisma_1 = require("@hedhog/prisma");
|
6
3
|
const pagination_1 = require("@hedhog/pagination");
|
4
|
+
const prisma_1 = require("@hedhog/prisma");
|
7
5
|
const common_1 = require("@nestjs/common");
|
6
|
+
const testing_1 = require("@nestjs/testing");
|
8
7
|
const bcrypt_1 = require("bcrypt");
|
9
8
|
const user_constants_1 = require("./constants/user.constants");
|
9
|
+
const user_service_1 = require("./user.service");
|
10
10
|
jest.mock('bcrypt', () => ({
|
11
11
|
genSalt: jest.fn().mockResolvedValue('mockSalt'),
|
12
12
|
hash: jest.fn().mockResolvedValue('mockHashedPassword'),
|
@@ -22,13 +22,13 @@ describe('UserService', () => {
|
|
22
22
|
{
|
23
23
|
provide: prisma_1.PrismaService,
|
24
24
|
useValue: {
|
25
|
-
|
25
|
+
user: {
|
26
26
|
findUnique: jest.fn(),
|
27
27
|
create: jest.fn(),
|
28
28
|
update: jest.fn(),
|
29
29
|
deleteMany: jest.fn(),
|
30
30
|
},
|
31
|
-
|
31
|
+
role_user: {
|
32
32
|
deleteMany: jest.fn(),
|
33
33
|
createMany: jest.fn(),
|
34
34
|
},
|
@@ -51,7 +51,7 @@ describe('UserService', () => {
|
|
51
51
|
expect(service).toBeDefined();
|
52
52
|
});
|
53
53
|
describe('listRoles', () => {
|
54
|
-
it('should return paginated
|
54
|
+
it('should return paginated role for a specific user', async () => {
|
55
55
|
const paginationParams = {
|
56
56
|
page: 1,
|
57
57
|
pageSize: 10,
|
@@ -73,9 +73,9 @@ describe('UserService', () => {
|
|
73
73
|
.spyOn(paginationService, 'paginate')
|
74
74
|
.mockResolvedValue(mockPaginatedRoles);
|
75
75
|
const result = await service.listRoles(1, paginationParams);
|
76
|
-
expect(paginationService.paginate).toHaveBeenCalledWith(prismaService.
|
76
|
+
expect(paginationService.paginate).toHaveBeenCalledWith(prismaService.role, paginationParams, {
|
77
77
|
include: {
|
78
|
-
|
78
|
+
role_user: {
|
79
79
|
where: { user_id: 1 },
|
80
80
|
select: { user_id: true, role_id: true },
|
81
81
|
},
|
@@ -85,19 +85,19 @@ describe('UserService', () => {
|
|
85
85
|
});
|
86
86
|
});
|
87
87
|
describe('updateRoles', () => {
|
88
|
-
it('should update user
|
88
|
+
it('should update user role', async () => {
|
89
89
|
const updateIdsDTO = { ids: [1, 2] };
|
90
90
|
jest
|
91
|
-
.spyOn(prismaService.
|
91
|
+
.spyOn(prismaService.role_user, 'deleteMany')
|
92
92
|
.mockResolvedValue({ count: 1 });
|
93
93
|
jest
|
94
|
-
.spyOn(prismaService.
|
94
|
+
.spyOn(prismaService.role_user, 'createMany')
|
95
95
|
.mockResolvedValue({ count: 2 });
|
96
96
|
await service.updateRoles(1, updateIdsDTO);
|
97
|
-
expect(prismaService.
|
97
|
+
expect(prismaService.role_user.deleteMany).toHaveBeenCalledWith({
|
98
98
|
where: { user_id: 1 },
|
99
99
|
});
|
100
|
-
expect(prismaService.
|
100
|
+
expect(prismaService.role_user.createMany).toHaveBeenCalledWith({
|
101
101
|
data: [
|
102
102
|
{ user_id: 1, role_id: 1 },
|
103
103
|
{ user_id: 1, role_id: 2 },
|
@@ -106,35 +106,48 @@ describe('UserService', () => {
|
|
106
106
|
});
|
107
107
|
});
|
108
108
|
});
|
109
|
+
/*
|
109
110
|
describe('getUsers', () => {
|
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
|
-
|
111
|
+
it('should return paginated user', async () => {
|
112
|
+
const paginationParams: PaginationDTO = {
|
113
|
+
page: 1,
|
114
|
+
pageSize: 10,
|
115
|
+
search: '',
|
116
|
+
sortField: '',
|
117
|
+
sortOrder: PageOrderDirection.Asc,
|
118
|
+
fields: '',
|
119
|
+
};
|
120
|
+
|
121
|
+
const mockPaginatedUsers = {
|
122
|
+
data: [],
|
123
|
+
total: 10,
|
124
|
+
lastPage: 1,
|
125
|
+
page: 1,
|
126
|
+
prev: 0,
|
127
|
+
next: 2,
|
128
|
+
pageSize: 10,
|
129
|
+
};
|
130
|
+
|
131
|
+
jest.spyOn(prismaService, 'createInsensitiveSearch').mockReturnValue([]);
|
132
|
+
jest
|
133
|
+
.spyOn(paginationService, 'paginate')
|
134
|
+
.mockResolvedValue(mockPaginatedUsers);
|
135
|
+
|
136
|
+
const result = await service.getUsers(paginationParams);
|
137
|
+
|
138
|
+
expect(prismaService.createInsensitiveSearch).toHaveBeenCalledWith(
|
139
|
+
['name', 'email'],
|
140
|
+
paginationParams,
|
141
|
+
);
|
142
|
+
expect(paginationService.paginate).toHaveBeenCalledWith(
|
143
|
+
prismaService.user,
|
144
|
+
paginationParams,
|
145
|
+
{ where: { OR: [] } },
|
146
|
+
);
|
147
|
+
expect(result).toEqual(mockPaginatedUsers);
|
148
|
+
});
|
137
149
|
});
|
150
|
+
*/
|
138
151
|
describe('get', () => {
|
139
152
|
it('should return a specific user by ID', async () => {
|
140
153
|
const mockUser = {
|
@@ -147,9 +160,9 @@ describe('UserService', () => {
|
|
147
160
|
multifactor_id: null,
|
148
161
|
code: null,
|
149
162
|
};
|
150
|
-
jest.spyOn(prismaService.
|
163
|
+
jest.spyOn(prismaService.user, 'findUnique').mockResolvedValue(mockUser);
|
151
164
|
const result = await service.get(1);
|
152
|
-
expect(prismaService.
|
165
|
+
expect(prismaService.user.findUnique).toHaveBeenCalledWith({
|
153
166
|
where: { id: 1 },
|
154
167
|
});
|
155
168
|
expect(result).toEqual(mockUser);
|
@@ -181,9 +194,9 @@ describe('UserService', () => {
|
|
181
194
|
multifactor_id: null,
|
182
195
|
code: null,
|
183
196
|
};
|
184
|
-
jest.spyOn(prismaService.
|
197
|
+
jest.spyOn(prismaService.user, 'create').mockResolvedValue(mockUser);
|
185
198
|
const result = await service.create(createDTO);
|
186
|
-
expect(prismaService.
|
199
|
+
expect(prismaService.user.create).toHaveBeenCalledWith({
|
187
200
|
data: {
|
188
201
|
email: createDTO.email,
|
189
202
|
name: createDTO.name,
|
@@ -207,9 +220,9 @@ describe('UserService', () => {
|
|
207
220
|
multifactor_id: null,
|
208
221
|
code: null,
|
209
222
|
};
|
210
|
-
jest.spyOn(prismaService.
|
223
|
+
jest.spyOn(prismaService.user, 'update').mockResolvedValue(mockUser);
|
211
224
|
const result = await service.update(updateInput);
|
212
|
-
expect(prismaService.
|
225
|
+
expect(prismaService.user.update).toHaveBeenCalledWith({
|
213
226
|
where: { id: updateInput.id },
|
214
227
|
data: updateInput.data,
|
215
228
|
});
|
@@ -221,13 +234,13 @@ describe('UserService', () => {
|
|
221
234
|
const deleteDTO = { ids: null };
|
222
235
|
await expect(service.delete(deleteDTO)).rejects.toThrow(new common_1.BadRequestException('You must select at least one user to delete.'));
|
223
236
|
});
|
224
|
-
it('should delete
|
237
|
+
it('should delete user by ids', async () => {
|
225
238
|
const deleteDTO = { ids: [1, 2] };
|
226
239
|
jest
|
227
|
-
.spyOn(prismaService.
|
240
|
+
.spyOn(prismaService.user, 'deleteMany')
|
228
241
|
.mockResolvedValue({ count: 2 });
|
229
242
|
await service.delete(deleteDTO);
|
230
|
-
expect(prismaService.
|
243
|
+
expect(prismaService.user.deleteMany).toHaveBeenCalledWith({
|
231
244
|
where: {
|
232
245
|
id: { in: deleteDTO.ids },
|
233
246
|
email: { not: { startsWith: 'root@' } },
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"user.service.spec.js","sourceRoot":"","sources":["../../src/user/user.service.spec.ts"],"names":[],"mappings":";;AAAA,
|
1
|
+
{"version":3,"file":"user.service.spec.js","sourceRoot":"","sources":["../../src/user/user.service.spec.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@hedhog/admin",
|
3
|
-
"version": "0.0.
|
3
|
+
"version": "0.0.106",
|
4
4
|
"private": false,
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"scripts": {
|
@@ -9,7 +9,7 @@
|
|
9
9
|
"build": "tsc --project tsconfig.production.json && npm version patch",
|
10
10
|
"prod": "npm run build && npm publish --access public"
|
11
11
|
},
|
12
|
-
"
|
12
|
+
"file": [
|
13
13
|
"dist/**/*",
|
14
14
|
"src/entities/**/*.ts",
|
15
15
|
"src/migrations/**/*.ts",
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import { PaginationModule } from '@hedhog/pagination';
|
2
|
+
import { PrismaModule } from '@hedhog/prisma';
|
3
|
+
import { forwardRef, Module } from '@nestjs/common';
|
4
|
+
import { AuthModule } from './auth/auth.module';
|
5
|
+
import { LocaleModule } from './locale';
|
6
|
+
import { MenuModule } from './menu/menu.module';
|
7
|
+
import { RoleModule } from './role/role.module';
|
8
|
+
import { RouteModule } from './route/route.module';
|
9
|
+
import { ScreenModule } from './screen/screen.module';
|
10
|
+
import { SettingModule } from './setting/setting.module';
|
11
|
+
import { UserModule } from './user/user.module';
|
12
|
+
|
13
|
+
@Module({
|
14
|
+
imports: [
|
15
|
+
forwardRef(() => AuthModule),
|
16
|
+
forwardRef(() => MenuModule),
|
17
|
+
forwardRef(() => PaginationModule),
|
18
|
+
forwardRef(() => RoleModule),
|
19
|
+
forwardRef(() => RouteModule),
|
20
|
+
forwardRef(() => PrismaModule),
|
21
|
+
forwardRef(() => ScreenModule),
|
22
|
+
forwardRef(() => SettingModule),
|
23
|
+
forwardRef(() => LocaleModule),
|
24
|
+
forwardRef(() => UserModule),
|
25
|
+
],
|
26
|
+
exports: [
|
27
|
+
UserModule,
|
28
|
+
AuthModule,
|
29
|
+
RouteModule,
|
30
|
+
RoleModule,
|
31
|
+
MenuModule,
|
32
|
+
SettingModule,
|
33
|
+
ScreenModule,
|
34
|
+
LocaleModule,
|
35
|
+
],
|
36
|
+
})
|
37
|
+
export class AdminModule {}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import {
|
2
|
+
Body,
|
3
|
+
Controller,
|
4
|
+
forwardRef,
|
5
|
+
Get,
|
6
|
+
Inject,
|
7
|
+
Post,
|
8
|
+
} from '@nestjs/common';
|
9
|
+
import { Role } from '../role/decorators/role.decorator';
|
10
|
+
import { AuthService } from './auth.service';
|
11
|
+
import { Public } from './decorators/public.decorator';
|
12
|
+
import { User } from './decorators/user.decorator';
|
13
|
+
import { ForgetDTO } from './dto/forget.dto';
|
14
|
+
import { LoginDTO } from './dto/login.dto';
|
15
|
+
import { OtpDTO } from './dto/otp.dto';
|
16
|
+
import { User as UserType } from './types/user.type';
|
17
|
+
|
18
|
+
@Controller('auth')
|
19
|
+
export class AuthController {
|
20
|
+
constructor(
|
21
|
+
@Inject(forwardRef(() => AuthService))
|
22
|
+
private readonly service: AuthService,
|
23
|
+
) {}
|
24
|
+
|
25
|
+
@Role()
|
26
|
+
@Get('verify')
|
27
|
+
async verify(@User() { id }: UserType) {
|
28
|
+
return this.service.verify(id);
|
29
|
+
}
|
30
|
+
|
31
|
+
@Public()
|
32
|
+
@Post('login')
|
33
|
+
async login(@Body() { email, password }: LoginDTO) {
|
34
|
+
return this.service.login({ email, password });
|
35
|
+
}
|
36
|
+
|
37
|
+
@Public()
|
38
|
+
@Post('otp')
|
39
|
+
async otp(@Body() { token, code }: OtpDTO) {
|
40
|
+
return this.service.otp({ token, code });
|
41
|
+
}
|
42
|
+
|
43
|
+
@Public()
|
44
|
+
@Post('forget')
|
45
|
+
async forget(@Body() { email }: ForgetDTO) {
|
46
|
+
return this.service.forget({ email });
|
47
|
+
}
|
48
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
import { MailModule } from '@hedhog/mail';
|
2
|
+
import { PrismaModule } from '@hedhog/prisma';
|
3
|
+
import { forwardRef, Module } from '@nestjs/common';
|
4
|
+
import { APP_GUARD } from '@nestjs/core';
|
5
|
+
import { JwtModule } from '@nestjs/jwt';
|
6
|
+
import { AuthController } from './auth.controller';
|
7
|
+
import { AuthService } from './auth.service';
|
8
|
+
import { AuthGuard } from './guards/auth.guard';
|
9
|
+
|
10
|
+
@Module({
|
11
|
+
imports: [
|
12
|
+
forwardRef(() =>
|
13
|
+
JwtModule.registerAsync({
|
14
|
+
global: true,
|
15
|
+
useFactory: () => {
|
16
|
+
return {
|
17
|
+
secret: String(process.env.JWT_SECRET),
|
18
|
+
global: true,
|
19
|
+
signOptions: {
|
20
|
+
expiresIn: process.env.JWT_EXPIRES_IN || '30d',
|
21
|
+
},
|
22
|
+
};
|
23
|
+
},
|
24
|
+
}),
|
25
|
+
),
|
26
|
+
forwardRef(() => PrismaModule),
|
27
|
+
forwardRef(() => MailModule),
|
28
|
+
],
|
29
|
+
controllers: [AuthController],
|
30
|
+
providers: [
|
31
|
+
AuthService,
|
32
|
+
{
|
33
|
+
provide: APP_GUARD,
|
34
|
+
useClass: AuthGuard,
|
35
|
+
},
|
36
|
+
],
|
37
|
+
exports: [AuthService],
|
38
|
+
})
|
39
|
+
export class AuthModule {}
|
@@ -0,0 +1,196 @@
|
|
1
|
+
import { MailService } from '@hedhog/mail';
|
2
|
+
import { PrismaService } from '@hedhog/prisma';
|
3
|
+
import { NotFoundException } from '@nestjs/common';
|
4
|
+
import { JwtService } from '@nestjs/jwt';
|
5
|
+
import { Test, TestingModule } from '@nestjs/testing';
|
6
|
+
import { compare } from 'bcrypt';
|
7
|
+
import { AuthService } from './auth.service';
|
8
|
+
|
9
|
+
jest.mock('bcrypt');
|
10
|
+
|
11
|
+
describe('AuthService', () => {
|
12
|
+
let authService: AuthService;
|
13
|
+
let prismaService: PrismaService;
|
14
|
+
let jwtService: JwtService;
|
15
|
+
let mailService: MailService;
|
16
|
+
|
17
|
+
beforeEach(async () => {
|
18
|
+
const module: TestingModule = await Test.createTestingModule({
|
19
|
+
providers: [
|
20
|
+
AuthService,
|
21
|
+
{
|
22
|
+
provide: PrismaService,
|
23
|
+
useValue: {
|
24
|
+
user: {
|
25
|
+
findFirst: jest.fn(),
|
26
|
+
update: jest.fn(),
|
27
|
+
findUnique: jest.fn(),
|
28
|
+
},
|
29
|
+
},
|
30
|
+
},
|
31
|
+
{
|
32
|
+
provide: JwtService,
|
33
|
+
useValue: {
|
34
|
+
sign: jest.fn(),
|
35
|
+
verifyAsync: jest.fn(),
|
36
|
+
decode: jest.fn(),
|
37
|
+
},
|
38
|
+
},
|
39
|
+
{
|
40
|
+
provide: MailService,
|
41
|
+
useValue: {
|
42
|
+
send: jest.fn(),
|
43
|
+
},
|
44
|
+
},
|
45
|
+
],
|
46
|
+
}).compile();
|
47
|
+
|
48
|
+
authService = module.get<AuthService>(AuthService);
|
49
|
+
prismaService = module.get<PrismaService>(PrismaService);
|
50
|
+
jwtService = module.get<JwtService>(JwtService);
|
51
|
+
mailService = module.get<MailService>(MailService);
|
52
|
+
});
|
53
|
+
|
54
|
+
it('should be defined', () => {
|
55
|
+
expect(authService).toBeDefined();
|
56
|
+
});
|
57
|
+
|
58
|
+
describe('loginWithEmailAndPassword', () => {
|
59
|
+
it('should throw NotFoundException if user is not found', async () => {
|
60
|
+
jest.spyOn(prismaService.user, 'findFirst').mockResolvedValue(null);
|
61
|
+
|
62
|
+
await expect(
|
63
|
+
authService.loginWithEmailAndPassword('test@example.com', 'password'),
|
64
|
+
).rejects.toThrow(NotFoundException);
|
65
|
+
});
|
66
|
+
|
67
|
+
it('should throw NotFoundException if password is invalid', async () => {
|
68
|
+
const mockUser = {
|
69
|
+
id: 1,
|
70
|
+
name: 'Test User',
|
71
|
+
email: 'test@example.com',
|
72
|
+
password: 'hashedpassword',
|
73
|
+
multifactor_id: null,
|
74
|
+
code: null,
|
75
|
+
created_at: new Date(),
|
76
|
+
updated_at: new Date(),
|
77
|
+
};
|
78
|
+
jest.spyOn(prismaService.user, 'findFirst').mockResolvedValue(mockUser);
|
79
|
+
(compare as jest.Mock).mockResolvedValue(false);
|
80
|
+
|
81
|
+
await expect(
|
82
|
+
authService.loginWithEmailAndPassword('test@example.com', 'password'),
|
83
|
+
).rejects.toThrow(NotFoundException);
|
84
|
+
});
|
85
|
+
|
86
|
+
it('should return a token if login is successful', async () => {
|
87
|
+
const mockUser = {
|
88
|
+
id: 1,
|
89
|
+
name: 'Test User',
|
90
|
+
email: 'test@example.com',
|
91
|
+
password: 'hashedpassword',
|
92
|
+
multifactor_id: null,
|
93
|
+
code: null,
|
94
|
+
created_at: new Date(),
|
95
|
+
updated_at: new Date(),
|
96
|
+
};
|
97
|
+
jest.spyOn(prismaService.user, 'findFirst').mockResolvedValue(mockUser);
|
98
|
+
(compare as jest.Mock).mockResolvedValue(true);
|
99
|
+
jest.spyOn(jwtService, 'sign').mockReturnValue('token');
|
100
|
+
|
101
|
+
const result = await authService.loginWithEmailAndPassword(
|
102
|
+
'test@example.com',
|
103
|
+
'password',
|
104
|
+
);
|
105
|
+
|
106
|
+
expect(result).toEqual({ token: 'token' });
|
107
|
+
});
|
108
|
+
});
|
109
|
+
|
110
|
+
describe('forget', () => {
|
111
|
+
it('should throw NotFoundException if user is not found', async () => {
|
112
|
+
jest.spyOn(prismaService.user, 'findFirst').mockResolvedValue(null);
|
113
|
+
|
114
|
+
await expect(
|
115
|
+
authService.forget({ email: 'test@example.com' }),
|
116
|
+
).rejects.toThrow(NotFoundException);
|
117
|
+
});
|
118
|
+
|
119
|
+
it('should update user with reset code and send email', async () => {
|
120
|
+
const mockUser = {
|
121
|
+
id: 1,
|
122
|
+
name: 'Test User',
|
123
|
+
email: 'test@example.com',
|
124
|
+
password: 'hashedpassword',
|
125
|
+
multifactor_id: null,
|
126
|
+
code: null,
|
127
|
+
created_at: new Date(),
|
128
|
+
updated_at: new Date(),
|
129
|
+
};
|
130
|
+
jest.spyOn(prismaService.user, 'findFirst').mockResolvedValue(mockUser);
|
131
|
+
jest.spyOn(prismaService.user, 'update').mockResolvedValue(mockUser);
|
132
|
+
jest
|
133
|
+
.spyOn(authService, 'generateRandomString')
|
134
|
+
.mockReturnValue('resetCode');
|
135
|
+
|
136
|
+
const result = await authService.forget({ email: 'test@example.com' });
|
137
|
+
|
138
|
+
expect(prismaService.user.update).toHaveBeenCalledWith({
|
139
|
+
where: { id: 1 },
|
140
|
+
data: { code: 'resetCode' },
|
141
|
+
});
|
142
|
+
expect(mailService.send).toHaveBeenCalledWith({
|
143
|
+
to: 'test@example.com',
|
144
|
+
subject: 'Reset password',
|
145
|
+
body: `Reset your password by clicking <a href="${process.env.FRONTEND_URL}/reset-password/resetCode">here</a>`,
|
146
|
+
});
|
147
|
+
expect(result).toEqual(true);
|
148
|
+
});
|
149
|
+
});
|
150
|
+
|
151
|
+
describe('otp', () => {
|
152
|
+
it('should throw NotFoundException if user with code is not found', async () => {
|
153
|
+
jest.spyOn(jwtService, 'decode').mockReturnValue({ id: 1 });
|
154
|
+
jest.spyOn(prismaService.user, 'findFirst').mockResolvedValue(null);
|
155
|
+
|
156
|
+
await expect(
|
157
|
+
authService.otp({ token: 'token', code: 123456 }),
|
158
|
+
).rejects.toThrow(NotFoundException);
|
159
|
+
});
|
160
|
+
|
161
|
+
it('should return a token if otp is valid', async () => {
|
162
|
+
const mockUser = {
|
163
|
+
id: 1,
|
164
|
+
name: 'Test User',
|
165
|
+
email: 'test@example.com',
|
166
|
+
password: 'hashedpassword',
|
167
|
+
multifactor_id: null,
|
168
|
+
code: null,
|
169
|
+
created_at: new Date(),
|
170
|
+
updated_at: new Date(),
|
171
|
+
};
|
172
|
+
jest.spyOn(jwtService, 'decode').mockReturnValue({ id: 1 });
|
173
|
+
jest.spyOn(prismaService.user, 'findFirst').mockResolvedValue(mockUser);
|
174
|
+
jest.spyOn(prismaService.user, 'update').mockResolvedValue(mockUser);
|
175
|
+
jest.spyOn(jwtService, 'sign').mockReturnValue('newToken');
|
176
|
+
|
177
|
+
const result = await authService.otp({ token: 'token', code: 123456 });
|
178
|
+
|
179
|
+
expect(prismaService.user.update).toHaveBeenCalledWith({
|
180
|
+
where: { id: 1 },
|
181
|
+
data: { code: null },
|
182
|
+
});
|
183
|
+
expect(result).toEqual({ token: 'newToken' });
|
184
|
+
});
|
185
|
+
});
|
186
|
+
|
187
|
+
describe('verifyToken', () => {
|
188
|
+
it('should verify and return token data', async () => {
|
189
|
+
jest.spyOn(jwtService, 'verifyAsync').mockResolvedValue({ id: 1 });
|
190
|
+
|
191
|
+
const result = await authService.verifyToken('token');
|
192
|
+
|
193
|
+
expect(result).toEqual({ id: 1 });
|
194
|
+
});
|
195
|
+
});
|
196
|
+
});
|