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.
- package/.env +2 -0
- package/README.md +93 -0
- package/authenik8-core-0.1.0.tgz +0 -0
- package/dist/auth/guestModeService.d.ts +3 -0
- package/dist/auth/guestModeService.d.ts.map +1 -0
- package/dist/auth/guestModeService.js +24 -0
- package/dist/auth/guestModeService.js.map +1 -0
- package/dist/auth/jwtAuth.d.ts +28 -0
- package/dist/auth/jwtAuth.d.ts.map +1 -0
- package/dist/auth/jwtAuth.js +67 -0
- package/dist/auth/jwtAuth.js.map +1 -0
- package/dist/auth/refreshService.d.ts +41 -0
- package/dist/auth/refreshService.d.ts.map +1 -0
- package/dist/auth/refreshService.js +77 -0
- package/dist/auth/refreshService.js.map +1 -0
- package/dist/creatAuthenik8.d.ts +2 -0
- package/dist/creatAuthenik8.d.ts.map +1 -0
- package/dist/creatAuthenik8.js +3 -0
- package/dist/creatAuthenik8.js.map +1 -0
- package/dist/createAuthenik8.d.ts +4 -0
- package/dist/createAuthenik8.d.ts.map +1 -0
- package/dist/createAuthenik8.js +58 -0
- package/dist/createAuthenik8.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/adminService.d.ts +4 -0
- package/dist/middleware/adminService.d.ts.map +1 -0
- package/dist/middleware/adminService.js +40 -0
- package/dist/middleware/adminService.js.map +1 -0
- package/dist/redis/redisService.d.ts +26 -0
- package/dist/redis/redisService.d.ts.map +1 -0
- package/dist/redis/redisService.js +104 -0
- package/dist/redis/redisService.js.map +1 -0
- package/dist/security/ipService.d.ts +36 -0
- package/dist/security/ipService.d.ts.map +1 -0
- package/dist/security/ipService.js +160 -0
- package/dist/security/ipService.js.map +1 -0
- package/dist/security/limiter.d.ts +5 -0
- package/dist/security/limiter.d.ts.map +1 -0
- package/dist/security/limiter.js +93 -0
- package/dist/security/limiter.js.map +1 -0
- package/dist/storage/RedisTokenStore.d.ts +21 -0
- package/dist/storage/RedisTokenStore.d.ts.map +1 -0
- package/dist/storage/RedisTokenStore.js +86 -0
- package/dist/storage/RedisTokenStore.js.map +1 -0
- package/dist/storage/userStorage.d.ts +7 -0
- package/dist/storage/userStorage.d.ts.map +1 -0
- package/dist/storage/userStorage.js +18 -0
- package/dist/storage/userStorage.js.map +1 -0
- package/dist/tests/full.intergration.test.d.ts +2 -0
- package/dist/tests/full.intergration.test.d.ts.map +1 -0
- package/dist/tests/full.intergration.test.js +79 -0
- package/dist/tests/full.intergration.test.js.map +1 -0
- package/dist/tests/testApp.d.ts +7 -0
- package/dist/tests/testApp.d.ts.map +1 -0
- package/dist/tests/testApp.js +53 -0
- package/dist/tests/testApp.js.map +1 -0
- package/dist/types/admin.d.ts +6 -0
- package/dist/types/admin.d.ts.map +1 -0
- package/dist/types/admin.js +3 -0
- package/dist/types/admin.js.map +1 -0
- package/dist/types/config.d.ts +9 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +3 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/public.d.ts +17 -0
- package/dist/types/public.d.ts.map +1 -0
- package/dist/types/public.js +3 -0
- package/dist/types/public.js.map +1 -0
- package/dist/types/storage.d.ts +14 -0
- package/dist/types/storage.d.ts.map +1 -0
- package/dist/types/storage.js +3 -0
- package/dist/types/storage.js.map +1 -0
- package/dump.rdb +0 -0
- package/jest.config.js +11 -0
- package/package.json +56 -0
- package/src/1 +22 -0
- package/src/auth/guestModeService.ts +31 -0
- package/src/auth/jwtAuth.ts +99 -0
- package/src/auth/refreshService.ts +134 -0
- package/src/creatAuthenik8.ts +0 -0
- package/src/createAuthenik8.ts +66 -0
- package/src/index.ts +1 -0
- package/src/middleware/adminService.ts +50 -0
- package/src/redis/redisService.ts +137 -0
- package/src/security/ipService.ts +180 -0
- package/src/security/limiter.ts +116 -0
- package/src/storage/RedisTokenStore.ts +99 -0
- package/src/storage/userStorage.ts +16 -0
- package/src/tests/full.intergration.test.ts +100 -0
- package/src/tests/testApp.ts +56 -0
- package/src/types/admin.ts +7 -0
- package/src/types/config.ts +11 -0
- package/src/types/public.ts +22 -0
- package/src/types/storage.ts +15 -0
- 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 @@
|
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"full.intergration.test.d.ts","sourceRoot":"","sources":["../../src/tests/full.intergration.test.ts"],"names":[],"mappings":""}
|