@ciscode/authentication-kit 1.1.6 → 1.2.0
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/README.md +455 -120
- package/dist/auth-kit.module.d.ts +6 -4
- package/dist/auth-kit.module.js +64 -13
- package/dist/config/passport.config.d.ts +2 -1
- package/dist/config/passport.config.js +64 -241
- package/dist/controllers/auth.controller.d.ts +35 -19
- package/dist/controllers/auth.controller.js +155 -488
- package/dist/controllers/permissions.controller.d.ts +10 -5
- package/dist/controllers/permissions.controller.js +40 -76
- package/dist/controllers/roles.controller.d.ts +11 -5
- package/dist/controllers/roles.controller.js +49 -66
- package/dist/controllers/users.controller.d.ts +15 -7
- package/dist/controllers/users.controller.js +52 -227
- package/dist/dtos/auth/forgot-password.dto.d.ts +3 -0
- package/dist/dtos/auth/forgot-password.dto.js +20 -0
- package/dist/dtos/auth/login.dto.d.ts +4 -0
- package/dist/dtos/auth/login.dto.js +24 -0
- package/dist/dtos/auth/refresh-token.dto.d.ts +3 -0
- package/dist/dtos/auth/refresh-token.dto.js +21 -0
- package/dist/dtos/auth/register.dto.d.ts +13 -0
- package/dist/dtos/auth/register.dto.js +56 -0
- package/dist/dtos/auth/resend-verification.dto.d.ts +3 -0
- package/dist/dtos/auth/resend-verification.dto.js +20 -0
- package/dist/dtos/auth/reset-password.dto.d.ts +4 -0
- package/dist/dtos/auth/reset-password.dto.js +25 -0
- package/dist/dtos/auth/update-user-role.dto.d.ts +3 -0
- package/dist/dtos/auth/update-user-role.dto.js +21 -0
- package/dist/dtos/auth/verify-email.dto.d.ts +3 -0
- package/dist/dtos/auth/verify-email.dto.js +20 -0
- package/dist/dtos/permission/create-permission.dto.d.ts +4 -0
- package/dist/dtos/permission/create-permission.dto.js +25 -0
- package/dist/dtos/permission/update-permission.dto.d.ts +4 -0
- package/dist/dtos/permission/update-permission.dto.js +26 -0
- package/dist/dtos/role/create-role.dto.d.ts +4 -0
- package/dist/dtos/role/create-role.dto.js +26 -0
- package/dist/dtos/role/update-role.dto.d.ts +7 -0
- package/dist/dtos/role/update-role.dto.js +35 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +11 -5
- package/dist/middleware/admin.decorator.d.ts +1 -0
- package/dist/middleware/admin.decorator.js +8 -0
- package/dist/middleware/admin.guard.d.ts +7 -0
- package/dist/middleware/admin.guard.js +35 -0
- package/dist/middleware/authenticate.guard.d.ts +5 -1
- package/dist/middleware/authenticate.guard.js +35 -8
- package/dist/middleware/role.guard.d.ts +4 -0
- package/dist/middleware/role.guard.js +29 -0
- package/dist/models/permission.model.d.ts +8 -16
- package/dist/models/permission.model.js +25 -14
- package/dist/models/role.model.d.ts +9 -28
- package/dist/models/role.model.js +26 -14
- package/dist/models/user.model.d.ts +22 -64
- package/dist/models/user.model.js +82 -41
- package/dist/repositories/permission.repository.d.ts +34 -0
- package/dist/repositories/permission.repository.js +47 -0
- package/dist/repositories/role.repository.d.ts +39 -0
- package/dist/repositories/role.repository.js +50 -0
- package/dist/repositories/user.repository.d.ts +57 -0
- package/dist/repositories/user.repository.js +71 -0
- package/dist/services/admin-role.service.d.ts +7 -0
- package/dist/services/admin-role.service.js +33 -0
- package/dist/services/auth.service.d.ts +49 -0
- package/dist/services/auth.service.js +219 -0
- package/dist/services/mail.service.d.ts +5 -0
- package/dist/services/mail.service.js +39 -0
- package/dist/services/oauth.service.d.ts +32 -0
- package/dist/services/oauth.service.js +138 -0
- package/dist/services/permissions.service.d.ts +19 -0
- package/dist/services/permissions.service.js +44 -0
- package/dist/services/roles.service.d.ts +23 -0
- package/dist/services/roles.service.js +57 -0
- package/dist/services/seed.service.d.ts +11 -0
- package/dist/services/seed.service.js +50 -0
- package/dist/services/users.service.d.ts +30 -0
- package/dist/services/users.service.js +81 -0
- package/package.json +31 -21
- package/dist/config/db.config.d.ts +0 -1
- package/dist/config/db.config.js +0 -22
- package/dist/controllers/admin.controller.d.ts +0 -4
- package/dist/controllers/admin.controller.js +0 -59
- package/dist/controllers/password-reset.controller.d.ts +0 -8
- package/dist/controllers/password-reset.controller.js +0 -146
- package/dist/middleware/auth.guard.d.ts +0 -4
- package/dist/middleware/auth.guard.js +0 -39
- package/dist/middleware/permission.guard.d.ts +0 -4
- package/dist/middleware/permission.guard.js +0 -52
- package/dist/models/client.model.d.ts +0 -54
- package/dist/models/client.model.js +0 -37
- package/dist/models/tenant.model.d.ts +0 -19
- package/dist/models/tenant.model.js +0 -15
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { UserRepository } from '../repositories/user.repository';
|
|
2
|
+
import { RoleRepository } from '../repositories/role.repository';
|
|
3
|
+
import { RegisterDto } from '../dtos/auth/register.dto';
|
|
4
|
+
import { Types } from 'mongoose';
|
|
5
|
+
export declare class UsersService {
|
|
6
|
+
private readonly users;
|
|
7
|
+
private readonly rolesRepo;
|
|
8
|
+
constructor(users: UserRepository, rolesRepo: RoleRepository);
|
|
9
|
+
create(dto: RegisterDto): Promise<{
|
|
10
|
+
id: any;
|
|
11
|
+
email: string;
|
|
12
|
+
}>;
|
|
13
|
+
list(filter: {
|
|
14
|
+
email?: string;
|
|
15
|
+
username?: string;
|
|
16
|
+
}): Promise<(import("mongoose").FlattenMaps<import("../models/user.model").UserDocument> & {
|
|
17
|
+
_id: Types.ObjectId;
|
|
18
|
+
})[]>;
|
|
19
|
+
setBan(id: string, banned: boolean): Promise<{
|
|
20
|
+
id: any;
|
|
21
|
+
isBanned: boolean;
|
|
22
|
+
}>;
|
|
23
|
+
delete(id: string): Promise<{
|
|
24
|
+
ok: boolean;
|
|
25
|
+
}>;
|
|
26
|
+
updateRoles(id: string, roles: string[]): Promise<{
|
|
27
|
+
id: any;
|
|
28
|
+
roles: Types.ObjectId[];
|
|
29
|
+
}>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.UsersService = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const bcryptjs_1 = __importDefault(require("bcryptjs"));
|
|
18
|
+
const user_repository_1 = require("../repositories/user.repository");
|
|
19
|
+
const role_repository_1 = require("../repositories/role.repository");
|
|
20
|
+
const mongoose_1 = require("mongoose");
|
|
21
|
+
let UsersService = class UsersService {
|
|
22
|
+
constructor(users, rolesRepo) {
|
|
23
|
+
this.users = users;
|
|
24
|
+
this.rolesRepo = rolesRepo;
|
|
25
|
+
}
|
|
26
|
+
async create(dto) {
|
|
27
|
+
if (await this.users.findByEmail(dto.email))
|
|
28
|
+
throw new Error('Email already in use.');
|
|
29
|
+
if (await this.users.findByUsername(dto.username))
|
|
30
|
+
throw new Error('Username already in use.');
|
|
31
|
+
if (dto.phoneNumber && (await this.users.findByPhone(dto.phoneNumber))) {
|
|
32
|
+
throw new Error('Phone already in use.');
|
|
33
|
+
}
|
|
34
|
+
const salt = await bcryptjs_1.default.genSalt(10);
|
|
35
|
+
const hashed = await bcryptjs_1.default.hash(dto.password, salt);
|
|
36
|
+
const user = await this.users.create({
|
|
37
|
+
fullname: dto.fullname,
|
|
38
|
+
username: dto.username,
|
|
39
|
+
email: dto.email,
|
|
40
|
+
phoneNumber: dto.phoneNumber,
|
|
41
|
+
avatar: dto.avatar,
|
|
42
|
+
password: hashed,
|
|
43
|
+
roles: [],
|
|
44
|
+
isVerified: true,
|
|
45
|
+
isBanned: false,
|
|
46
|
+
passwordChangedAt: new Date()
|
|
47
|
+
});
|
|
48
|
+
return { id: user._id, email: user.email };
|
|
49
|
+
}
|
|
50
|
+
async list(filter) {
|
|
51
|
+
return this.users.list(filter);
|
|
52
|
+
}
|
|
53
|
+
async setBan(id, banned) {
|
|
54
|
+
const user = await this.users.updateById(id, { isBanned: banned });
|
|
55
|
+
if (!user)
|
|
56
|
+
throw new Error('User not found.');
|
|
57
|
+
return { id: user._id, isBanned: user.isBanned };
|
|
58
|
+
}
|
|
59
|
+
async delete(id) {
|
|
60
|
+
const user = await this.users.deleteById(id);
|
|
61
|
+
if (!user)
|
|
62
|
+
throw new Error('User not found.');
|
|
63
|
+
return { ok: true };
|
|
64
|
+
}
|
|
65
|
+
async updateRoles(id, roles) {
|
|
66
|
+
const existing = await this.rolesRepo.findByIds(roles);
|
|
67
|
+
if (existing.length !== roles.length)
|
|
68
|
+
throw new Error('One or more roles not found.');
|
|
69
|
+
const roleIds = roles.map((r) => new mongoose_1.Types.ObjectId(r));
|
|
70
|
+
const user = await this.users.updateById(id, { roles: roleIds });
|
|
71
|
+
if (!user)
|
|
72
|
+
throw new Error('User not found.');
|
|
73
|
+
return { id: user._id, roles: user.roles };
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
exports.UsersService = UsersService;
|
|
77
|
+
exports.UsersService = UsersService = __decorate([
|
|
78
|
+
(0, common_1.Injectable)(),
|
|
79
|
+
__metadata("design:paramtypes", [user_repository_1.UserRepository,
|
|
80
|
+
role_repository_1.RoleRepository])
|
|
81
|
+
], UsersService);
|
package/package.json
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ciscode/authentication-kit",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "NestJS auth kit with local + OAuth, JWT, RBAC, password reset.",
|
|
3
5
|
"publishConfig": {
|
|
4
6
|
"access": "public"
|
|
5
7
|
},
|
|
@@ -7,8 +9,6 @@
|
|
|
7
9
|
"type": "git",
|
|
8
10
|
"url": "git+https://github.com/CISCODE-MA/AuthKit.git"
|
|
9
11
|
},
|
|
10
|
-
"version": "1.1.6",
|
|
11
|
-
"description": "A login library with local login, Microsoft Entra ID authentication, password reset, and roles/permissions.",
|
|
12
12
|
"main": "dist/index.js",
|
|
13
13
|
"types": "dist/index.d.ts",
|
|
14
14
|
"files": [
|
|
@@ -17,46 +17,52 @@
|
|
|
17
17
|
"LICENSE"
|
|
18
18
|
],
|
|
19
19
|
"scripts": {
|
|
20
|
-
"build": "tsc -p tsconfig.json",
|
|
20
|
+
"build": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
|
|
21
21
|
"start": "node dist/standalone.js",
|
|
22
22
|
"test": "echo \"No tests defined\" && exit 0",
|
|
23
23
|
"prepack": "npm run build",
|
|
24
24
|
"release": "semantic-release"
|
|
25
25
|
},
|
|
26
26
|
"keywords": [
|
|
27
|
-
"login",
|
|
28
27
|
"authentication",
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
28
|
+
"nest",
|
|
29
|
+
"oauth",
|
|
30
|
+
"jwt",
|
|
31
|
+
"rbac",
|
|
32
|
+
"password-reset"
|
|
34
33
|
],
|
|
35
34
|
"author": "Ciscode",
|
|
36
35
|
"license": "MIT",
|
|
37
36
|
"dependencies": {
|
|
38
|
-
"@nestjs/common": "^10.4.0",
|
|
39
|
-
"@nestjs/core": "^10.4.0",
|
|
40
|
-
"@nestjs/platform-express": "^10.4.0",
|
|
41
37
|
"axios": "^1.7.7",
|
|
42
38
|
"bcryptjs": "^2.4.3",
|
|
39
|
+
"class-transformer": "^0.5.1",
|
|
40
|
+
"class-validator": "^0.14.1",
|
|
43
41
|
"cookie-parser": "^1.4.6",
|
|
44
|
-
"dotenv": "^16.
|
|
45
|
-
"
|
|
46
|
-
"jsonwebtoken": "^9.0.0",
|
|
42
|
+
"dotenv": "^16.4.5",
|
|
43
|
+
"jsonwebtoken": "^9.0.2",
|
|
47
44
|
"jwks-rsa": "^3.1.0",
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"nodemailer": "^7.0.12",
|
|
51
|
-
"passport": "^0.6.0",
|
|
45
|
+
"nodemailer": "^6.9.15",
|
|
46
|
+
"passport": "^0.7.0",
|
|
52
47
|
"passport-azure-ad-oauth2": "^0.0.4",
|
|
53
48
|
"passport-facebook": "^3.0.0",
|
|
54
49
|
"passport-google-oauth20": "^2.0.0",
|
|
55
|
-
"passport-local": "^1.0.0"
|
|
50
|
+
"passport-local": "^1.0.0"
|
|
51
|
+
},
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"@nestjs/common": "^10.0.0 || ^11.0.0",
|
|
54
|
+
"@nestjs/core": "^10.0.0 || ^11.0.0",
|
|
55
|
+
"@nestjs/mongoose": "^11",
|
|
56
|
+
"@nestjs/platform-express": "^10.0.0 || ^11.0.0",
|
|
57
|
+
"mongoose": "^9",
|
|
56
58
|
"reflect-metadata": "^0.2.2",
|
|
57
|
-
"rxjs": "^7.
|
|
59
|
+
"rxjs": "^7.0.0"
|
|
58
60
|
},
|
|
59
61
|
"devDependencies": {
|
|
62
|
+
"@nestjs/common": "^10.4.0",
|
|
63
|
+
"@nestjs/core": "^10.4.0",
|
|
64
|
+
"@nestjs/mongoose": "^10.0.2",
|
|
65
|
+
"@nestjs/platform-express": "^10.4.0",
|
|
60
66
|
"@types/cookie-parser": "^1.4.6",
|
|
61
67
|
"@types/express": "^4.17.21",
|
|
62
68
|
"@types/jsonwebtoken": "^9.0.6",
|
|
@@ -64,8 +70,12 @@
|
|
|
64
70
|
"@types/passport-facebook": "^3.0.4",
|
|
65
71
|
"@types/passport-google-oauth20": "^2.0.15",
|
|
66
72
|
"@types/passport-local": "^1.0.38",
|
|
73
|
+
"mongoose": "^7.6.4",
|
|
74
|
+
"reflect-metadata": "^0.2.2",
|
|
75
|
+
"rxjs": "^7.8.1",
|
|
67
76
|
"semantic-release": "^25.0.2",
|
|
68
77
|
"ts-node": "^10.9.2",
|
|
78
|
+
"tsc-alias": "^1.8.16",
|
|
69
79
|
"typescript": "^5.6.2"
|
|
70
80
|
}
|
|
71
81
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function connectDB(): Promise<void>;
|
package/dist/config/db.config.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.connectDB = connectDB;
|
|
7
|
-
const mongoose_1 = __importDefault(require("mongoose"));
|
|
8
|
-
mongoose_1.default.set('strictQuery', false);
|
|
9
|
-
async function connectDB() {
|
|
10
|
-
try {
|
|
11
|
-
const mongoURI = process.env.MONGO_URI_T;
|
|
12
|
-
if (!mongoURI) {
|
|
13
|
-
throw new Error('MONGO_URI is not defined in the environment variables.');
|
|
14
|
-
}
|
|
15
|
-
await mongoose_1.default.connect(mongoURI);
|
|
16
|
-
console.log('MongoDB Connected...');
|
|
17
|
-
}
|
|
18
|
-
catch (error) {
|
|
19
|
-
console.error('MongoDB Connection Error:', error);
|
|
20
|
-
process.exit(1);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
-
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
-
};
|
|
14
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
|
-
};
|
|
17
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.AdminController = void 0;
|
|
19
|
-
const common_1 = require("@nestjs/common");
|
|
20
|
-
const user_model_1 = __importDefault(require("../models/user.model"));
|
|
21
|
-
const authenticate_guard_1 = require("../middleware/authenticate.guard");
|
|
22
|
-
let AdminController = class AdminController {
|
|
23
|
-
async suspendUser(req, res) {
|
|
24
|
-
try {
|
|
25
|
-
if (!req.user || !req.user.roles) {
|
|
26
|
-
return res.status(403).json({ message: 'Access denied. Superadmin privileges required.' });
|
|
27
|
-
}
|
|
28
|
-
if (!req.user.roles.includes('superadmin')) {
|
|
29
|
-
return res.status(403).json({ message: 'Access denied. Superadmin privileges required.' });
|
|
30
|
-
}
|
|
31
|
-
const { id } = req.params;
|
|
32
|
-
if (!id) {
|
|
33
|
-
return res.status(400).json({ message: 'User ID is required in the URL.' });
|
|
34
|
-
}
|
|
35
|
-
const updatedUser = await user_model_1.default.findByIdAndUpdate(id, { status: 'suspended' }, { new: true });
|
|
36
|
-
if (!updatedUser) {
|
|
37
|
-
return res.status(404).json({ message: 'User not found.' });
|
|
38
|
-
}
|
|
39
|
-
return res.status(200).json({ message: 'User suspended successfully.', user: updatedUser });
|
|
40
|
-
}
|
|
41
|
-
catch (error) {
|
|
42
|
-
console.error('Error suspending user:', error);
|
|
43
|
-
return res.status(500).json({ message: 'Server error', error: error.message });
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
exports.AdminController = AdminController;
|
|
48
|
-
__decorate([
|
|
49
|
-
(0, common_1.Put)(':id/suspend'),
|
|
50
|
-
__param(0, (0, common_1.Req)()),
|
|
51
|
-
__param(1, (0, common_1.Res)()),
|
|
52
|
-
__metadata("design:type", Function),
|
|
53
|
-
__metadata("design:paramtypes", [Object, Object]),
|
|
54
|
-
__metadata("design:returntype", Promise)
|
|
55
|
-
], AdminController.prototype, "suspendUser", null);
|
|
56
|
-
exports.AdminController = AdminController = __decorate([
|
|
57
|
-
(0, common_1.UseGuards)(authenticate_guard_1.AuthenticateGuard),
|
|
58
|
-
(0, common_1.Controller)('api/admin')
|
|
59
|
-
], AdminController);
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { Request, Response } from 'express';
|
|
2
|
-
export declare class PasswordResetController {
|
|
3
|
-
private requestPasswordReset;
|
|
4
|
-
private resetPassword;
|
|
5
|
-
forgotPassword(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
6
|
-
requestPasswordResetRoute(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
7
|
-
resetPasswordRoute(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
8
|
-
}
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
-
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
-
};
|
|
14
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
|
-
};
|
|
17
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.PasswordResetController = void 0;
|
|
19
|
-
const common_1 = require("@nestjs/common");
|
|
20
|
-
const node_crypto_1 = require("node:crypto");
|
|
21
|
-
const bcryptjs_1 = __importDefault(require("bcryptjs"));
|
|
22
|
-
const nodemailer_1 = __importDefault(require("nodemailer"));
|
|
23
|
-
const user_model_1 = __importDefault(require("../models/user.model"));
|
|
24
|
-
const client_model_1 = __importDefault(require("../models/client.model"));
|
|
25
|
-
const ACCOUNT_TYPES = ['user', 'client'];
|
|
26
|
-
const isAccountType = (value) => ACCOUNT_TYPES.includes(value);
|
|
27
|
-
const getModel = (type) => (type === 'user' ? user_model_1.default : client_model_1.default);
|
|
28
|
-
let PasswordResetController = class PasswordResetController {
|
|
29
|
-
async requestPasswordReset(req, res) {
|
|
30
|
-
try {
|
|
31
|
-
const { email, type } = req.body;
|
|
32
|
-
if (!email || !type) {
|
|
33
|
-
return res.status(400).json({ message: 'Email and type are required.' });
|
|
34
|
-
}
|
|
35
|
-
if (!isAccountType(type)) {
|
|
36
|
-
return res.status(400).json({ message: 'Invalid account type.' });
|
|
37
|
-
}
|
|
38
|
-
const Model = getModel(type);
|
|
39
|
-
const account = await Model.findOne({ email });
|
|
40
|
-
if (!account) {
|
|
41
|
-
return res.status(200).json({
|
|
42
|
-
message: 'If that email address is in our system, a password reset link has been sent.'
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
const token = (0, node_crypto_1.randomBytes)(20).toString('hex');
|
|
46
|
-
account.resetPasswordToken = token;
|
|
47
|
-
account.resetPasswordExpires = Date.now() + 3600000;
|
|
48
|
-
await account.save();
|
|
49
|
-
const transporter = nodemailer_1.default.createTransport({
|
|
50
|
-
host: process.env.SMTP_HOST,
|
|
51
|
-
port: parseInt(process.env.SMTP_PORT, 10),
|
|
52
|
-
secure: process.env.SMTP_SECURE === 'true',
|
|
53
|
-
auth: {
|
|
54
|
-
user: process.env.SMTP_USER,
|
|
55
|
-
pass: process.env.SMTP_PASS
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
const resetUrl = `${process.env.FRONTEND_URL}/reset-password?token=${token}&type=${type}`;
|
|
59
|
-
const mailOptions = {
|
|
60
|
-
from: process.env.FROM_EMAIL,
|
|
61
|
-
to: account.email,
|
|
62
|
-
subject: 'Password Reset',
|
|
63
|
-
text: `You are receiving this email because you (or someone else) requested a password reset.
|
|
64
|
-
Please click the link below, or paste it into your browser:
|
|
65
|
-
${resetUrl}
|
|
66
|
-
|
|
67
|
-
If you did not request this, please ignore this email.
|
|
68
|
-
This link will expire in 1 hour.`
|
|
69
|
-
};
|
|
70
|
-
await transporter.sendMail(mailOptions);
|
|
71
|
-
return res.status(200).json({
|
|
72
|
-
message: 'If that email address is in our system, a password reset link has been sent.'
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
catch (error) {
|
|
76
|
-
console.error('Error in requestPasswordReset:', error);
|
|
77
|
-
return res.status(500).json({ message: 'Server error', error: error.message });
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
async resetPassword(req, res) {
|
|
81
|
-
try {
|
|
82
|
-
const { token, newPassword, type } = req.body;
|
|
83
|
-
if (!token || !newPassword || !type) {
|
|
84
|
-
return res.status(400).json({ message: 'Token, new password, and type are required.' });
|
|
85
|
-
}
|
|
86
|
-
if (!isAccountType(type)) {
|
|
87
|
-
return res.status(400).json({ message: 'Invalid account type.' });
|
|
88
|
-
}
|
|
89
|
-
const Model = getModel(type);
|
|
90
|
-
const account = await Model.findOne({
|
|
91
|
-
resetPasswordToken: token,
|
|
92
|
-
resetPasswordExpires: { $gt: Date.now() }
|
|
93
|
-
});
|
|
94
|
-
if (!account) {
|
|
95
|
-
return res.status(400).json({ message: 'Invalid or expired token.' });
|
|
96
|
-
}
|
|
97
|
-
const salt = await bcryptjs_1.default.genSalt(10);
|
|
98
|
-
account.password = await bcryptjs_1.default.hash(newPassword, salt);
|
|
99
|
-
account.resetPasswordToken = undefined;
|
|
100
|
-
account.resetPasswordExpires = undefined;
|
|
101
|
-
await account.save();
|
|
102
|
-
return res.status(200).json({ message: 'Password has been reset successfully.' });
|
|
103
|
-
}
|
|
104
|
-
catch (error) {
|
|
105
|
-
console.error('Error in resetPassword:', error);
|
|
106
|
-
return res.status(500).json({ message: 'Server error', error: error.message });
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
forgotPassword(req, res) {
|
|
110
|
-
return this.requestPasswordReset(req, res);
|
|
111
|
-
}
|
|
112
|
-
requestPasswordResetRoute(req, res) {
|
|
113
|
-
return this.requestPasswordReset(req, res);
|
|
114
|
-
}
|
|
115
|
-
resetPasswordRoute(req, res) {
|
|
116
|
-
return this.resetPassword(req, res);
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
exports.PasswordResetController = PasswordResetController;
|
|
120
|
-
__decorate([
|
|
121
|
-
(0, common_1.Post)('forgot-password'),
|
|
122
|
-
__param(0, (0, common_1.Req)()),
|
|
123
|
-
__param(1, (0, common_1.Res)()),
|
|
124
|
-
__metadata("design:type", Function),
|
|
125
|
-
__metadata("design:paramtypes", [Object, Object]),
|
|
126
|
-
__metadata("design:returntype", void 0)
|
|
127
|
-
], PasswordResetController.prototype, "forgotPassword", null);
|
|
128
|
-
__decorate([
|
|
129
|
-
(0, common_1.Post)('request-password-reset'),
|
|
130
|
-
__param(0, (0, common_1.Req)()),
|
|
131
|
-
__param(1, (0, common_1.Res)()),
|
|
132
|
-
__metadata("design:type", Function),
|
|
133
|
-
__metadata("design:paramtypes", [Object, Object]),
|
|
134
|
-
__metadata("design:returntype", void 0)
|
|
135
|
-
], PasswordResetController.prototype, "requestPasswordResetRoute", null);
|
|
136
|
-
__decorate([
|
|
137
|
-
(0, common_1.Post)('reset-password'),
|
|
138
|
-
__param(0, (0, common_1.Req)()),
|
|
139
|
-
__param(1, (0, common_1.Res)()),
|
|
140
|
-
__metadata("design:type", Function),
|
|
141
|
-
__metadata("design:paramtypes", [Object, Object]),
|
|
142
|
-
__metadata("design:returntype", void 0)
|
|
143
|
-
], PasswordResetController.prototype, "resetPasswordRoute", null);
|
|
144
|
-
exports.PasswordResetController = PasswordResetController = __decorate([
|
|
145
|
-
(0, common_1.Controller)('api/auth')
|
|
146
|
-
], PasswordResetController);
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.AuthGuard = void 0;
|
|
13
|
-
const common_1 = require("@nestjs/common");
|
|
14
|
-
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
15
|
-
let AuthGuard = class AuthGuard {
|
|
16
|
-
canActivate(context) {
|
|
17
|
-
var _a, _b;
|
|
18
|
-
const req = context.switchToHttp().getRequest();
|
|
19
|
-
const res = context.switchToHttp().getResponse();
|
|
20
|
-
const token = (_b = (_a = req.headers) === null || _a === void 0 ? void 0 : _a.authorization) === null || _b === void 0 ? void 0 : _b.split(' ')[1];
|
|
21
|
-
if (!token) {
|
|
22
|
-
res.status(401).json({ error: 'Unauthorized' });
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
try {
|
|
26
|
-
const decoded = jsonwebtoken_1.default.verify(token, process.env.JWT_SECRET);
|
|
27
|
-
req.user = decoded;
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
30
|
-
catch (error) {
|
|
31
|
-
res.status(403).json({ error: 'Invalid token' });
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
exports.AuthGuard = AuthGuard;
|
|
37
|
-
exports.AuthGuard = AuthGuard = __decorate([
|
|
38
|
-
(0, common_1.Injectable)()
|
|
39
|
-
], AuthGuard);
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.hasPermission = void 0;
|
|
13
|
-
const common_1 = require("@nestjs/common");
|
|
14
|
-
const role_model_1 = __importDefault(require("../models/role.model"));
|
|
15
|
-
const hasPermission = (requiredPermission) => {
|
|
16
|
-
let PermissionGuard = class PermissionGuard {
|
|
17
|
-
async canActivate(context) {
|
|
18
|
-
const req = context.switchToHttp().getRequest();
|
|
19
|
-
const res = context.switchToHttp().getResponse();
|
|
20
|
-
try {
|
|
21
|
-
const { roleIds, roles, permissions } = req.user || {};
|
|
22
|
-
const tokenPermissions = Array.isArray(permissions) ? permissions : [];
|
|
23
|
-
if (tokenPermissions.includes(requiredPermission)) {
|
|
24
|
-
return true;
|
|
25
|
-
}
|
|
26
|
-
let resolvedPermissions = [];
|
|
27
|
-
if (Array.isArray(roleIds) && roleIds.length > 0) {
|
|
28
|
-
const roleDocs = await role_model_1.default.find({ _id: { $in: roleIds } });
|
|
29
|
-
resolvedPermissions = roleDocs.flatMap((role) => role.permissions);
|
|
30
|
-
}
|
|
31
|
-
else if (Array.isArray(roles) && roles.length > 0) {
|
|
32
|
-
const roleDocs = await role_model_1.default.find({ name: { $in: roles } });
|
|
33
|
-
resolvedPermissions = roleDocs.flatMap((role) => role.permissions);
|
|
34
|
-
}
|
|
35
|
-
if (resolvedPermissions.includes(requiredPermission)) {
|
|
36
|
-
return true;
|
|
37
|
-
}
|
|
38
|
-
res.status(403).json({ error: 'Forbidden: Insufficient permissions' });
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
catch (error) {
|
|
42
|
-
res.status(500).json({ error: 'Authorization error' });
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
PermissionGuard = __decorate([
|
|
48
|
-
(0, common_1.Injectable)()
|
|
49
|
-
], PermissionGuard);
|
|
50
|
-
return (0, common_1.mixin)(PermissionGuard);
|
|
51
|
-
};
|
|
52
|
-
exports.hasPermission = hasPermission;
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import mongoose from 'mongoose';
|
|
2
|
-
declare const ClientSchema: mongoose.Schema<any, mongoose.Model<any, any, any, any, any, any>, {}, {}, {}, {}, {
|
|
3
|
-
timestamps: true;
|
|
4
|
-
}, {
|
|
5
|
-
createdAt: NativeDate;
|
|
6
|
-
updatedAt: NativeDate;
|
|
7
|
-
} & {
|
|
8
|
-
roles: mongoose.Types.ObjectId[];
|
|
9
|
-
createdAt: Date;
|
|
10
|
-
email?: string;
|
|
11
|
-
name?: string;
|
|
12
|
-
password?: string;
|
|
13
|
-
microsoftId?: string;
|
|
14
|
-
googleId?: string;
|
|
15
|
-
facebookId?: string;
|
|
16
|
-
resetPasswordToken?: string;
|
|
17
|
-
resetPasswordExpires?: Date;
|
|
18
|
-
refreshToken?: string;
|
|
19
|
-
}, mongoose.Document<unknown, {}, mongoose.FlatRecord<{
|
|
20
|
-
createdAt: NativeDate;
|
|
21
|
-
updatedAt: NativeDate;
|
|
22
|
-
} & {
|
|
23
|
-
roles: mongoose.Types.ObjectId[];
|
|
24
|
-
createdAt: Date;
|
|
25
|
-
email?: string;
|
|
26
|
-
name?: string;
|
|
27
|
-
password?: string;
|
|
28
|
-
microsoftId?: string;
|
|
29
|
-
googleId?: string;
|
|
30
|
-
facebookId?: string;
|
|
31
|
-
resetPasswordToken?: string;
|
|
32
|
-
resetPasswordExpires?: Date;
|
|
33
|
-
refreshToken?: string;
|
|
34
|
-
}>> & mongoose.FlatRecord<{
|
|
35
|
-
createdAt: NativeDate;
|
|
36
|
-
updatedAt: NativeDate;
|
|
37
|
-
} & {
|
|
38
|
-
roles: mongoose.Types.ObjectId[];
|
|
39
|
-
createdAt: Date;
|
|
40
|
-
email?: string;
|
|
41
|
-
name?: string;
|
|
42
|
-
password?: string;
|
|
43
|
-
microsoftId?: string;
|
|
44
|
-
googleId?: string;
|
|
45
|
-
facebookId?: string;
|
|
46
|
-
resetPasswordToken?: string;
|
|
47
|
-
resetPasswordExpires?: Date;
|
|
48
|
-
refreshToken?: string;
|
|
49
|
-
}> & {
|
|
50
|
-
_id: mongoose.Types.ObjectId;
|
|
51
|
-
}>;
|
|
52
|
-
declare const Client: mongoose.Model<any, {}, {}, {}, any, any>;
|
|
53
|
-
export { ClientSchema };
|
|
54
|
-
export default Client;
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.ClientSchema = void 0;
|
|
7
|
-
const mongoose_1 = __importDefault(require("mongoose"));
|
|
8
|
-
const mongoose_paginate_v2_1 = __importDefault(require("mongoose-paginate-v2"));
|
|
9
|
-
const ClientSchema = new mongoose_1.default.Schema({
|
|
10
|
-
email: {
|
|
11
|
-
type: String,
|
|
12
|
-
required: function () {
|
|
13
|
-
return !this.microsoftId && !this.googleId && !this.facebookId;
|
|
14
|
-
},
|
|
15
|
-
unique: true,
|
|
16
|
-
sparse: true
|
|
17
|
-
},
|
|
18
|
-
password: {
|
|
19
|
-
type: String,
|
|
20
|
-
required: function () {
|
|
21
|
-
return !this.microsoftId && !this.googleId && !this.facebookId;
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
name: { type: String },
|
|
25
|
-
microsoftId: { type: String, index: true },
|
|
26
|
-
googleId: { type: String, index: true },
|
|
27
|
-
facebookId: { type: String, index: true },
|
|
28
|
-
roles: [{ type: mongoose_1.default.Schema.Types.ObjectId, ref: 'Role' }],
|
|
29
|
-
resetPasswordToken: { type: String },
|
|
30
|
-
resetPasswordExpires: { type: Date },
|
|
31
|
-
refreshToken: { type: String },
|
|
32
|
-
createdAt: { type: Date, default: Date.now }
|
|
33
|
-
}, { timestamps: true });
|
|
34
|
-
exports.ClientSchema = ClientSchema;
|
|
35
|
-
ClientSchema.plugin(mongoose_paginate_v2_1.default);
|
|
36
|
-
const Client = mongoose_1.default.models.Client || mongoose_1.default.model('Client', ClientSchema);
|
|
37
|
-
exports.default = Client;
|