ecrs-auth-core 1.0.62 → 1.0.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth.module.js +3 -0
- package/dist/guards/api-key.guard.d.ts +3 -1
- package/dist/guards/api-key.guard.js +17 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/services/encryption.service.d.ts +16 -0
- package/dist/services/encryption.service.js +70 -0
- package/package.json +1 -1
package/dist/auth.module.js
CHANGED
|
@@ -20,6 +20,7 @@ const feature_guard_1 = require("./guards/feature.guard");
|
|
|
20
20
|
const route_guard_1 = require("./guards/route.guard");
|
|
21
21
|
const permission_guard_1 = require("./guards/permission.guard");
|
|
22
22
|
const api_key_guard_1 = require("./guards/api-key.guard");
|
|
23
|
+
const encryption_service_1 = require("./services/encryption.service");
|
|
23
24
|
exports.AUTH_CORE_OPTIONS = 'AUTH_CORE_OPTIONS';
|
|
24
25
|
// @Global()
|
|
25
26
|
// @Module({})
|
|
@@ -115,6 +116,7 @@ let AuthCoreModule = AuthCoreModule_1 = class AuthCoreModule {
|
|
|
115
116
|
useFactory: (opts) => opts.repositories?.apiKeyRepo || null,
|
|
116
117
|
inject: [exports.AUTH_CORE_OPTIONS],
|
|
117
118
|
},
|
|
119
|
+
encryption_service_1.EncryptionService,
|
|
118
120
|
auth_service_1.AuthService,
|
|
119
121
|
jwt_strategy_1.JwtStrategy,
|
|
120
122
|
jwt_guard_1.JwtAuthGuard,
|
|
@@ -133,6 +135,7 @@ let AuthCoreModule = AuthCoreModule_1 = class AuthCoreModule {
|
|
|
133
135
|
'API_KEY_REPOSITORY',
|
|
134
136
|
jwt_1.JwtModule,
|
|
135
137
|
auth_service_1.AuthService,
|
|
138
|
+
encryption_service_1.EncryptionService,
|
|
136
139
|
jwt_strategy_1.JwtStrategy,
|
|
137
140
|
jwt_guard_1.JwtAuthGuard,
|
|
138
141
|
module_guard_1.ModuleGuard,
|
|
@@ -2,11 +2,13 @@ import { CanActivate, ExecutionContext } from '@nestjs/common';
|
|
|
2
2
|
import { Reflector } from '@nestjs/core';
|
|
3
3
|
import { Repository } from 'typeorm';
|
|
4
4
|
import { ApiKeyEntity } from '../entities/api-key.entity';
|
|
5
|
+
import { EncryptionService } from '../services/encryption.service';
|
|
5
6
|
export declare class ApiKeyGuard implements CanActivate {
|
|
6
7
|
private readonly reflector;
|
|
8
|
+
private readonly encryptionService;
|
|
7
9
|
private apiKeyRepo;
|
|
8
10
|
private rateLimitMap;
|
|
9
|
-
constructor(reflector: Reflector, apiKeyRepository?: Repository<ApiKeyEntity>);
|
|
11
|
+
constructor(reflector: Reflector, encryptionService: EncryptionService, apiKeyRepository?: Repository<ApiKeyEntity>);
|
|
10
12
|
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
11
13
|
private extractApiKey;
|
|
12
14
|
private validateApiKey;
|
|
@@ -16,9 +16,11 @@ exports.ApiKeyGuard = void 0;
|
|
|
16
16
|
const common_1 = require("@nestjs/common");
|
|
17
17
|
const core_1 = require("@nestjs/core");
|
|
18
18
|
const typeorm_1 = require("typeorm");
|
|
19
|
+
const encryption_service_1 = require("../services/encryption.service");
|
|
19
20
|
let ApiKeyGuard = class ApiKeyGuard {
|
|
20
|
-
constructor(reflector, apiKeyRepository) {
|
|
21
|
+
constructor(reflector, encryptionService, apiKeyRepository) {
|
|
21
22
|
this.reflector = reflector;
|
|
23
|
+
this.encryptionService = encryptionService;
|
|
22
24
|
this.rateLimitMap = new Map();
|
|
23
25
|
if (apiKeyRepository) {
|
|
24
26
|
this.apiKeyRepo = apiKeyRepository;
|
|
@@ -70,9 +72,19 @@ let ApiKeyGuard = class ApiKeyGuard {
|
|
|
70
72
|
if (!this.apiKeyRepo) {
|
|
71
73
|
return { valid: false, message: 'API key validation not configured' };
|
|
72
74
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
// Find all active API keys and compare hashes
|
|
76
|
+
const records = await this.apiKeyRepo.find({
|
|
77
|
+
where: { isActive: true },
|
|
75
78
|
});
|
|
79
|
+
let record = null;
|
|
80
|
+
// Compare incoming key with hashed keys in database
|
|
81
|
+
for (const dbRecord of records) {
|
|
82
|
+
const isMatch = await this.encryptionService.compareKey(apiKey, dbRecord.key);
|
|
83
|
+
if (isMatch) {
|
|
84
|
+
record = dbRecord;
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
76
88
|
if (!record) {
|
|
77
89
|
return { valid: false, message: 'API key not found or inactive' };
|
|
78
90
|
}
|
|
@@ -176,7 +188,8 @@ let ApiKeyGuard = class ApiKeyGuard {
|
|
|
176
188
|
exports.ApiKeyGuard = ApiKeyGuard;
|
|
177
189
|
exports.ApiKeyGuard = ApiKeyGuard = __decorate([
|
|
178
190
|
(0, common_1.Injectable)(),
|
|
179
|
-
__param(
|
|
191
|
+
__param(2, (0, common_1.Inject)('API_KEY_REPOSITORY')),
|
|
180
192
|
__metadata("design:paramtypes", [core_1.Reflector,
|
|
193
|
+
encryption_service_1.EncryptionService,
|
|
181
194
|
typeorm_1.Repository])
|
|
182
195
|
], ApiKeyGuard);
|
package/dist/index.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export * from './guards/permission.guard';
|
|
|
16
16
|
export * from './guards/api-key.guard';
|
|
17
17
|
export * from './jwt/jwt.guard';
|
|
18
18
|
export * from './jwt/jwt.strategy';
|
|
19
|
+
export * from './services/encryption.service';
|
|
19
20
|
export * from './interfaces/auth-core-options.interface';
|
|
20
21
|
export * from './entities/user.entity';
|
|
21
22
|
export * from './entities/role.entity';
|
package/dist/index.js
CHANGED
|
@@ -37,6 +37,8 @@ __exportStar(require("./guards/api-key.guard"), exports);
|
|
|
37
37
|
// JWT
|
|
38
38
|
__exportStar(require("./jwt/jwt.guard"), exports);
|
|
39
39
|
__exportStar(require("./jwt/jwt.strategy"), exports);
|
|
40
|
+
// Services
|
|
41
|
+
__exportStar(require("./services/encryption.service"), exports);
|
|
40
42
|
// Interfaces
|
|
41
43
|
__exportStar(require("./interfaces/auth-core-options.interface"), exports);
|
|
42
44
|
// ✅ Entities
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare class EncryptionService {
|
|
2
|
+
private readonly saltRounds;
|
|
3
|
+
/**
|
|
4
|
+
* Hash an API key using bcrypt
|
|
5
|
+
* @param plainKey - The plain text API key
|
|
6
|
+
* @returns Hashed key
|
|
7
|
+
*/
|
|
8
|
+
hashKey(plainKey: string): Promise<string>;
|
|
9
|
+
/**
|
|
10
|
+
* Compare plain key with hashed key
|
|
11
|
+
* @param plainKey - The plain text API key
|
|
12
|
+
* @param hashedKey - The hashed key from database
|
|
13
|
+
* @returns True if keys match, false otherwise
|
|
14
|
+
*/
|
|
15
|
+
compareKey(plainKey: string, hashedKey: string): Promise<boolean>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
|
+
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;
|
|
22
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
|
+
};
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.EncryptionService = void 0;
|
|
43
|
+
const common_1 = require("@nestjs/common");
|
|
44
|
+
const bcrypt = __importStar(require("bcrypt"));
|
|
45
|
+
let EncryptionService = class EncryptionService {
|
|
46
|
+
constructor() {
|
|
47
|
+
this.saltRounds = 10;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Hash an API key using bcrypt
|
|
51
|
+
* @param plainKey - The plain text API key
|
|
52
|
+
* @returns Hashed key
|
|
53
|
+
*/
|
|
54
|
+
async hashKey(plainKey) {
|
|
55
|
+
return bcrypt.hash(plainKey, this.saltRounds);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Compare plain key with hashed key
|
|
59
|
+
* @param plainKey - The plain text API key
|
|
60
|
+
* @param hashedKey - The hashed key from database
|
|
61
|
+
* @returns True if keys match, false otherwise
|
|
62
|
+
*/
|
|
63
|
+
async compareKey(plainKey, hashedKey) {
|
|
64
|
+
return bcrypt.compare(plainKey, hashedKey);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
exports.EncryptionService = EncryptionService;
|
|
68
|
+
exports.EncryptionService = EncryptionService = __decorate([
|
|
69
|
+
(0, common_1.Injectable)()
|
|
70
|
+
], EncryptionService);
|