@ciscode/authentication-kit 1.1.2 → 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 CHANGED
@@ -1,14 +1,13 @@
1
- Auth Service (NestJS, JWT, Multi-tenant, RBAC)
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, tenant scoping, RBAC, and optional OAuth (Microsoft Entra, Google, Facebook).
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 (tenant-scoped, paginated).
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, tenantId, permissions: string[]).
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!","tenantId":"t-001","name":"Alice"}'
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!","tenantId":"t-001"}'
104
+ -d '{"email":"a@b.com","password":"Secret123!"}'
109
105
  # => { "accessToken": "...", "refreshToken": "..." }
110
106
 
111
107
  Call a protected route
@@ -16,15 +16,11 @@ require("dotenv/config");
16
16
  const MAX_FAILED = parseInt(process.env.MAX_FAILED_LOGIN_ATTEMPTS || '', 10) || 3;
17
17
  const LOCK_TIME_MIN = parseInt(process.env.ACCOUNT_LOCK_TIME_MINUTES || '', 10) || 15;
18
18
  const LOCK_TIME_MS = LOCK_TIME_MIN * 60 * 1000;
19
- const DEFAULT_TENANT_ID = process.env.DEFAULT_TENANT_ID || 'social-staff';
20
19
  passport_1.default.use(new passport_local_1.Strategy({ usernameField: 'email', passwordField: 'password', passReqToCallback: true }, async (req, email, password, done) => {
21
20
  try {
22
- const query = { email };
23
- if (req.body.tenantId)
24
- query.tenantId = String(req.body.tenantId).trim();
25
- const user = await user_model_1.default.findOne(query);
21
+ const user = await user_model_1.default.findOne({ email });
26
22
  if (!user)
27
- return done(null, false, { message: 'Incorrect email (or tenant).' });
23
+ return done(null, false, { message: 'Incorrect email.' });
28
24
  if (user.lockUntil && user.lockUntil > Date.now()) {
29
25
  return done(null, false, { message: `Account locked until ${new Date(user.lockUntil).toLocaleString()}.` });
30
26
  }
@@ -55,10 +51,9 @@ passport_1.default.use(new passport_azure_ad_oauth2_1.Strategy({
55
51
  const microsoftId = decoded.oid;
56
52
  const email = decoded.preferred_username;
57
53
  const name = decoded.name;
58
- const tenantId = decoded.tid;
59
54
  let user = await user_model_1.default.findOne({ $or: [{ microsoftId }, { email }] });
60
55
  if (!user) {
61
- user = new user_model_1.default({ email, name, tenantId, microsoftId, roles: [], status: 'active' });
56
+ user = new user_model_1.default({ email, name, microsoftId, roles: [], status: 'active' });
62
57
  await user.save();
63
58
  }
64
59
  else {
@@ -67,10 +62,6 @@ passport_1.default.use(new passport_azure_ad_oauth2_1.Strategy({
67
62
  user.microsoftId = microsoftId;
68
63
  changed = true;
69
64
  }
70
- if (!user.tenantId) {
71
- user.tenantId = tenantId;
72
- changed = true;
73
- }
74
65
  if (changed)
75
66
  await user.save();
76
67
  }
@@ -121,7 +112,6 @@ if (process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET && process.
121
112
  user = new user_model_1.default({
122
113
  email,
123
114
  name: profile.displayName,
124
- tenantId: DEFAULT_TENANT_ID,
125
115
  googleId: profile.id,
126
116
  roles: [],
127
117
  status: 'active'
@@ -134,10 +124,6 @@ if (process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET && process.
134
124
  user.googleId = profile.id;
135
125
  changed = true;
136
126
  }
137
- if (!user.tenantId) {
138
- user.tenantId = DEFAULT_TENANT_ID;
139
- changed = true;
140
- }
141
127
  if (changed)
142
128
  await user.save();
143
129
  }
@@ -197,7 +183,6 @@ if (process.env.FB_CLIENT_ID && process.env.FB_CLIENT_SECRET && process.env.FB_C
197
183
  user = new user_model_1.default({
198
184
  email,
199
185
  name: profile.displayName,
200
- tenantId: DEFAULT_TENANT_ID,
201
186
  facebookId: profile.id,
202
187
  roles: [],
203
188
  status: 'active'
@@ -210,10 +195,6 @@ if (process.env.FB_CLIENT_ID && process.env.FB_CLIENT_SECRET && process.env.FB_C
210
195
  user.facebookId = profile.id;
211
196
  changed = true;
212
197
  }
213
- if (!user.tenantId) {
214
- user.tenantId = DEFAULT_TENANT_ID;
215
- changed = true;
216
- }
217
198
  if (changed)
218
199
  await user.save();
219
200
  }
@@ -26,7 +26,6 @@ const user_model_1 = __importDefault(require("../models/user.model"));
26
26
  const client_model_1 = __importDefault(require("../models/client.model"));
27
27
  const role_model_1 = __importDefault(require("../models/role.model"));
28
28
  const helper_1 = require("../utils/helper");
29
- const TENANT_ID = process.env.MICROSOFT_TENANT_ID || 'common';
30
29
  const MSAL_MOBILE_CLIENT_ID = process.env.MSAL_MOBILE_CLIENT_ID;
31
30
  const resolveJwtExpiry = (value, fallback) => (value || fallback);
32
31
  const msJwks = (0, jwks_rsa_1.default)({
@@ -58,7 +57,6 @@ let AuthController = class AuthController {
58
57
  const payload = {
59
58
  id: principal._id,
60
59
  email: principal.email,
61
- tenantId: principal.tenantId,
62
60
  roles,
63
61
  permissions,
64
62
  };
@@ -92,7 +90,6 @@ let AuthController = class AuthController {
92
90
  const payload = {
93
91
  id: principal._id,
94
92
  email: principal.email,
95
- tenantId: principal.tenantId,
96
93
  roles,
97
94
  permissions,
98
95
  };
@@ -231,10 +228,6 @@ let AuthController = class AuthController {
231
228
  }
232
229
  const email = ms.preferred_username || ms.email;
233
230
  const name = ms.name;
234
- const tid = ms.tid;
235
- if (TENANT_ID && TENANT_ID !== 'common' && tid && tid !== TENANT_ID) {
236
- return res.status(401).json({ message: 'Tenant mismatch.' });
237
- }
238
231
  if (!email) {
239
232
  return res.status(400).json({ message: 'Email claim missing in Microsoft ID token.' });
240
233
  }
@@ -244,7 +237,6 @@ let AuthController = class AuthController {
244
237
  user = new user_model_1.default({
245
238
  email,
246
239
  name,
247
- tenantId: tid || TENANT_ID,
248
240
  microsoftId,
249
241
  roles: [],
250
242
  status: 'active',
@@ -257,10 +249,6 @@ let AuthController = class AuthController {
257
249
  user.microsoftId = microsoftId;
258
250
  changed = true;
259
251
  }
260
- if (!user.tenantId) {
261
- user.tenantId = tid || TENANT_ID;
262
- changed = true;
263
- }
264
252
  if (changed)
265
253
  await user.save();
266
254
  }
@@ -302,17 +290,10 @@ let AuthController = class AuthController {
302
290
  async googleExchange(req, res) {
303
291
  var _a, _b, _c, _d, _e, _f, _g, _h;
304
292
  try {
305
- let { code, idToken, type = 'user', tenantId } = req.body || {};
293
+ let { code, idToken, type = 'user' } = req.body || {};
306
294
  if (!['user', 'client'].includes(type)) {
307
295
  return res.status(400).json({ message: 'invalid type; must be "user" or "client"' });
308
296
  }
309
- let resolvedTenantId;
310
- if (type === 'user') {
311
- resolvedTenantId = tenantId || process.env.DEFAULT_TENANT_ID;
312
- if (!resolvedTenantId) {
313
- return res.status(400).json({ message: 'tenantId is required for user login.' });
314
- }
315
- }
316
297
  let email;
317
298
  let name;
318
299
  let googleId;
@@ -352,14 +333,12 @@ let AuthController = class AuthController {
352
333
  let principal = await Model.findOne({ $or: [{ email }, { googleId }] });
353
334
  if (!principal) {
354
335
  principal = new Model(type === 'user'
355
- ? { email, name, googleId, tenantId: resolvedTenantId, roles: [], status: 'active' }
336
+ ? { email, name, googleId, roles: [], status: 'active' }
356
337
  : { email, name, googleId, roles: [] });
357
338
  await principal.save();
358
339
  }
359
340
  else if (!principal.googleId) {
360
341
  principal.googleId = googleId;
361
- if (type === 'user' && !principal.tenantId)
362
- principal.tenantId = resolvedTenantId;
363
342
  await principal.save();
364
343
  }
365
344
  const roleDocs = await role_model_1.default.find({ _id: { $in: principal.roles } })
@@ -368,7 +347,7 @@ let AuthController = class AuthController {
368
347
  const permissions = Array.from(new Set(roleDocs.flatMap((r) => r.permissions)));
369
348
  const accessTTL = resolveJwtExpiry(process.env.JWT_ACCESS_TOKEN_EXPIRES_IN, '15m');
370
349
  const refreshTTL = resolveJwtExpiry(process.env.JWT_REFRESH_TOKEN_EXPIRES_IN, '7d');
371
- const payload = { id: principal._id, email: principal.email, tenantId: principal.tenantId, roles, permissions };
350
+ const payload = { id: principal._id, email: principal.email, roles, permissions };
372
351
  const accessToken = jsonwebtoken_1.default.sign(payload, process.env.JWT_SECRET, { expiresIn: accessTTL });
373
352
  const refreshToken = jsonwebtoken_1.default.sign({ id: principal._id }, process.env.JWT_REFRESH_SECRET, { expiresIn: refreshTTL });
374
353
  principal.refreshToken = refreshToken;
@@ -468,7 +447,6 @@ let AuthController = class AuthController {
468
447
  const payload = {
469
448
  id: principal._id,
470
449
  email: principal.email,
471
- tenantId: principal.tenantId,
472
450
  roles,
473
451
  permissions,
474
452
  };
@@ -21,11 +21,11 @@ const role_model_1 = __importDefault(require("../models/role.model"));
21
21
  let RolesController = class RolesController {
22
22
  async createRole(req, res) {
23
23
  try {
24
- const { tenantId, name, description, permissions } = req.body;
25
- if (!tenantId || !name) {
26
- return res.status(400).json({ message: 'tenantId and role name are required.' });
24
+ const { name, description, permissions } = req.body;
25
+ if (!name) {
26
+ return res.status(400).json({ message: 'Role name is required.' });
27
27
  }
28
- const newRole = new role_model_1.default({ tenantId, name, description, permissions });
28
+ const newRole = new role_model_1.default({ name, description, permissions });
29
29
  await newRole.save();
30
30
  return res.status(201).json(newRole);
31
31
  }
@@ -36,11 +36,7 @@ let RolesController = class RolesController {
36
36
  }
37
37
  async getRoles(req, res) {
38
38
  try {
39
- const { tenantId } = req.params;
40
- if (!tenantId) {
41
- return res.status(400).json({ message: 'tenantId is required in the URL.' });
42
- }
43
- const roles = await role_model_1.default.paginate({ tenantId }, { page: 1, limit: 100 });
39
+ const roles = await role_model_1.default.paginate({}, { page: 1, limit: 100 });
44
40
  return res.status(200).json(roles);
45
41
  }
46
42
  catch (error) {
@@ -85,7 +81,7 @@ __decorate([
85
81
  __metadata("design:returntype", Promise)
86
82
  ], RolesController.prototype, "createRole", null);
87
83
  __decorate([
88
- (0, common_1.Get)(':tenantId'),
84
+ (0, common_1.Get)(),
89
85
  __param(0, (0, common_1.Req)()),
90
86
  __param(1, (0, common_1.Res)()),
91
87
  __metadata("design:type", Function),
@@ -24,17 +24,14 @@ const node_crypto_1 = require("node:crypto");
24
24
  let UsersController = class UsersController {
25
25
  async createUser(req, res) {
26
26
  try {
27
- const { email, password, name, tenantId, microsoftId, roles } = req.body;
27
+ const { email, password, name, microsoftId, roles, jobTitle, company } = req.body;
28
28
  if (!email) {
29
29
  return res.status(400).json({ message: 'Email is required.' });
30
30
  }
31
- if (!tenantId) {
32
- return res.status(400).json({ message: 'TenantId is required.' });
33
- }
34
31
  if (!microsoftId && !password) {
35
32
  return res.status(400).json({ message: 'Password is required for local login.' });
36
33
  }
37
- const existingUser = await user_model_1.default.findOne({ email, tenantId });
34
+ const existingUser = await user_model_1.default.findOne({ email });
38
35
  if (existingUser) {
39
36
  return res.status(400).json({ message: 'User with this email already exists.' });
40
37
  }
@@ -48,9 +45,10 @@ let UsersController = class UsersController {
48
45
  email,
49
46
  password: hashedPassword,
50
47
  name,
51
- tenantId,
52
48
  microsoftId,
53
49
  roles,
50
+ jobTitle,
51
+ company,
54
52
  status,
55
53
  resetPasswordToken: confirmationToken,
56
54
  resetPasswordExpires: tokenExpiration
@@ -124,14 +122,11 @@ Thank you.`
124
122
  }
125
123
  async createUserInvitation(req, res) {
126
124
  try {
127
- const { email, tenantId, name } = req.body;
125
+ const { email, name } = req.body;
128
126
  if (!email) {
129
127
  return res.status(400).json({ message: 'Email is required.' });
130
128
  }
131
- if (!tenantId) {
132
- return res.status(400).json({ message: 'TenantId is required.' });
133
- }
134
- const existingUser = await user_model_1.default.findOne({ email, tenantId });
129
+ const existingUser = await user_model_1.default.findOne({ email });
135
130
  if (existingUser) {
136
131
  return res.status(400).json({ message: 'User with this email already exists.' });
137
132
  }
@@ -139,7 +134,6 @@ Thank you.`
139
134
  const tokenExpiration = Date.now() + 24 * 60 * 60 * 1000;
140
135
  const newUser = new user_model_1.default({
141
136
  email,
142
- tenantId,
143
137
  name,
144
138
  resetPasswordToken: token,
145
139
  resetPasswordExpires: tokenExpiration
@@ -180,8 +174,6 @@ Thank you!`
180
174
  async getAllUsers(req, res) {
181
175
  try {
182
176
  const filter = {};
183
- if (req.query.tenantId)
184
- filter.tenantId = req.query.tenantId;
185
177
  if (req.query.email)
186
178
  filter.email = req.query.email;
187
179
  const page = Math.max(parseInt(req.query.page, 10) || 1, 1);
package/dist/index.d.ts CHANGED
@@ -2,5 +2,4 @@ import 'reflect-metadata';
2
2
  export { AuthKitModule } from './auth-kit.module';
3
3
  export { AuthenticateGuard } from './middleware/authenticate.guard';
4
4
  export { AuthGuard } from './middleware/auth.guard';
5
- export { TenantGuard } from './middleware/tenant.guard';
6
5
  export { hasPermission } from './middleware/permission.guard';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hasPermission = exports.TenantGuard = exports.AuthGuard = exports.AuthenticateGuard = exports.AuthKitModule = void 0;
3
+ exports.hasPermission = exports.AuthGuard = exports.AuthenticateGuard = exports.AuthKitModule = void 0;
4
4
  require("reflect-metadata");
5
5
  var auth_kit_module_1 = require("./auth-kit.module");
6
6
  Object.defineProperty(exports, "AuthKitModule", { enumerable: true, get: function () { return auth_kit_module_1.AuthKitModule; } });
@@ -8,7 +8,5 @@ var authenticate_guard_1 = require("./middleware/authenticate.guard");
8
8
  Object.defineProperty(exports, "AuthenticateGuard", { enumerable: true, get: function () { return authenticate_guard_1.AuthenticateGuard; } });
9
9
  var auth_guard_1 = require("./middleware/auth.guard");
10
10
  Object.defineProperty(exports, "AuthGuard", { enumerable: true, get: function () { return auth_guard_1.AuthGuard; } });
11
- var tenant_guard_1 = require("./middleware/tenant.guard");
12
- Object.defineProperty(exports, "TenantGuard", { enumerable: true, get: function () { return tenant_guard_1.TenantGuard; } });
13
11
  var permission_guard_1 = require("./middleware/permission.guard");
14
12
  Object.defineProperty(exports, "hasPermission", { enumerable: true, get: function () { return permission_guard_1.hasPermission; } });
@@ -18,18 +18,18 @@ const hasPermission = (requiredPermission) => {
18
18
  const req = context.switchToHttp().getRequest();
19
19
  const res = context.switchToHttp().getResponse();
20
20
  try {
21
- const { tenantId, roleIds, roles, permissions } = req.user || {};
21
+ const { roleIds, roles, permissions } = req.user || {};
22
22
  const tokenPermissions = Array.isArray(permissions) ? permissions : [];
23
23
  if (tokenPermissions.includes(requiredPermission)) {
24
24
  return true;
25
25
  }
26
26
  let resolvedPermissions = [];
27
27
  if (Array.isArray(roleIds) && roleIds.length > 0) {
28
- const roleDocs = await role_model_1.default.find({ _id: { $in: roleIds }, tenantId });
28
+ const roleDocs = await role_model_1.default.find({ _id: { $in: roleIds } });
29
29
  resolvedPermissions = roleDocs.flatMap((role) => role.permissions);
30
30
  }
31
- else if (Array.isArray(roles) && roles.length > 0 && tenantId) {
32
- const roleDocs = await role_model_1.default.find({ name: { $in: roles }, tenantId });
31
+ else if (Array.isArray(roles) && roles.length > 0) {
32
+ const roleDocs = await role_model_1.default.find({ name: { $in: roles } });
33
33
  resolvedPermissions = roleDocs.flatMap((role) => role.permissions);
34
34
  }
35
35
  if (resolvedPermissions.includes(requiredPermission)) {
@@ -6,7 +6,6 @@ declare const RoleSchema: mongoose.Schema<any, mongoose.Model<any, any, any, any
6
6
  updatedAt: NativeDate;
7
7
  } & {
8
8
  name: string;
9
- tenantId: string;
10
9
  permissions: string[];
11
10
  description?: string;
12
11
  }, mongoose.Document<unknown, {}, mongoose.FlatRecord<{
@@ -14,7 +13,6 @@ declare const RoleSchema: mongoose.Schema<any, mongoose.Model<any, any, any, any
14
13
  updatedAt: NativeDate;
15
14
  } & {
16
15
  name: string;
17
- tenantId: string;
18
16
  permissions: string[];
19
17
  description?: string;
20
18
  }>> & mongoose.FlatRecord<{
@@ -22,7 +20,6 @@ declare const RoleSchema: mongoose.Schema<any, mongoose.Model<any, any, any, any
22
20
  updatedAt: NativeDate;
23
21
  } & {
24
22
  name: string;
25
- tenantId: string;
26
23
  permissions: string[];
27
24
  description?: string;
28
25
  }> & {
@@ -7,13 +7,11 @@ exports.RoleSchema = void 0;
7
7
  const mongoose_1 = __importDefault(require("mongoose"));
8
8
  const mongoose_paginate_v2_1 = __importDefault(require("mongoose-paginate-v2"));
9
9
  const RoleSchema = new mongoose_1.default.Schema({
10
- tenantId: { type: String, required: true },
11
- name: { type: String, required: true },
10
+ name: { type: String, required: true, unique: true },
12
11
  description: { type: String },
13
12
  permissions: [{ type: String }]
14
13
  }, { timestamps: true });
15
14
  exports.RoleSchema = RoleSchema;
16
15
  RoleSchema.plugin(mongoose_paginate_v2_1.default);
17
- RoleSchema.index({ tenantId: 1, name: 1 }, { unique: true });
18
16
  const Role = mongoose_1.default.models.Role || mongoose_1.default.model('Role', RoleSchema);
19
17
  exports.default = Role;
@@ -6,12 +6,13 @@ declare const UserSchema: mongoose.Schema<any, mongoose.Model<any, any, any, any
6
6
  updatedAt: NativeDate;
7
7
  } & {
8
8
  email: string;
9
- tenantId: string;
10
9
  roles: mongoose.Types.ObjectId[];
11
10
  status: "pending" | "active" | "suspended" | "deactivated";
12
11
  failedLoginAttempts: number;
13
12
  name?: string;
14
13
  password?: string;
14
+ jobTitle?: string;
15
+ company?: string;
15
16
  microsoftId?: string;
16
17
  googleId?: string;
17
18
  facebookId?: string;
@@ -24,12 +25,13 @@ declare const UserSchema: mongoose.Schema<any, mongoose.Model<any, any, any, any
24
25
  updatedAt: NativeDate;
25
26
  } & {
26
27
  email: string;
27
- tenantId: string;
28
28
  roles: mongoose.Types.ObjectId[];
29
29
  status: "pending" | "active" | "suspended" | "deactivated";
30
30
  failedLoginAttempts: number;
31
31
  name?: string;
32
32
  password?: string;
33
+ jobTitle?: string;
34
+ company?: string;
33
35
  microsoftId?: string;
34
36
  googleId?: string;
35
37
  facebookId?: string;
@@ -42,12 +44,13 @@ declare const UserSchema: mongoose.Schema<any, mongoose.Model<any, any, any, any
42
44
  updatedAt: NativeDate;
43
45
  } & {
44
46
  email: string;
45
- tenantId: string;
46
47
  roles: mongoose.Types.ObjectId[];
47
48
  status: "pending" | "active" | "suspended" | "deactivated";
48
49
  failedLoginAttempts: number;
49
50
  name?: string;
50
51
  password?: string;
52
+ jobTitle?: string;
53
+ company?: string;
51
54
  microsoftId?: string;
52
55
  googleId?: string;
53
56
  facebookId?: string;
@@ -9,7 +9,8 @@ const mongoose_paginate_v2_1 = __importDefault(require("mongoose-paginate-v2"));
9
9
  const UserSchema = new mongoose_1.default.Schema({
10
10
  email: {
11
11
  type: String,
12
- required: true
12
+ required: true,
13
+ unique: true
13
14
  },
14
15
  password: {
15
16
  type: String,
@@ -18,7 +19,8 @@ const UserSchema = new mongoose_1.default.Schema({
18
19
  }
19
20
  },
20
21
  name: { type: String },
21
- tenantId: { type: String, required: true },
22
+ jobTitle: { type: String },
23
+ company: { type: String },
22
24
  microsoftId: { type: String, index: true },
23
25
  googleId: { type: String, index: true },
24
26
  facebookId: { type: String, index: true },
@@ -36,6 +38,5 @@ const UserSchema = new mongoose_1.default.Schema({
36
38
  }, { timestamps: true });
37
39
  exports.UserSchema = UserSchema;
38
40
  UserSchema.plugin(mongoose_paginate_v2_1.default);
39
- UserSchema.index({ tenantId: 1, email: 1 }, { unique: true });
40
41
  const User = mongoose_1.default.models.User || mongoose_1.default.model('User', UserSchema);
41
42
  exports.default = User;
package/package.json CHANGED
@@ -7,8 +7,8 @@
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/CISCODE-MA/AuthKit.git"
9
9
  },
10
- "version": "1.1.2",
11
- "description": "A login library with local login, Microsoft Entra ID authentication, password reset, and roles/permissions for multi-tenant applications.",
10
+ "version": "1.1.3",
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": [
@@ -30,7 +30,7 @@
30
30
  "password-reset",
31
31
  "roles",
32
32
  "permissions",
33
- "multi-tenant"
33
+ "users"
34
34
  ],
35
35
  "author": "Ciscode",
36
36
  "license": "MIT",
@@ -1,4 +0,0 @@
1
- import { CanActivate, ExecutionContext } from '@nestjs/common';
2
- export declare class TenantGuard implements CanActivate {
3
- canActivate(context: ExecutionContext): boolean;
4
- }
@@ -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.TenantGuard = void 0;
13
- const common_1 = require("@nestjs/common");
14
- const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
15
- let TenantGuard = class TenantGuard {
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.tenantId = decoded.tenantId;
28
- return true;
29
- }
30
- catch (error) {
31
- res.status(403).json({ error: 'Invalid token' });
32
- return false;
33
- }
34
- }
35
- };
36
- exports.TenantGuard = TenantGuard;
37
- exports.TenantGuard = TenantGuard = __decorate([
38
- (0, common_1.Injectable)()
39
- ], TenantGuard);