authenik8-core 0.1.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.
Files changed (98) hide show
  1. package/.env +2 -0
  2. package/README.md +93 -0
  3. package/authenik8-core-0.1.0.tgz +0 -0
  4. package/dist/auth/guestModeService.d.ts +3 -0
  5. package/dist/auth/guestModeService.d.ts.map +1 -0
  6. package/dist/auth/guestModeService.js +24 -0
  7. package/dist/auth/guestModeService.js.map +1 -0
  8. package/dist/auth/jwtAuth.d.ts +28 -0
  9. package/dist/auth/jwtAuth.d.ts.map +1 -0
  10. package/dist/auth/jwtAuth.js +67 -0
  11. package/dist/auth/jwtAuth.js.map +1 -0
  12. package/dist/auth/refreshService.d.ts +41 -0
  13. package/dist/auth/refreshService.d.ts.map +1 -0
  14. package/dist/auth/refreshService.js +77 -0
  15. package/dist/auth/refreshService.js.map +1 -0
  16. package/dist/creatAuthenik8.d.ts +2 -0
  17. package/dist/creatAuthenik8.d.ts.map +1 -0
  18. package/dist/creatAuthenik8.js +3 -0
  19. package/dist/creatAuthenik8.js.map +1 -0
  20. package/dist/createAuthenik8.d.ts +4 -0
  21. package/dist/createAuthenik8.d.ts.map +1 -0
  22. package/dist/createAuthenik8.js +58 -0
  23. package/dist/createAuthenik8.js.map +1 -0
  24. package/dist/index.d.ts +2 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +6 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/middleware/adminService.d.ts +4 -0
  29. package/dist/middleware/adminService.d.ts.map +1 -0
  30. package/dist/middleware/adminService.js +40 -0
  31. package/dist/middleware/adminService.js.map +1 -0
  32. package/dist/redis/redisService.d.ts +26 -0
  33. package/dist/redis/redisService.d.ts.map +1 -0
  34. package/dist/redis/redisService.js +104 -0
  35. package/dist/redis/redisService.js.map +1 -0
  36. package/dist/security/ipService.d.ts +36 -0
  37. package/dist/security/ipService.d.ts.map +1 -0
  38. package/dist/security/ipService.js +160 -0
  39. package/dist/security/ipService.js.map +1 -0
  40. package/dist/security/limiter.d.ts +5 -0
  41. package/dist/security/limiter.d.ts.map +1 -0
  42. package/dist/security/limiter.js +93 -0
  43. package/dist/security/limiter.js.map +1 -0
  44. package/dist/storage/RedisTokenStore.d.ts +21 -0
  45. package/dist/storage/RedisTokenStore.d.ts.map +1 -0
  46. package/dist/storage/RedisTokenStore.js +86 -0
  47. package/dist/storage/RedisTokenStore.js.map +1 -0
  48. package/dist/storage/userStorage.d.ts +7 -0
  49. package/dist/storage/userStorage.d.ts.map +1 -0
  50. package/dist/storage/userStorage.js +18 -0
  51. package/dist/storage/userStorage.js.map +1 -0
  52. package/dist/tests/full.intergration.test.d.ts +2 -0
  53. package/dist/tests/full.intergration.test.d.ts.map +1 -0
  54. package/dist/tests/full.intergration.test.js +79 -0
  55. package/dist/tests/full.intergration.test.js.map +1 -0
  56. package/dist/tests/testApp.d.ts +7 -0
  57. package/dist/tests/testApp.d.ts.map +1 -0
  58. package/dist/tests/testApp.js +53 -0
  59. package/dist/tests/testApp.js.map +1 -0
  60. package/dist/types/admin.d.ts +6 -0
  61. package/dist/types/admin.d.ts.map +1 -0
  62. package/dist/types/admin.js +3 -0
  63. package/dist/types/admin.js.map +1 -0
  64. package/dist/types/config.d.ts +9 -0
  65. package/dist/types/config.d.ts.map +1 -0
  66. package/dist/types/config.js +3 -0
  67. package/dist/types/config.js.map +1 -0
  68. package/dist/types/public.d.ts +17 -0
  69. package/dist/types/public.d.ts.map +1 -0
  70. package/dist/types/public.js +3 -0
  71. package/dist/types/public.js.map +1 -0
  72. package/dist/types/storage.d.ts +14 -0
  73. package/dist/types/storage.d.ts.map +1 -0
  74. package/dist/types/storage.js +3 -0
  75. package/dist/types/storage.js.map +1 -0
  76. package/dump.rdb +0 -0
  77. package/jest.config.js +11 -0
  78. package/package.json +56 -0
  79. package/src/1 +22 -0
  80. package/src/auth/guestModeService.ts +31 -0
  81. package/src/auth/jwtAuth.ts +99 -0
  82. package/src/auth/refreshService.ts +134 -0
  83. package/src/creatAuthenik8.ts +0 -0
  84. package/src/createAuthenik8.ts +66 -0
  85. package/src/index.ts +1 -0
  86. package/src/middleware/adminService.ts +50 -0
  87. package/src/redis/redisService.ts +137 -0
  88. package/src/security/ipService.ts +180 -0
  89. package/src/security/limiter.ts +116 -0
  90. package/src/storage/RedisTokenStore.ts +99 -0
  91. package/src/storage/userStorage.ts +16 -0
  92. package/src/tests/full.intergration.test.ts +100 -0
  93. package/src/tests/testApp.ts +56 -0
  94. package/src/types/admin.ts +7 -0
  95. package/src/types/config.ts +11 -0
  96. package/src/types/public.ts +22 -0
  97. package/src/types/storage.ts +15 -0
  98. package/tsconfig.json +51 -0
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ var _a, _b;
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.initializeRedisClient = exports.setupRedis = void 0;
8
+ const dotenv_1 = __importDefault(require("dotenv"));
9
+ const connect_redis_1 = require("connect-redis");
10
+ const ioredis_1 = __importDefault(require("ioredis"));
11
+ dotenv_1.default.config();
12
+ let redisClientInstance = null;
13
+ let redisStoreInstance = null;
14
+ const DEFAULT_REDIS_CONFIG = {
15
+ host: (_a = process.env.REDIS_HOST) !== null && _a !== void 0 ? _a : "redis",
16
+ port: Number((_b = process.env.REDIS_PORT) !== null && _b !== void 0 ? _b : "6379"),
17
+ maxRetriesPerRequest: 10,
18
+ connectTimeout: 5000
19
+ };
20
+ const DEFAULT_STORE_OPTIONS = {
21
+ prefix: "session",
22
+ ttl: 86400
23
+ };
24
+ const validateRedisConfig = (config) => {
25
+ if (!config.url && !config.host) {
26
+ throw new Error("Redis configuration requires either URL or host/port");
27
+ }
28
+ if (config.url && !config.url.startsWith("redis://") && !config.url.startsWith("rediss://")) {
29
+ throw new Error("Redis URL must use 'redis://' protocol");
30
+ }
31
+ };
32
+ const getRedisConfig = (options) => {
33
+ const port = (options === null || options === void 0 ? void 0 : options.port) ?
34
+ Number(options.port) :
35
+ process.env.REDIS_PORT ? Number(process.env.REDIS_PORT) :
36
+ Number(DEFAULT_REDIS_CONFIG.port);
37
+ const config = {
38
+ ...DEFAULT_REDIS_CONFIG,
39
+ host: (options === null || options === void 0 ? void 0 : options.host) || process.env.REDIS_HOST || DEFAULT_REDIS_CONFIG.host,
40
+ port: port,
41
+ password: (options === null || options === void 0 ? void 0 : options.password) || process.env.REDIS_PASSWORD || undefined,
42
+ ...options
43
+ };
44
+ validateRedisConfig(config);
45
+ return config;
46
+ };
47
+ const setupRedis = async (options) => {
48
+ try {
49
+ const config = getRedisConfig(options === null || options === void 0 ? void 0 : options.redisConfig);
50
+ const storeOptions = { ...DEFAULT_STORE_OPTIONS, ...options === null || options === void 0 ? void 0 : options.storeOptions };
51
+ const redisClient = new ioredis_1.default({
52
+ host: config.host,
53
+ port: Number(config.port),
54
+ connectTimeout: config.connectTimeout,
55
+ password: config.password,
56
+ retryStrategy: (times) => Math.min(times * 50, 2000),
57
+ maxRetriesPerRequest: config.maxRetriesPerRequest
58
+ });
59
+ await new Promise((resolve, reject) => {
60
+ redisClient.once("ready", async () => {
61
+ try {
62
+ const pong = await redisClient.ping();
63
+ console.log("Redis ping response:", pong);
64
+ resolve();
65
+ }
66
+ catch (err) {
67
+ reject(err);
68
+ }
69
+ });
70
+ redisClient.once("error", (err) => {
71
+ reject(err);
72
+ });
73
+ });
74
+ const redisStore = new connect_redis_1.RedisStore({
75
+ client: redisClient,
76
+ prefix: storeOptions.prefix,
77
+ ttl: storeOptions.ttl
78
+ });
79
+ redisClient.on("error", (err) => {
80
+ console.error("Redis client error:", err);
81
+ });
82
+ redisClient.on("ready", () => {
83
+ console.log("Redis client is ready");
84
+ });
85
+ redisClient.on("reconnecting", () => {
86
+ console.log("Redis client reconnecting...");
87
+ });
88
+ return { redisClient, redisStore };
89
+ }
90
+ catch (error) {
91
+ console.error("Redis setup failed:", error);
92
+ throw error;
93
+ }
94
+ };
95
+ exports.setupRedis = setupRedis;
96
+ const initializeRedisClient = async () => {
97
+ if (!redisClientInstance) {
98
+ const { redisClient } = await setupRedis();
99
+ redisClientInstance = redisClient;
100
+ }
101
+ return redisClientInstance;
102
+ };
103
+ exports.initializeRedisClient = initializeRedisClient;
104
+ //# sourceMappingURL=redisService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redisService.js","sourceRoot":"","sources":["../../src/redis/redisService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import Redis from "ioredis";
2
+ import type { StringValue } from "ms";
3
+ import { RequestHandler } from "express";
4
+ import { Request, Response, NextFunction } from "express";
5
+ export interface SecurityOptions {
6
+ redisClient?: Redis;
7
+ jwtSecret?: string;
8
+ jwtExpiry?: StringValue;
9
+ rateLimitPoints?: number;
10
+ rateLimitDuration?: number;
11
+ rateLimitBlock?: number;
12
+ rateLimiterEnabled?: boolean;
13
+ enableWhitelist?: boolean;
14
+ enableRateLimiter?: boolean;
15
+ enableHelmet?: boolean;
16
+ whiteListEnabled?: boolean;
17
+ helmetEnabled?: boolean;
18
+ }
19
+ export declare class SecurityModule {
20
+ private redisClient;
21
+ private jwtSecret;
22
+ private jwtExpiry;
23
+ private rateLimiter?;
24
+ private whiteListEnabled;
25
+ private helmetEnabled;
26
+ private rateLimiterEnabled;
27
+ constructor(options?: SecurityOptions);
28
+ isAllowed(ip: string): Promise<boolean>;
29
+ addIP(ipOrCIDR: string, ttl?: number): Promise<void>;
30
+ removeIP(ipOrCIDR: string): Promise<void>;
31
+ listIPs(): Promise<string[]>;
32
+ whiteListMiddleware(): (req: Request, res: Response, next: NextFunction) => Promise<void>;
33
+ rateLimiterMiddleware(): (req: Request, res: Response, next: NextFunction) => void;
34
+ helmetMiddleware(): RequestHandler;
35
+ }
36
+ //# sourceMappingURL=ipService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ipService.d.ts","sourceRoot":"","sources":["../../src/security/ipService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,SAAS,CAAC;AAC5B,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,IAAI,CAAA;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEzC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAwB1D,MAAM,WAAW,eAAe;IAC/B,WAAW,CAAC,EAAE,KAAK,CAAC;IACrB,SAAS,CAAC,EAAC,MAAM,CAAC;IAClB,SAAS,CAAC,EAAC,WAAW,CAAC;IACvB,eAAe,CAAC,EAAC,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAC,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAC,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAC,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAC,OAAO,CAAC;IACzB,iBAAiB,CAAC,EAAC,OAAO,CAAC;IAC3B,YAAY,CAAC,EAAC,OAAO,CAAC;IACtB,gBAAgB,CAAC,EAAC,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAC,OAAO,CAAC;CACtB;AAED,qBAAa,cAAc;IAC3B,OAAO,CAAC,WAAW,CAAO;IAC1B,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,WAAW,CAAC,CAAmB;IACvC,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,kBAAkB,CAAS;gBAGvB,OAAO,GAAE,eAAoB;IAoCnC,SAAS,CAAC,EAAE,EAAC,MAAM,GAAE,OAAO,CAAC,OAAO,CAAC;IA4BrC,KAAK,CAAC,QAAQ,EAAC,MAAM,EAAC,GAAG,GAAC,MAA6B;IAIvD,QAAQ,CAAC,QAAQ,EAAC,MAAM;IAIxB,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIlC,mBAAmB,KACN,KAAK,OAAO,EAAC,KAAI,QAAQ,EAAE,MAAK,YAAY;IASzD,qBAAqB,KACb,KAAI,OAAO,EAAE,KAAI,QAAQ,EAAE,MAAK,YAAY;IAOpD,gBAAgB,IAAG,cAAc;CA4BhC"}
@@ -0,0 +1,160 @@
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 __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.SecurityModule = void 0;
40
+ const helmet_1 = __importDefault(require("helmet"));
41
+ const ioredis_1 = __importDefault(require("ioredis"));
42
+ const rate_limiter_flexible_1 = require("rate-limiter-flexible");
43
+ const WHITELIST_KEY = "whitelist:ips";
44
+ const IP_EXPIRATION_SECONDS = 7 * 24 * 60 * 60;
45
+ const DEFAULT_JWT_EXPIRY = "1h";
46
+ const JWT_SECRET = process.env.JWT_SECRET || "Boo";
47
+ const EXPIRY = "1h";
48
+ class SecurityModule {
49
+ constructor(options = {}) {
50
+ var _a, _b, _c;
51
+ this.jwtSecret = options.jwtSecret || process.env.JWT_SECRET || "Boo";
52
+ this.jwtExpiry = options.jwtExpiry || DEFAULT_JWT_EXPIRY;
53
+ this.whiteListEnabled = (_a = options.whiteListEnabled) !== null && _a !== void 0 ? _a : true;
54
+ this.helmetEnabled = (_b = options.helmetEnabled) !== null && _b !== void 0 ? _b : true;
55
+ this.rateLimiterEnabled = (_c = options.rateLimiterEnabled) !== null && _c !== void 0 ? _c : true;
56
+ this.redisClient = options.redisClient || new ioredis_1.default({
57
+ host: process.env.REDIS_HOST || "127.0.0.1",
58
+ port: Number(process.env.REDIS_PORT || 6379),
59
+ enableOfflineQueue: false,
60
+ retryStrategy: (times) => Math.min(times * 50, 2000),
61
+ maxRetriesPerRequest: 10,
62
+ });
63
+ if (this.rateLimiterEnabled) {
64
+ this.rateLimiter = new rate_limiter_flexible_1.RateLimiterRedis({
65
+ storeClient: this.redisClient,
66
+ keyPrefix: "rate_limit",
67
+ points: options.rateLimitPoints || 100,
68
+ duration: options.rateLimitDuration || 60,
69
+ blockDuration: options.rateLimitBlock || 300,
70
+ });
71
+ }
72
+ this.redisClient.on("error", (err) => console.error("Security Redis error:", err));
73
+ this.redisClient.on("connect", () => {
74
+ console.log("SecurityRedis Connected to:", this.redisClient.options.host);
75
+ });
76
+ }
77
+ async isAllowed(ip) {
78
+ if (!this.whiteListEnabled)
79
+ return true;
80
+ try {
81
+ const exists = await this.redisClient.sismember(WHITELIST_KEY, ip);
82
+ if (exists === 1)
83
+ return true;
84
+ if (ip === "::1" || ip === "127.0.0.1")
85
+ return true;
86
+ const entries = await this.redisClient.smembers(WHITELIST_KEY);
87
+ for (const entry of entries) {
88
+ if (entry.includes("/")) {
89
+ const CIDR = (await Promise.resolve().then(() => __importStar(require("ip-cidr")))).default;
90
+ if (new CIDR(entry).contains(ip))
91
+ return true;
92
+ }
93
+ }
94
+ return false;
95
+ }
96
+ catch (err) {
97
+ console.error("whitelist check error:", err);
98
+ return false;
99
+ }
100
+ }
101
+ async addIP(ipOrCIDR, ttl = IP_EXPIRATION_SECONDS) {
102
+ await this.redisClient.sadd(WHITELIST_KEY, ipOrCIDR);
103
+ await this.redisClient.expire(WHITELIST_KEY, ttl);
104
+ }
105
+ async removeIP(ipOrCIDR) {
106
+ await this.redisClient.srem(WHITELIST_KEY, ipOrCIDR);
107
+ }
108
+ async listIPs() {
109
+ return await this.redisClient.smembers(WHITELIST_KEY);
110
+ }
111
+ whiteListMiddleware() {
112
+ return async (req, res, next) => {
113
+ var _a, _b;
114
+ if (!this.whiteListEnabled)
115
+ return next();
116
+ const clientIP = ((_b = (_a = req.headers["x-forwarded-for"]) === null || _a === void 0 ? void 0 : _a.toString().split(",")[0]) === null || _b === void 0 ? void 0 : _b.trim()) || req.ip;
117
+ if (await this.isAllowed(clientIP))
118
+ return next();
119
+ res.status(403).json({ error: "Access denied" });
120
+ };
121
+ }
122
+ rateLimiterMiddleware() {
123
+ return (req, res, next) => {
124
+ if (!this.rateLimiter || !this.rateLimiterEnabled)
125
+ return next();
126
+ const ip = req.ip || req.socket.remoteAddress || "unknown";
127
+ this.rateLimiter.consume(ip).then(() => next()).catch(() => res.status(429).send("Too many Requests"));
128
+ };
129
+ }
130
+ helmetMiddleware() {
131
+ if (!this.helmetEnabled) {
132
+ return (req, res, next) => next();
133
+ }
134
+ const helmetDirectives = {
135
+ defaultSrc: ["'self'"],
136
+ scriptSrc: ["'self'", "'unsafe-inline'", "trusted-cdn.com"],
137
+ styleSrc: ["'self'"],
138
+ imgSrc: ["'self'", "data:", "trusted-cdn.com"],
139
+ fontSrc: ["'self'", "trusted-cdn.com"],
140
+ connectSrc: ["'self'", "api.trusted-domain.com"],
141
+ frameSrc: ["'none'"],
142
+ objectSrc: ["'none'"],
143
+ upgradeInsecureRequests: [],
144
+ reportUri: "/csp-violation-report",
145
+ };
146
+ return (0, helmet_1.default)({
147
+ contentSecurityPolicy: {
148
+ directives: helmetDirectives, reportOnly: process.env.NODE_ENV !== "production"
149
+ },
150
+ hsts: { maxAge: 315366000,
151
+ includeSubDomains: true, preload: true },
152
+ xxsFilter: true,
153
+ noSniff: true,
154
+ frameguard: { action: "deny" },
155
+ referrerPolicy: { policy: "same-origin" },
156
+ });
157
+ }
158
+ }
159
+ exports.SecurityModule = SecurityModule;
160
+ //# sourceMappingURL=ipService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ipService.js","sourceRoot":"","sources":["../../src/security/ipService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { Request, Response, NextFunction } from "express";
2
+ export declare const initializeRateLimiter: () => Promise<void>;
3
+ export declare const OTPLimiterMiddleware: (req: Request, res: Response, next: NextFunction) => Promise<void>;
4
+ export declare const LoginLimiterMiddleware: () => (req: Request, res: Response, next: NextFunction) => Promise<void>;
5
+ //# sourceMappingURL=limiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limiter.d.ts","sourceRoot":"","sources":["../../src/security/limiter.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAC,MAAM,SAAS,CAAA;AAoDvD,eAAO,MAAM,qBAAqB,qBAGjC,CAAC;AAwDF,eAAO,MAAM,oBAAoB,QAlDhB,OAAO,OAAM,QAAQ,QAAO,YAAY,KAAG,OAAO,CAAC,IAAI,CAkDI,CAAC;AAC7E,eAAO,MAAM,sBAAsB,cAnDlB,OAAO,OAAM,QAAQ,QAAO,YAAY,KAAG,OAAO,CAAC,IAAI,CAmDe,CAAC"}
@@ -0,0 +1,93 @@
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.LoginLimiterMiddleware = exports.OTPLimiterMiddleware = exports.initializeRateLimiter = void 0;
7
+ const dotenv_1 = __importDefault(require("dotenv"));
8
+ const redisService_1 = require("../redis/redisService");
9
+ dotenv_1.default.config();
10
+ class TokenBucket {
11
+ constructor(redisClient) {
12
+ this.redis = redisClient;
13
+ }
14
+ async consume(key, capacity, refillRate) {
15
+ var _a, _b;
16
+ const now = Date.now();
17
+ const results = await this.redis
18
+ .pipeline()
19
+ .hgetall(`rate_limit:${key}`)
20
+ .exec();
21
+ const data = (_b = (_a = results === null || results === void 0 ? void 0 : results[0]) === null || _a === void 0 ? void 0 : _a[1]) !== null && _b !== void 0 ? _b : {};
22
+ const bucket = data
23
+ || {};
24
+ const currentToken = parseFloat(bucket.tokens || capacity.toString());
25
+ const lastRefill = parseFloat(bucket.lastRefill || now.toString());
26
+ const timeElapsed = (now - lastRefill) / 1000;
27
+ const newToken = Math.min(capacity, currentToken + (timeElapsed * refillRate));
28
+ if (newToken < 1) {
29
+ return {
30
+ allowed: false,
31
+ remaining: Math.floor(newToken),
32
+ retryAfter: Math.ceil((1 - newToken) / refillRate)
33
+ };
34
+ }
35
+ await this.redis.hset(`rate_limit:${key}`, {
36
+ tokens: (newToken - 1).toString(),
37
+ lastRefill: now.toString()
38
+ });
39
+ this.redis.expire(`rate_limit:${key}`, 3600);
40
+ return { allowed: true, remaining: Math.floor(newToken - 1) };
41
+ }
42
+ }
43
+ let tokenBucket;
44
+ const initializeRateLimiter = async () => {
45
+ const redisClient = (await (0, redisService_1.setupRedis)()).redisClient;
46
+ tokenBucket = new TokenBucket(redisClient);
47
+ };
48
+ exports.initializeRateLimiter = initializeRateLimiter;
49
+ const createRatelimiter = (config) => {
50
+ return async (req, res, next) => {
51
+ const key = config.keyGenerator(req);
52
+ const { allowed, remaining, retryAfter } = await tokenBucket.consume(key, config.capacity, config.refillRate);
53
+ res.set({
54
+ "X-RateLimit-Limit": config.capacity.toString(),
55
+ "X-RateLimit-Remaining": remaining.toString(),
56
+ ...(!allowed && { "Retry-After": (retryAfter === null || retryAfter === void 0 ? void 0 : retryAfter.toString()) || "1" })
57
+ });
58
+ if (allowed) {
59
+ return next();
60
+ }
61
+ else {
62
+ res.status(429).json({
63
+ error: `Too many requests`
64
+ });
65
+ }
66
+ };
67
+ };
68
+ const RATE_LIMIT_CONFIGS = {
69
+ OTP: {
70
+ keyPrefix: "otp_limiter",
71
+ refillRate: 0.1,
72
+ capacity: 3,
73
+ keyGenerator: (req) => {
74
+ var _a;
75
+ const email = (_a = req.body) === null || _a === void 0 ? void 0 : _a.email;
76
+ return email || req.ip || "unknown";
77
+ }
78
+ },
79
+ LOGIN: {
80
+ keyPrefix: "login_limiter",
81
+ capacity: 10,
82
+ refillRate: 2,
83
+ keyGenerator: (req) => req.ip || "unknown"
84
+ }
85
+ };
86
+ (0, exports.initializeRateLimiter)().catch((err) => {
87
+ console.error("Failed to initialize rate limiters:", err);
88
+ process.exit(1);
89
+ });
90
+ exports.OTPLimiterMiddleware = createRatelimiter(RATE_LIMIT_CONFIGS.OTP);
91
+ const LoginLimiterMiddleware = () => createRatelimiter(RATE_LIMIT_CONFIGS.LOGIN);
92
+ exports.LoginLimiterMiddleware = LoginLimiterMiddleware;
93
+ //# sourceMappingURL=limiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limiter.js","sourceRoot":"","sources":["../../src/security/limiter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { Redis } from "ioredis";
2
+ export declare class RedisTokenStore {
3
+ private redis;
4
+ private debug;
5
+ private prefix;
6
+ constructor(redis: Redis, debug?: boolean);
7
+ private key;
8
+ private log;
9
+ storeRefreshToken(token: string, userId: string, ttl: number): Promise<void>;
10
+ getRefreshToken(token: string): Promise<string | null>;
11
+ deleteRefreshToken(token: string): Promise<void>;
12
+ blacklistToken(token: string, ttl: number): Promise<void>;
13
+ isBlacklisted(token: string): Promise<boolean>;
14
+ incrementRateLimit(ip: string, ttl: number): Promise<number>;
15
+ addToWhitelist(ip: string): Promise<void>;
16
+ removeFromWhitelist(ip: string): Promise<void>;
17
+ isWhitelisted(ip: string): Promise<boolean>;
18
+ set(key: string, value: string, expiry?: number): Promise<void>;
19
+ get(key: string): Promise<string | null>;
20
+ }
21
+ //# sourceMappingURL=RedisTokenStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RedisTokenStore.d.ts","sourceRoot":"","sources":["../../src/storage/RedisTokenStore.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,qBAAa,eAAe;IAGd,OAAO,CAAC,KAAK;IAAQ,OAAO,CAAC,KAAK;IAF/C,OAAO,CAAC,MAAM,CAAa;gBAEN,KAAK,EAAE,KAAK,EAAS,KAAK,UAAQ;IAGtD,OAAO,CAAC,GAAG;IAIb,OAAO,CAAC,GAAG;IAKJ,iBAAiB,CAAC,KAAK,EAAC,MAAM,EAAC,MAAM,EAAC,MAAM,EAAC,GAAG,EAAC,MAAM;IAOxD,eAAe,CAAC,KAAK,EAAC,MAAM;IAO5B,kBAAkB,CAAC,KAAK,EAAC,MAAM;IAO/B,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;IAMvC,aAAa,CAAC,KAAK,EAAE,MAAM;IAQ3B,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;IAa1C,cAAc,CAAC,EAAE,EAAE,MAAM;IAMzB,mBAAmB,CAAC,EAAE,EAAE,MAAM;IAM9B,aAAa,CAAC,EAAE,EAAE,MAAM;IAM1B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW7D,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAG/C"}
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RedisTokenStore = void 0;
4
+ class RedisTokenStore {
5
+ constructor(redis, debug = false) {
6
+ this.redis = redis;
7
+ this.debug = debug;
8
+ this.prefix = "auth:v1";
9
+ }
10
+ key(...parts) {
11
+ return `${this.prefix}:${parts.join(":")}`;
12
+ }
13
+ log(action, key, value) {
14
+ if (this.debug) {
15
+ console.log(`[Redis ${action}]`, { key, value });
16
+ }
17
+ }
18
+ async storeRefreshToken(token, userId, ttl) {
19
+ const key = this.key("refresh", token);
20
+ await this.redis.set(key, userId, "EX", ttl);
21
+ this.log("SET", key, userId);
22
+ }
23
+ async getRefreshToken(token) {
24
+ const key = this.key("refresh", token);
25
+ const value = await this.redis.get(key);
26
+ this.log("GET", key, value);
27
+ return value;
28
+ }
29
+ async deleteRefreshToken(token) {
30
+ const key = this.key("refresh", token);
31
+ await this.redis.del(key);
32
+ this.log("DEL", key);
33
+ }
34
+ async blacklistToken(token, ttl) {
35
+ const key = this.key("blacklist", token);
36
+ await this.redis.set(key, "1", "EX", ttl);
37
+ this.log("SET", key, "blacklisted");
38
+ }
39
+ async isBlacklisted(token) {
40
+ const key = this.key("blacklist", token);
41
+ const exists = await this.redis.exists(key);
42
+ this.log("CHECK", key, exists);
43
+ return exists === 1;
44
+ }
45
+ // Rate Limiting
46
+ async incrementRateLimit(ip, ttl) {
47
+ const key = this.key("rate", ip);
48
+ const count = await this.redis.incr(key);
49
+ if (count === 1) {
50
+ await this.redis.expire(key, ttl);
51
+ }
52
+ this.log("INCR", key, count);
53
+ return count;
54
+ }
55
+ // IP Whitelist
56
+ async addToWhitelist(ip) {
57
+ const key = this.key("whitelist", ip);
58
+ await this.redis.set(key, "1");
59
+ this.log("SET", key, "whitelisted");
60
+ }
61
+ async removeFromWhitelist(ip) {
62
+ const key = this.key("whitelist", ip);
63
+ await this.redis.del(key);
64
+ this.log("DEL", key);
65
+ }
66
+ async isWhitelisted(ip) {
67
+ const key = this.key("whitelist", ip);
68
+ const exists = await this.redis.exists(key);
69
+ this.log("CHECK", key, exists);
70
+ return exists === 1;
71
+ }
72
+ async set(key, value, expiry) {
73
+ console.log("REDIS SET:", key, value);
74
+ if (expiry) {
75
+ await this.redis.set(key, value, "EX", expiry);
76
+ }
77
+ else {
78
+ await this.redis.set(key, value);
79
+ }
80
+ }
81
+ async get(key) {
82
+ return this.redis.get(key);
83
+ }
84
+ }
85
+ exports.RedisTokenStore = RedisTokenStore;
86
+ //# sourceMappingURL=RedisTokenStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RedisTokenStore.js","sourceRoot":"","sources":["../../src/storage/RedisTokenStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { UserStore } from "../types/storage";
2
+ export declare class Store {
3
+ private userStore;
4
+ constructor(userStore: UserStore);
5
+ register(email: string, password: string): Promise<void>;
6
+ }
7
+ //# sourceMappingURL=userStorage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"userStorage.d.ts","sourceRoot":"","sources":["../../src/storage/userStorage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,kBAAkB,CAAA;AAE1C,qBAAa,KAAK;IACN,OAAO,CAAC,SAAS;gBAAT,SAAS,EAAC,SAAS;IAEjC,QAAQ,CAAC,KAAK,EAAC,MAAM,EAAE,QAAQ,EAAC,MAAM;CAU3C"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Store = void 0;
4
+ class Store {
5
+ constructor(userStore) {
6
+ this.userStore = userStore;
7
+ }
8
+ async register(email, password) {
9
+ const exists = await this.userStore.findByEmail(email);
10
+ if (exists) {
11
+ throw new Error("If a record of user exists an email will be sent");
12
+ }
13
+ return;
14
+ this.userStore.create({ email, password });
15
+ }
16
+ }
17
+ exports.Store = Store;
18
+ //# sourceMappingURL=userStorage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"userStorage.js","sourceRoot":"","sources":["../../src/storage/userStorage.ts"],"names":[],"mappings":";;;AAEA,MAAa,KAAK;IAClB,YAAoB,SAAmB;QAAnB,cAAS,GAAT,SAAS,CAAU;IAAE,CAAC;IAE1C,KAAK,CAAC,QAAQ,CAAC,KAAY,EAAE,QAAe;QAC5C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;QAEtD,IAAI,MAAM,EAAC,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACpE,CAAC;QACD,OAAM;QACN,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAC,KAAK,EAAC,QAAQ,EAAC,CAAC,CAAC;IACxC,CAAC;CAEA;AAbD,sBAaC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=full.intergration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"full.intergration.test.d.ts","sourceRoot":"","sources":["../../src/tests/full.intergration.test.ts"],"names":[],"mappings":""}