nestjs-apikey-module 0.0.1

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.
Files changed (57) hide show
  1. package/README.md +1 -0
  2. package/dist/api-key.module.d.ts +6 -0
  3. package/dist/api-key.module.js +57 -0
  4. package/dist/api-key.module.js.map +1 -0
  5. package/dist/config/enum.d.ts +5 -0
  6. package/dist/config/enum.js +10 -0
  7. package/dist/config/enum.js.map +1 -0
  8. package/dist/constants/index.d.ts +3 -0
  9. package/dist/constants/index.js +7 -0
  10. package/dist/constants/index.js.map +1 -0
  11. package/dist/decorators/api-key-actions.decorator.d.ts +2 -0
  12. package/dist/decorators/api-key-actions.decorator.js +8 -0
  13. package/dist/decorators/api-key-actions.decorator.js.map +1 -0
  14. package/dist/decorators/api-key-session.decorator.d.ts +1 -0
  15. package/dist/decorators/api-key-session.decorator.js +9 -0
  16. package/dist/decorators/api-key-session.decorator.js.map +1 -0
  17. package/dist/entities/api-key-action.entity.d.ts +7 -0
  18. package/dist/entities/api-key-action.entity.js +41 -0
  19. package/dist/entities/api-key-action.entity.js.map +1 -0
  20. package/dist/entities/api-key.entity.d.ts +17 -0
  21. package/dist/entities/api-key.entity.js +82 -0
  22. package/dist/entities/api-key.entity.js.map +1 -0
  23. package/dist/guards/api-key-strategy.guard.d.ts +10 -0
  24. package/dist/guards/api-key-strategy.guard.js +35 -0
  25. package/dist/guards/api-key-strategy.guard.js.map +1 -0
  26. package/dist/guards/api-key.guard.d.ts +9 -0
  27. package/dist/guards/api-key.guard.js +48 -0
  28. package/dist/guards/api-key.guard.js.map +1 -0
  29. package/dist/helpers/api-key-actions.helper.d.ts +2 -0
  30. package/dist/helpers/api-key-actions.helper.js +15 -0
  31. package/dist/helpers/api-key-actions.helper.js.map +1 -0
  32. package/dist/index.d.ts +14 -0
  33. package/dist/index.js +31 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/interfaces/api-key-context.interface.d.ts +5 -0
  36. package/dist/interfaces/api-key-context.interface.js +3 -0
  37. package/dist/interfaces/api-key-context.interface.js.map +1 -0
  38. package/dist/interfaces/api-key.interfaces.d.ts +30 -0
  39. package/dist/interfaces/api-key.interfaces.js +3 -0
  40. package/dist/interfaces/api-key.interfaces.js.map +1 -0
  41. package/dist/services/api-key.service.d.ts +21 -0
  42. package/dist/services/api-key.service.js +171 -0
  43. package/dist/services/api-key.service.js.map +1 -0
  44. package/dist/tasks/api-key-expiry.task.d.ts +13 -0
  45. package/dist/tasks/api-key-expiry.task.js +65 -0
  46. package/dist/tasks/api-key-expiry.task.js.map +1 -0
  47. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  48. package/dist/utils/expiry.util.d.ts +1 -0
  49. package/dist/utils/expiry.util.js +8 -0
  50. package/dist/utils/expiry.util.js.map +1 -0
  51. package/dist/utils/key.util.d.ts +1 -0
  52. package/dist/utils/key.util.js +8 -0
  53. package/dist/utils/key.util.js.map +1 -0
  54. package/dist/utils/secret.util.d.ts +2 -0
  55. package/dist/utils/secret.util.js +13 -0
  56. package/dist/utils/secret.util.js.map +1 -0
  57. package/package.json +63 -0
@@ -0,0 +1,171 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.ApiKeyService = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const typeorm_1 = require("@nestjs/typeorm");
18
+ const typeorm_2 = require("typeorm");
19
+ const bcrypt = require("bcryptjs");
20
+ const api_key_entity_1 = require("../entities/api-key.entity");
21
+ const api_key_action_entity_1 = require("../entities/api-key-action.entity");
22
+ const enum_1 = require("../config/enum");
23
+ const constants_1 = require("../constants");
24
+ const secret_util_1 = require("../utils/secret.util");
25
+ const key_util_1 = require("../utils/key.util");
26
+ const expiry_util_1 = require("../utils/expiry.util");
27
+ let ApiKeyService = class ApiKeyService {
28
+ constructor(apiKeyRepo, apiKeyActionRepo, options) {
29
+ this.apiKeyRepo = apiKeyRepo;
30
+ this.apiKeyActionRepo = apiKeyActionRepo;
31
+ this.options = options;
32
+ }
33
+ async create(data) {
34
+ const keyPrefix = (0, key_util_1.generateKey)(this.options.keyPrefix);
35
+ const secret = (0, secret_util_1.generateSecret)();
36
+ const secretHash = await (0, secret_util_1.hashSecret)(secret, this.options.bcryptSaltRounds);
37
+ const secretLast4 = secret.slice(-4);
38
+ const fullKey = `${keyPrefix}.${secret}`;
39
+ const apiKey = this.apiKeyRepo.create({
40
+ name: data.name,
41
+ keyPrefix,
42
+ secretHash,
43
+ secretLast4,
44
+ status: enum_1.API_KEY_STATUS.ACTIVE,
45
+ expiresAt: data.expiresInDays
46
+ ? (0, expiry_util_1.calculateExpiryDate)(data.expiresInDays)
47
+ : null,
48
+ });
49
+ const saved = await this.apiKeyRepo.save(apiKey);
50
+ const actionEntities = data.actions.map((code) => this.apiKeyActionRepo.create({ actionCode: code, apiKey: saved }));
51
+ await this.apiKeyActionRepo.save(actionEntities);
52
+ return { apikey: fullKey, entity: saved };
53
+ }
54
+ async getById(id) {
55
+ const key = await this.apiKeyRepo.findOne({
56
+ where: { id },
57
+ relations: ["actions"],
58
+ });
59
+ if (!key)
60
+ throw new common_1.NotFoundException("API key not found.");
61
+ return key;
62
+ }
63
+ async getActiveById(id) {
64
+ const key = await this.apiKeyRepo.findOne({
65
+ where: { id },
66
+ relations: ["actions"],
67
+ });
68
+ if (!key)
69
+ throw new common_1.NotFoundException("API key not found.");
70
+ if (key.status !== enum_1.API_KEY_STATUS.ACTIVE) {
71
+ throw new common_1.NotFoundException("API key is not active.");
72
+ }
73
+ if (key.expiresAt && key.expiresAt < new Date()) {
74
+ throw new common_1.NotFoundException("API key has expired.");
75
+ }
76
+ return key;
77
+ }
78
+ async getActiveByKeyPrefix(keyPrefix) {
79
+ const key = await this.apiKeyRepo.findOne({
80
+ where: { keyPrefix },
81
+ relations: ["actions"],
82
+ });
83
+ if (!key)
84
+ throw new common_1.NotFoundException("API key not found.");
85
+ if (key.status !== enum_1.API_KEY_STATUS.ACTIVE) {
86
+ throw new common_1.NotFoundException("API key is not active.");
87
+ }
88
+ if (key.expiresAt && key.expiresAt < new Date()) {
89
+ throw new common_1.NotFoundException("API key has expired.");
90
+ }
91
+ return key;
92
+ }
93
+ async revoke(options) {
94
+ const key = await this.getActiveById(options.id);
95
+ key.status = enum_1.API_KEY_STATUS.REVOKED;
96
+ key.revokedAt = new Date();
97
+ key.revokeReason = options.reason;
98
+ await this.apiKeyRepo.save(key);
99
+ }
100
+ async rotate(id) {
101
+ const key = await this.getActiveById(id);
102
+ const newSecret = (0, secret_util_1.generateSecret)();
103
+ const fullKey = `${key.keyPrefix}.${newSecret}`;
104
+ const secretHash = await (0, secret_util_1.hashSecret)(newSecret, this.options.bcryptSaltRounds);
105
+ const secretLast4 = newSecret.slice(-4);
106
+ key.secretHash = secretHash;
107
+ key.secretLast4 = secretLast4;
108
+ const saved = await this.apiKeyRepo.save(key);
109
+ return {
110
+ entity: saved,
111
+ apikey: fullKey,
112
+ };
113
+ }
114
+ async validate(options) {
115
+ const { value, ip } = options;
116
+ const dotIndex = value.indexOf(".");
117
+ if (dotIndex === -1)
118
+ throw new common_1.UnauthorizedException("Api key has invalid format.");
119
+ const prefix = value.substring(0, dotIndex);
120
+ const secret = value.substring(dotIndex + 1);
121
+ const apiKey = await this.getActiveByKeyPrefix(prefix);
122
+ const isValid = await bcrypt.compare(secret, apiKey.secretHash);
123
+ if (!isValid)
124
+ throw new common_1.UnauthorizedException("Api key is invalid.");
125
+ this.apiKeyRepo
126
+ .update(apiKey.id, { lastUsedAt: new Date(), lastUsedIp: ip ?? null })
127
+ .catch(() => null);
128
+ return apiKey;
129
+ }
130
+ async remove(id) {
131
+ await this.apiKeyRepo.delete(id);
132
+ }
133
+ async removeByKeyPrefix(keyPrefix) {
134
+ await this.apiKeyRepo.delete({ keyPrefix });
135
+ }
136
+ async expireKeys() {
137
+ await this.apiKeyRepo
138
+ .createQueryBuilder()
139
+ .update(api_key_entity_1.ApiKeyEntity)
140
+ .set({ status: enum_1.API_KEY_STATUS.EXPIRED })
141
+ .where("status = :activeStatus", { activeStatus: enum_1.API_KEY_STATUS.ACTIVE })
142
+ .andWhere("expires_at IS NOT NULL AND expires_at < :now", {
143
+ now: new Date(),
144
+ })
145
+ .execute();
146
+ }
147
+ async expireByKeyPrefix(keyPrefix) {
148
+ await this.apiKeyRepo
149
+ .createQueryBuilder()
150
+ .update(api_key_entity_1.ApiKeyEntity)
151
+ .set({ status: enum_1.API_KEY_STATUS.EXPIRED })
152
+ .where("key_prefix = :keyPrefix", { keyPrefix })
153
+ .andWhere("status = :activeStatus", {
154
+ activeStatus: enum_1.API_KEY_STATUS.ACTIVE,
155
+ })
156
+ .andWhere("expires_at IS NOT NULL AND expires_at < :now", {
157
+ now: new Date(),
158
+ })
159
+ .execute();
160
+ }
161
+ };
162
+ exports.ApiKeyService = ApiKeyService;
163
+ exports.ApiKeyService = ApiKeyService = __decorate([
164
+ (0, common_1.Injectable)(),
165
+ __param(0, (0, typeorm_1.InjectRepository)(api_key_entity_1.ApiKeyEntity)),
166
+ __param(1, (0, typeorm_1.InjectRepository)(api_key_action_entity_1.ApiKeyActionEntity)),
167
+ __param(2, (0, common_1.Inject)(constants_1.API_KEY_MODULE_OPTIONS)),
168
+ __metadata("design:paramtypes", [typeorm_2.Repository,
169
+ typeorm_2.Repository, Object])
170
+ ], ApiKeyService);
171
+ //# sourceMappingURL=api-key.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-key.service.js","sourceRoot":"","sources":["../../libs/nestjs-apikey-module/src/services/api-key.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { SchedulerRegistry } from "@nestjs/schedule";
2
+ import { Repository } from "typeorm";
3
+ import { ApiKeyEntity } from "../entities/api-key.entity";
4
+ import { IApiKeyModuleOptions } from "../interfaces/api-key.interfaces";
5
+ export declare class ApiKeyExpiryTask {
6
+ private readonly apiKeyRepo;
7
+ private readonly options;
8
+ private readonly schedulerRegistry;
9
+ private readonly logger;
10
+ constructor(apiKeyRepo: Repository<ApiKeyEntity>, options: IApiKeyModuleOptions, schedulerRegistry: SchedulerRegistry);
11
+ private registerJob;
12
+ markExpiredKeys(): Promise<void>;
13
+ }
@@ -0,0 +1,65 @@
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 ApiKeyExpiryTask_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.ApiKeyExpiryTask = void 0;
17
+ const common_1 = require("@nestjs/common");
18
+ const schedule_1 = require("@nestjs/schedule");
19
+ const cron_1 = require("cron");
20
+ const typeorm_1 = require("@nestjs/typeorm");
21
+ const typeorm_2 = require("typeorm");
22
+ const api_key_entity_1 = require("../entities/api-key.entity");
23
+ const enum_1 = require("../config/enum");
24
+ const constants_1 = require("../constants");
25
+ const DEFAULT_CRON = "0 0 * * *";
26
+ const JOB_NAME = "api-key-expiry";
27
+ let ApiKeyExpiryTask = ApiKeyExpiryTask_1 = class ApiKeyExpiryTask {
28
+ constructor(apiKeyRepo, options, schedulerRegistry) {
29
+ this.apiKeyRepo = apiKeyRepo;
30
+ this.options = options;
31
+ this.schedulerRegistry = schedulerRegistry;
32
+ this.logger = new common_1.Logger(ApiKeyExpiryTask_1.name);
33
+ this.registerJob();
34
+ }
35
+ registerJob() {
36
+ if (this.options.expiryCron === false)
37
+ return;
38
+ const expression = this.options.expiryCron ?? DEFAULT_CRON;
39
+ const job = new cron_1.CronJob(expression, () => this.markExpiredKeys());
40
+ this.schedulerRegistry.addCronJob(JOB_NAME, job);
41
+ job.start();
42
+ this.logger.log(`API key expiry job scheduled: "${expression}"`);
43
+ }
44
+ async markExpiredKeys() {
45
+ const now = new Date();
46
+ const result = await this.apiKeyRepo.update({
47
+ status: enum_1.API_KEY_STATUS.ACTIVE,
48
+ expiresAt: (0, typeorm_2.LessThan)(now),
49
+ }, {
50
+ status: enum_1.API_KEY_STATUS.EXPIRED,
51
+ });
52
+ const affected = result.affected ?? 0;
53
+ if (affected > 0) {
54
+ this.logger.log(`Marked ${affected} API key(s) as EXPIRED.`);
55
+ }
56
+ }
57
+ };
58
+ exports.ApiKeyExpiryTask = ApiKeyExpiryTask;
59
+ exports.ApiKeyExpiryTask = ApiKeyExpiryTask = ApiKeyExpiryTask_1 = __decorate([
60
+ (0, common_1.Injectable)(),
61
+ __param(0, (0, typeorm_1.InjectRepository)(api_key_entity_1.ApiKeyEntity)),
62
+ __param(1, (0, common_1.Inject)(constants_1.API_KEY_MODULE_OPTIONS)),
63
+ __metadata("design:paramtypes", [typeorm_2.Repository, Object, schedule_1.SchedulerRegistry])
64
+ ], ApiKeyExpiryTask);
65
+ //# sourceMappingURL=api-key-expiry.task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-key-expiry.task.js","sourceRoot":"","sources":["../../libs/nestjs-apikey-module/src/tasks/api-key-expiry.task.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAA4D;AAC5D,+CAAqD;AACrD,+BAA+B;AAC/B,6CAAmD;AACnD,qCAA+C;AAC/C,+DAA0D;AAC1D,yCAAgD;AAEhD,4CAAsD;AAEtD,MAAM,YAAY,GAAG,WAAW,CAAC;AACjC,MAAM,QAAQ,GAAG,gBAAgB,CAAC;AAG3B,IAAM,gBAAgB,wBAAtB,MAAM,gBAAgB;IAG3B,YAEE,UAAqD,EAErD,OAA8C,EAC7B,iBAAoC;QAHpC,eAAU,GAAV,UAAU,CAA0B;QAEpC,YAAO,GAAP,OAAO,CAAsB;QAC7B,sBAAiB,GAAjB,iBAAiB,CAAmB;QAPtC,WAAM,GAAG,IAAI,eAAM,CAAC,kBAAgB,CAAC,IAAI,CAAC,CAAC;QAS1D,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAOO,WAAW;QACjB,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,KAAK,KAAK;YAAE,OAAO;QAE9C,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,YAAY,CAAC;QAE3D,MAAM,GAAG,GAAG,IAAI,cAAO,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC;QAClE,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACjD,GAAG,CAAC,KAAK,EAAE,CAAC;QAEZ,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,kCAAkC,UAAU,GAAG,CAAC,CAAC;IACnE,CAAC;IAOD,KAAK,CAAC,eAAe;QACnB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QAEvB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CACzC;YACE,MAAM,EAAE,qBAAc,CAAC,MAAM;YAC7B,SAAS,EAAE,IAAA,kBAAQ,EAAC,GAAG,CAAC;SACzB,EACD;YACE,MAAM,EAAE,qBAAc,CAAC,OAAO;SAC/B,CACF,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;QACtC,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;YACjB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,QAAQ,yBAAyB,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;CACF,CAAA;AArDY,4CAAgB;2BAAhB,gBAAgB;IAD5B,IAAA,mBAAU,GAAE;IAKR,WAAA,IAAA,0BAAgB,EAAC,6BAAY,CAAC,CAAA;IAE9B,WAAA,IAAA,eAAM,EAAC,kCAAsB,CAAC,CAAA;qCADF,oBAAU,UAGH,4BAAiB;GAR5C,gBAAgB,CAqD5B"}