@ciscode/authentication-kit 1.1.1 → 1.1.3
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 +6 -10
- package/dist/auth-kit.module.d.ts +7 -0
- package/dist/auth-kit.module.js +50 -0
- package/dist/config/db.config.d.ts +1 -0
- package/dist/config/db.config.js +22 -0
- package/dist/config/passport.config.d.ts +3 -0
- package/dist/config/passport.config.js +253 -0
- package/dist/controllers/admin.controller.d.ts +4 -0
- package/dist/controllers/admin.controller.js +59 -0
- package/dist/controllers/auth.controller.d.ts +23 -0
- package/dist/controllers/auth.controller.js +623 -0
- package/dist/controllers/password-reset.controller.d.ts +8 -0
- package/dist/controllers/password-reset.controller.js +146 -0
- package/dist/controllers/permissions.controller.d.ts +7 -0
- package/dist/controllers/permissions.controller.js +115 -0
- package/dist/controllers/roles.controller.d.ts +7 -0
- package/dist/controllers/roles.controller.js +109 -0
- package/dist/controllers/users.controller.d.ts +8 -0
- package/dist/controllers/users.controller.js +251 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +12 -0
- package/dist/middleware/auth.guard.d.ts +4 -0
- package/dist/middleware/auth.guard.js +39 -0
- package/dist/middleware/authenticate.guard.d.ts +4 -0
- package/dist/middleware/authenticate.guard.js +44 -0
- package/dist/middleware/permission.guard.d.ts +4 -0
- package/dist/middleware/permission.guard.js +52 -0
- package/dist/models/client.model.d.ts +54 -0
- package/dist/models/client.model.js +34 -0
- package/dist/models/permission.model.d.ts +19 -0
- package/dist/models/permission.model.js +17 -0
- package/dist/models/role.model.d.ts +30 -0
- package/dist/models/role.model.js +17 -0
- package/dist/models/tenant.model.d.ts +19 -0
- package/dist/models/tenant.model.js +15 -0
- package/dist/models/user.model.d.ts +66 -0
- package/dist/models/user.model.js +42 -0
- package/dist/standalone.d.ts +1 -0
- package/dist/standalone.js +12 -0
- package/dist/utils/helper.d.ts +1 -0
- package/dist/utils/helper.js +22 -0
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
Auth Service (NestJS, JWT,
|
|
1
|
+
Auth Service (NestJS, JWT, RBAC)
|
|
2
2
|
Internal package - private to the company.
|
|
3
3
|
This package is not published on npmjs. Install it only from the company Azure Artifacts feed using a project or user-level .npmrc.
|
|
4
4
|
|
|
5
5
|
Authentication and authorization module for NestJS apps.
|
|
6
|
-
Provides local email/password auth with lockout, JWT access tokens and refresh,
|
|
6
|
+
Provides local email/password auth with lockout, JWT access tokens and refresh, RBAC, and optional OAuth (Microsoft Entra, Google, Facebook).
|
|
7
7
|
|
|
8
8
|
Features
|
|
9
9
|
Local auth (email/password) with account lockout policy.
|
|
10
10
|
JWT access tokens (Bearer) and refresh endpoint (cookie or body).
|
|
11
|
-
Multi-tenant scope on requests.
|
|
12
11
|
RBAC (roles -> permission strings).
|
|
13
12
|
Microsoft Entra (Azure AD), Google, Facebook OAuth (optional).
|
|
14
13
|
MongoDB/Mongoose models.
|
|
@@ -47,7 +46,6 @@ MAX_FAILED_LOGIN_ATTEMPTS=5
|
|
|
47
46
|
ACCOUNT_LOCK_TIME_MINUTES=15
|
|
48
47
|
|
|
49
48
|
# (Optional) Microsoft Entra ID (Azure AD)
|
|
50
|
-
MICROSOFT_TENANT_ID=common
|
|
51
49
|
MICROSOFT_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
52
50
|
MICROSOFT_CLIENT_SECRET=your-secret
|
|
53
51
|
MICROSOFT_CALLBACK_URL=${BASE_URL}/api/auth/microsoft/callback
|
|
@@ -77,11 +75,11 @@ POST /api/auth/request-password-reset - Sends a reset token (e.g., by email).
|
|
|
77
75
|
POST /api/auth/reset-password - Consumes the reset token and sets a new password.
|
|
78
76
|
GET /api/auth/microsoft - GET /api/auth/microsoft/callback - Optional Microsoft Entra OAuth; issues first-party tokens.
|
|
79
77
|
Users
|
|
80
|
-
GET /api/users - List users (
|
|
78
|
+
GET /api/users - List users (paginated).
|
|
81
79
|
POST /api/users - Create a user.
|
|
82
80
|
Additional CRUD endpoints as exposed by controllers.
|
|
83
81
|
Roles and Permissions
|
|
84
|
-
GET/POST /api/auth/roles - Manage roles (name,
|
|
82
|
+
GET/POST /api/auth/roles - Manage roles (name, permissions: string[]).
|
|
85
83
|
GET /api/auth/permissions - List permission strings and metadata.
|
|
86
84
|
|
|
87
85
|
Protecting your own routes (host app)
|
|
@@ -94,18 +92,16 @@ getReports() {
|
|
|
94
92
|
return { ok: true };
|
|
95
93
|
}
|
|
96
94
|
|
|
97
|
-
Tenant scope comes from the JWT payload (e.g., tenantId) and is used inside controllers/guards to filter queries.
|
|
98
|
-
|
|
99
95
|
Quick start (smoke tests)
|
|
100
96
|
Start your host app, then create a user and log in:
|
|
101
97
|
|
|
102
98
|
curl -X POST http://localhost:3000/api/users \
|
|
103
99
|
-H 'Content-Type: application/json' \
|
|
104
|
-
-d '{"email":"a@b.com","password":"Secret123!","
|
|
100
|
+
-d '{"email":"a@b.com","password":"Secret123!","name":"Alice"}'
|
|
105
101
|
|
|
106
102
|
curl -X POST http://localhost:3000/api/auth/login \
|
|
107
103
|
-H 'Content-Type: application/json' \
|
|
108
|
-
-d '{"email":"a@b.com","password":"Secret123!"
|
|
104
|
+
-d '{"email":"a@b.com","password":"Secret123!"}'
|
|
109
105
|
# => { "accessToken": "...", "refreshToken": "..." }
|
|
110
106
|
|
|
111
107
|
Call a protected route
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import { MiddlewareConsumer, NestModule, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
|
|
3
|
+
export declare class AuthKitModule implements NestModule, OnModuleInit, OnModuleDestroy {
|
|
4
|
+
onModuleInit(): Promise<void>;
|
|
5
|
+
onModuleDestroy(): Promise<void>;
|
|
6
|
+
configure(consumer: MiddlewareConsumer): void;
|
|
7
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
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.AuthKitModule = void 0;
|
|
13
|
+
require("dotenv/config");
|
|
14
|
+
const common_1 = require("@nestjs/common");
|
|
15
|
+
const passport_config_1 = __importDefault(require("./config/passport.config"));
|
|
16
|
+
const cookie_parser_1 = __importDefault(require("cookie-parser"));
|
|
17
|
+
const mongoose_1 = __importDefault(require("mongoose"));
|
|
18
|
+
const db_config_1 = require("./config/db.config");
|
|
19
|
+
const auth_controller_1 = require("./controllers/auth.controller");
|
|
20
|
+
const password_reset_controller_1 = require("./controllers/password-reset.controller");
|
|
21
|
+
const users_controller_1 = require("./controllers/users.controller");
|
|
22
|
+
const roles_controller_1 = require("./controllers/roles.controller");
|
|
23
|
+
const permissions_controller_1 = require("./controllers/permissions.controller");
|
|
24
|
+
const admin_controller_1 = require("./controllers/admin.controller");
|
|
25
|
+
let AuthKitModule = class AuthKitModule {
|
|
26
|
+
async onModuleInit() {
|
|
27
|
+
await (0, db_config_1.connectDB)();
|
|
28
|
+
}
|
|
29
|
+
async onModuleDestroy() {
|
|
30
|
+
await mongoose_1.default.disconnect();
|
|
31
|
+
}
|
|
32
|
+
configure(consumer) {
|
|
33
|
+
consumer
|
|
34
|
+
.apply((0, cookie_parser_1.default)(), passport_config_1.default.initialize())
|
|
35
|
+
.forRoutes({ path: '*', method: common_1.RequestMethod.ALL });
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
exports.AuthKitModule = AuthKitModule;
|
|
39
|
+
exports.AuthKitModule = AuthKitModule = __decorate([
|
|
40
|
+
(0, common_1.Module)({
|
|
41
|
+
controllers: [
|
|
42
|
+
auth_controller_1.AuthController,
|
|
43
|
+
password_reset_controller_1.PasswordResetController,
|
|
44
|
+
users_controller_1.UsersController,
|
|
45
|
+
roles_controller_1.RolesController,
|
|
46
|
+
permissions_controller_1.PermissionsController,
|
|
47
|
+
admin_controller_1.AdminController,
|
|
48
|
+
],
|
|
49
|
+
})
|
|
50
|
+
], AuthKitModule);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function connectDB(): Promise<void>;
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,253 @@
|
|
|
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
|
+
const passport_1 = __importDefault(require("passport"));
|
|
7
|
+
const passport_local_1 = require("passport-local");
|
|
8
|
+
const passport_azure_ad_oauth2_1 = require("passport-azure-ad-oauth2");
|
|
9
|
+
const passport_google_oauth20_1 = require("passport-google-oauth20");
|
|
10
|
+
const passport_facebook_1 = require("passport-facebook");
|
|
11
|
+
const bcryptjs_1 = __importDefault(require("bcryptjs"));
|
|
12
|
+
const jsonwebtoken_1 = require("jsonwebtoken");
|
|
13
|
+
const user_model_1 = __importDefault(require("../models/user.model"));
|
|
14
|
+
const client_model_1 = __importDefault(require("../models/client.model"));
|
|
15
|
+
require("dotenv/config");
|
|
16
|
+
const MAX_FAILED = parseInt(process.env.MAX_FAILED_LOGIN_ATTEMPTS || '', 10) || 3;
|
|
17
|
+
const LOCK_TIME_MIN = parseInt(process.env.ACCOUNT_LOCK_TIME_MINUTES || '', 10) || 15;
|
|
18
|
+
const LOCK_TIME_MS = LOCK_TIME_MIN * 60 * 1000;
|
|
19
|
+
passport_1.default.use(new passport_local_1.Strategy({ usernameField: 'email', passwordField: 'password', passReqToCallback: true }, async (req, email, password, done) => {
|
|
20
|
+
try {
|
|
21
|
+
const user = await user_model_1.default.findOne({ email });
|
|
22
|
+
if (!user)
|
|
23
|
+
return done(null, false, { message: 'Incorrect email.' });
|
|
24
|
+
if (user.lockUntil && user.lockUntil > Date.now()) {
|
|
25
|
+
return done(null, false, { message: `Account locked until ${new Date(user.lockUntil).toLocaleString()}.` });
|
|
26
|
+
}
|
|
27
|
+
const ok = await bcryptjs_1.default.compare(password, user.password);
|
|
28
|
+
if (!ok) {
|
|
29
|
+
user.failedLoginAttempts += 1;
|
|
30
|
+
if (user.failedLoginAttempts >= MAX_FAILED)
|
|
31
|
+
user.lockUntil = Date.now() + LOCK_TIME_MS;
|
|
32
|
+
await user.save();
|
|
33
|
+
return done(null, false, { message: 'Incorrect password.' });
|
|
34
|
+
}
|
|
35
|
+
user.failedLoginAttempts = 0;
|
|
36
|
+
user.lockUntil = undefined;
|
|
37
|
+
await user.save();
|
|
38
|
+
return done(null, user);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
return done(err);
|
|
42
|
+
}
|
|
43
|
+
}));
|
|
44
|
+
passport_1.default.use(new passport_azure_ad_oauth2_1.Strategy({
|
|
45
|
+
clientID: process.env.MICROSOFT_CLIENT_ID,
|
|
46
|
+
clientSecret: process.env.MICROSOFT_CLIENT_SECRET,
|
|
47
|
+
callbackURL: process.env.MICROSOFT_CALLBACK_URL,
|
|
48
|
+
}, async (_at, _rt, params, _profile, done) => {
|
|
49
|
+
try {
|
|
50
|
+
const decoded = (0, jsonwebtoken_1.decode)(params.id_token);
|
|
51
|
+
const microsoftId = decoded.oid;
|
|
52
|
+
const email = decoded.preferred_username;
|
|
53
|
+
const name = decoded.name;
|
|
54
|
+
let user = await user_model_1.default.findOne({ $or: [{ microsoftId }, { email }] });
|
|
55
|
+
if (!user) {
|
|
56
|
+
user = new user_model_1.default({ email, name, microsoftId, roles: [], status: 'active' });
|
|
57
|
+
await user.save();
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
let changed = false;
|
|
61
|
+
if (!user.microsoftId) {
|
|
62
|
+
user.microsoftId = microsoftId;
|
|
63
|
+
changed = true;
|
|
64
|
+
}
|
|
65
|
+
if (changed)
|
|
66
|
+
await user.save();
|
|
67
|
+
}
|
|
68
|
+
return done(null, user);
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
return done(err);
|
|
72
|
+
}
|
|
73
|
+
}));
|
|
74
|
+
passport_1.default.use('azure_ad_oauth2_client', new passport_azure_ad_oauth2_1.Strategy({
|
|
75
|
+
clientID: process.env.MICROSOFT_CLIENT_ID_CLIENT || process.env.MICROSOFT_CLIENT_ID,
|
|
76
|
+
clientSecret: process.env.MICROSOFT_CLIENT_SECRET_CLIENT || process.env.MICROSOFT_CLIENT_SECRET,
|
|
77
|
+
callbackURL: process.env.MICROSOFT_CALLBACK_URL_CLIENT,
|
|
78
|
+
}, async (_at, _rt, params, _profile, done) => {
|
|
79
|
+
try {
|
|
80
|
+
const decoded = (0, jsonwebtoken_1.decode)(params.id_token);
|
|
81
|
+
const microsoftId = decoded.oid;
|
|
82
|
+
const email = decoded.preferred_username;
|
|
83
|
+
const name = decoded.name;
|
|
84
|
+
let client = await client_model_1.default.findOne({ $or: [{ microsoftId }, { email }] });
|
|
85
|
+
if (!client) {
|
|
86
|
+
client = new client_model_1.default({ email, name, microsoftId, roles: [] });
|
|
87
|
+
await client.save();
|
|
88
|
+
}
|
|
89
|
+
else if (!client.microsoftId) {
|
|
90
|
+
client.microsoftId = microsoftId;
|
|
91
|
+
await client.save();
|
|
92
|
+
}
|
|
93
|
+
return done(null, client);
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
return done(err);
|
|
97
|
+
}
|
|
98
|
+
}));
|
|
99
|
+
if (process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET && process.env.GOOGLE_CALLBACK_URL_USER) {
|
|
100
|
+
passport_1.default.use('google-user', new passport_google_oauth20_1.Strategy({
|
|
101
|
+
clientID: process.env.GOOGLE_CLIENT_ID,
|
|
102
|
+
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
|
103
|
+
callbackURL: process.env.GOOGLE_CALLBACK_URL_USER
|
|
104
|
+
}, async (_at, _rt, profile, done) => {
|
|
105
|
+
var _a;
|
|
106
|
+
try {
|
|
107
|
+
const email = profile.emails && ((_a = profile.emails[0]) === null || _a === void 0 ? void 0 : _a.value);
|
|
108
|
+
if (!email)
|
|
109
|
+
return done(null, false);
|
|
110
|
+
let user = await user_model_1.default.findOne({ email });
|
|
111
|
+
if (!user) {
|
|
112
|
+
user = new user_model_1.default({
|
|
113
|
+
email,
|
|
114
|
+
name: profile.displayName,
|
|
115
|
+
googleId: profile.id,
|
|
116
|
+
roles: [],
|
|
117
|
+
status: 'active'
|
|
118
|
+
});
|
|
119
|
+
await user.save();
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
let changed = false;
|
|
123
|
+
if (!user.googleId) {
|
|
124
|
+
user.googleId = profile.id;
|
|
125
|
+
changed = true;
|
|
126
|
+
}
|
|
127
|
+
if (changed)
|
|
128
|
+
await user.save();
|
|
129
|
+
}
|
|
130
|
+
return done(null, user);
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
return done(err);
|
|
134
|
+
}
|
|
135
|
+
}));
|
|
136
|
+
}
|
|
137
|
+
if (process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET && process.env.GOOGLE_CALLBACK_URL_CLIENT) {
|
|
138
|
+
passport_1.default.use('google-client', new passport_google_oauth20_1.Strategy({
|
|
139
|
+
clientID: process.env.GOOGLE_CLIENT_ID,
|
|
140
|
+
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
|
141
|
+
callbackURL: process.env.GOOGLE_CALLBACK_URL_CLIENT
|
|
142
|
+
}, async (_at, _rt, profile, done) => {
|
|
143
|
+
var _a;
|
|
144
|
+
try {
|
|
145
|
+
const email = profile.emails && ((_a = profile.emails[0]) === null || _a === void 0 ? void 0 : _a.value);
|
|
146
|
+
if (!email)
|
|
147
|
+
return done(null, false);
|
|
148
|
+
let client = await client_model_1.default.findOne({ email });
|
|
149
|
+
if (!client) {
|
|
150
|
+
client = new client_model_1.default({
|
|
151
|
+
email,
|
|
152
|
+
name: profile.displayName,
|
|
153
|
+
googleId: profile.id,
|
|
154
|
+
roles: []
|
|
155
|
+
});
|
|
156
|
+
await client.save();
|
|
157
|
+
}
|
|
158
|
+
else if (!client.googleId) {
|
|
159
|
+
client.googleId = profile.id;
|
|
160
|
+
await client.save();
|
|
161
|
+
}
|
|
162
|
+
return done(null, client);
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
return done(err);
|
|
166
|
+
}
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
169
|
+
if (process.env.FB_CLIENT_ID && process.env.FB_CLIENT_SECRET && process.env.FB_CALLBACK_URL_USER) {
|
|
170
|
+
passport_1.default.use('facebook-user', new passport_facebook_1.Strategy({
|
|
171
|
+
clientID: process.env.FB_CLIENT_ID,
|
|
172
|
+
clientSecret: process.env.FB_CLIENT_SECRET,
|
|
173
|
+
callbackURL: process.env.FB_CALLBACK_URL_USER,
|
|
174
|
+
profileFields: ['id', 'displayName', 'emails']
|
|
175
|
+
}, async (_at, _rt, profile, done) => {
|
|
176
|
+
var _a;
|
|
177
|
+
try {
|
|
178
|
+
const email = profile.emails && ((_a = profile.emails[0]) === null || _a === void 0 ? void 0 : _a.value);
|
|
179
|
+
if (!email)
|
|
180
|
+
return done(null, false);
|
|
181
|
+
let user = await user_model_1.default.findOne({ email });
|
|
182
|
+
if (!user) {
|
|
183
|
+
user = new user_model_1.default({
|
|
184
|
+
email,
|
|
185
|
+
name: profile.displayName,
|
|
186
|
+
facebookId: profile.id,
|
|
187
|
+
roles: [],
|
|
188
|
+
status: 'active'
|
|
189
|
+
});
|
|
190
|
+
await user.save();
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
let changed = false;
|
|
194
|
+
if (!user.facebookId) {
|
|
195
|
+
user.facebookId = profile.id;
|
|
196
|
+
changed = true;
|
|
197
|
+
}
|
|
198
|
+
if (changed)
|
|
199
|
+
await user.save();
|
|
200
|
+
}
|
|
201
|
+
return done(null, user);
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
return done(err);
|
|
205
|
+
}
|
|
206
|
+
}));
|
|
207
|
+
}
|
|
208
|
+
if (process.env.FB_CLIENT_ID && process.env.FB_CLIENT_SECRET && process.env.FB_CALLBACK_URL_CLIENT) {
|
|
209
|
+
passport_1.default.use('facebook-client', new passport_facebook_1.Strategy({
|
|
210
|
+
clientID: process.env.FB_CLIENT_ID,
|
|
211
|
+
clientSecret: process.env.FB_CLIENT_SECRET,
|
|
212
|
+
callbackURL: process.env.FB_CALLBACK_URL_CLIENT,
|
|
213
|
+
profileFields: ['id', 'displayName', 'emails']
|
|
214
|
+
}, async (_at, _rt, profile, done) => {
|
|
215
|
+
var _a;
|
|
216
|
+
try {
|
|
217
|
+
const email = profile.emails && ((_a = profile.emails[0]) === null || _a === void 0 ? void 0 : _a.value);
|
|
218
|
+
if (!email)
|
|
219
|
+
return done(null, false);
|
|
220
|
+
let client = await client_model_1.default.findOne({ email });
|
|
221
|
+
if (!client) {
|
|
222
|
+
client = new client_model_1.default({
|
|
223
|
+
email,
|
|
224
|
+
name: profile.displayName,
|
|
225
|
+
facebookId: profile.id,
|
|
226
|
+
roles: []
|
|
227
|
+
});
|
|
228
|
+
await client.save();
|
|
229
|
+
}
|
|
230
|
+
else if (!client.facebookId) {
|
|
231
|
+
client.facebookId = profile.id;
|
|
232
|
+
await client.save();
|
|
233
|
+
}
|
|
234
|
+
return done(null, client);
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
return done(err);
|
|
238
|
+
}
|
|
239
|
+
}));
|
|
240
|
+
}
|
|
241
|
+
passport_1.default.serializeUser((principal, done) => done(null, principal.id));
|
|
242
|
+
passport_1.default.deserializeUser(async (id, done) => {
|
|
243
|
+
try {
|
|
244
|
+
let principal = await user_model_1.default.findById(id);
|
|
245
|
+
if (!principal)
|
|
246
|
+
principal = await client_model_1.default.findById(id);
|
|
247
|
+
done(null, principal);
|
|
248
|
+
}
|
|
249
|
+
catch (err) {
|
|
250
|
+
done(err);
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
exports.default = passport_1.default;
|
|
@@ -0,0 +1,59 @@
|
|
|
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);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Request, Response, NextFunction } from 'express';
|
|
2
|
+
export declare class AuthController {
|
|
3
|
+
private issueTokensAndRespond;
|
|
4
|
+
private respondWebOrMobile;
|
|
5
|
+
registerClient(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
6
|
+
clientLogin(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
7
|
+
localLogin(req: Request, res: Response, next: NextFunction): any;
|
|
8
|
+
microsoftLogin(req: Request, res: Response, next: NextFunction): any;
|
|
9
|
+
microsoftCallback(req: Request, res: Response, next: NextFunction): void;
|
|
10
|
+
microsoftExchange(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
11
|
+
googleUserLogin(req: Request, res: Response, next: NextFunction): any;
|
|
12
|
+
googleUserCallback(req: Request, res: Response, next: NextFunction): void;
|
|
13
|
+
googleClientLogin(req: Request, res: Response, next: NextFunction): any;
|
|
14
|
+
googleClientCallback(req: Request, res: Response, next: NextFunction): void;
|
|
15
|
+
googleExchange(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
16
|
+
facebookUserLogin(req: Request, res: Response, next: NextFunction): any;
|
|
17
|
+
facebookUserCallback(req: Request, res: Response, next: NextFunction): void;
|
|
18
|
+
facebookClientLogin(req: Request, res: Response, next: NextFunction): any;
|
|
19
|
+
facebookClientCallback(req: Request, res: Response, next: NextFunction): void;
|
|
20
|
+
microsoftClientLogin(req: Request, res: Response, next: NextFunction): any;
|
|
21
|
+
microsoftClientCallback(req: Request, res: Response, next: NextFunction): void;
|
|
22
|
+
refreshToken(req: Request, res: Response): Promise<Response<any, Record<string, any>>>;
|
|
23
|
+
}
|