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,100 @@
1
+ // tests/full.integration.test.ts
2
+ import { createTestApp } from "./testApp";
3
+
4
+ describe("Authenik8 Full Integration", () => {
5
+ let request: any;
6
+ let auth: any;
7
+
8
+ let accessToken: string;
9
+ let refreshToken: string;
10
+
11
+ beforeAll(async () => {
12
+ const setup = await createTestApp();
13
+ request = setup.request;
14
+ auth = setup.auth;
15
+ });
16
+
17
+ afterAll(async () => {
18
+ if (auth.redis) {
19
+ await auth.redis.flushdb();
20
+ await auth.redis.quit();
21
+ }
22
+ });
23
+
24
+ // 🔐 LOGIN
25
+ test("should login and receive tokens", async () => {
26
+ const res = await request.post("/login");
27
+
28
+ expect(res.status).toBe(200);
29
+ expect(res.body).toHaveProperty("accessToken");
30
+ expect(res.body).toHaveProperty("refreshToken");
31
+
32
+ accessToken = res.body.accessToken;
33
+ refreshToken = res.body.refreshToken;
34
+ });
35
+
36
+ // 🔒 PROTECTED ROUTE
37
+ test("should access protected route with valid token", async () => {
38
+ const res = await request
39
+ .get("/protected")
40
+ .set("Authorization", `Bearer ${accessToken}`);
41
+
42
+ expect(res.status).toBe(200);
43
+ expect(res.body).toHaveProperty("data", "secure data");
44
+ });
45
+
46
+ // 🚫 NO TOKEN
47
+ test("should reject request without token", async () => {
48
+ const res = await request.get("/protected");
49
+
50
+ expect(res.status).toBe(401);
51
+ });
52
+
53
+ // 🔄 REFRESH TOKEN
54
+ test("should refresh access token", async () => {
55
+ const res = await request
56
+ .post("/refresh")
57
+ .send({ refreshToken });
58
+
59
+ expect(res.status).toBe(200);
60
+ expect(res.body).toHaveProperty("accessToken");
61
+ expect(res.body).toHaveProperty("refreshToken");
62
+
63
+ // update tokens
64
+ accessToken = res.body.accessToken;
65
+ refreshToken = res.body.refreshToken;
66
+
67
+ if (res.body.refreshToken) {
68
+ refreshToken = res.body.refreshToken;
69
+ }
70
+
71
+ });
72
+
73
+ // 🔥 ROTATION (IMPORTANT)
74
+ test("should NOT allow reuse of old refresh token", async () => {
75
+ const originalToken = refreshToken;
76
+
77
+ // first use → rotates token
78
+ const firstRes = await request
79
+ .post("/refresh")
80
+ .send({ refreshToken: originalToken });
81
+
82
+ expect(firstRes.status).toBe(200);
83
+
84
+ const newToken = firstRes.body.refreshToken;
85
+
86
+ // second use with OLD token → should fail
87
+ const res = await request
88
+ .post("/refresh")
89
+ .send({ refreshToken: originalToken });
90
+
91
+ expect(res.status).toBe(401);
92
+
93
+ // sanity check: new token should work
94
+ const validRes = await request
95
+ .post("/refresh")
96
+ .send({ refreshToken: newToken });
97
+
98
+ expect(validRes.status).toBe(200);
99
+ });
100
+ });
@@ -0,0 +1,56 @@
1
+ // tests/testApp.ts
2
+ import express from "express";
3
+ import request from "supertest";
4
+ import { createAuthenik8 } from "../createAuthenik8";
5
+
6
+ export const createTestApp = async () => {
7
+ const auth = await createAuthenik8({
8
+ jwtSecret: "test-secret",
9
+ refreshSecret: "refresh-secret",
10
+ jwtExpiry: "15m"
11
+ });
12
+
13
+ const app = express();
14
+ app.use(express.json());
15
+
16
+ // 🔐 Login (simulate user)
17
+ app.post("/login", async(req, res) => {
18
+ const user = { userId: "user_1", email:"test@test.com" };
19
+
20
+ const accessToken = auth.signToken(user);
21
+ const refreshToken = await auth.generateRefreshToken(user);
22
+
23
+ res.json({ accessToken, refreshToken });
24
+ console.log("Refresh Token",refreshToken)
25
+ });
26
+
27
+ // 🔒 Protected route
28
+ app.get("/protected", (req, res) => {
29
+ const token = req.headers.authorization?.split(" ")[1];
30
+
31
+ if(!token){
32
+ return res.status(401).json({error:"Invalid token"})
33
+ }
34
+
35
+ const decoded = auth.verifyToken(token);
36
+
37
+ if (!decoded) {
38
+ return res.status(401).json({ error: "Unauthorized" });
39
+ }
40
+
41
+ res.json({ data: "secure data", user: decoded });
42
+ });
43
+
44
+ // 🔄 Refresh
45
+ app.post("/refresh", async (req, res) => {
46
+ try {
47
+ const result = await auth.refreshToken(req.body.refreshToken);
48
+ res.json(result);
49
+ } catch (err) {
50
+ res.status(401).json({ error: "Invalid refresh token" });
51
+ }
52
+
53
+ });
54
+
55
+ return { app, auth, request: request(app) };
56
+ };
@@ -0,0 +1,7 @@
1
+
2
+ import { Redis } from "ioredis";
3
+
4
+ export interface RequireAdminOptions {
5
+ jwtSecret: string;
6
+ redis?: Redis;
7
+ }
@@ -0,0 +1,11 @@
1
+
2
+ import { SignOptions } from "jsonwebtoken";
3
+ import { Redis } from "ioredis";
4
+
5
+ export interface Authenik8Config {
6
+ jwtSecret: string;
7
+ jwtExpiry: SignOptions["expiresIn"];
8
+ refreshSecret: string;
9
+
10
+ redis?: Redis;
11
+ }
@@ -0,0 +1,22 @@
1
+
2
+ export interface Authenik8Instance {
3
+ signToken: (payload: any) => string;
4
+ verifyToken: (token: string) => any;
5
+ guestToken: () => string;
6
+
7
+ refreshToken: (token: string) => Promise<any>;
8
+ generateRefreshToken: (payload: any) => Promise<string>;
9
+
10
+ rateLimit: any;
11
+ ipWhitelist: any;
12
+ helmet: any;
13
+
14
+ addIP: (ip: string) => Promise<void>;
15
+ removeIP: (ip: string) => Promise<void>;
16
+ listIPs: () => Promise<string[]>;
17
+
18
+ requireAdmin: any;
19
+ incognito: any;
20
+
21
+ redis?: any;
22
+ }
@@ -0,0 +1,15 @@
1
+ export interface User{
2
+ id:string;
3
+ email:string;
4
+ password:string;
5
+ role?:string;
6
+ type?:string;
7
+ }
8
+
9
+ export interface UserStore{
10
+ findByEmail(email:string):Promise<User | null>;
11
+ findById(id:string):Promise<User | null>;
12
+ create(user: Partial<User>):
13
+ Promise<User>;
14
+ update(id:string, data:Partial<User>):Promise<User>;
15
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ // Visit https://aka.ms/tsconfig to read more about this file
3
+ "compilerOptions": {
4
+ // File Layout
5
+ "rootDir": "./src",
6
+ "outDir": "./dist",
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+
10
+ "declaration": true,
11
+ "sourceMap": true,
12
+
13
+ "skipLibCheck": true,
14
+ "forceConsistentCasingInFileNames": true,
15
+ // Environment Settings
16
+ // See also https://aka.ms/tsconfig/module
17
+ "module": "CommonJS",
18
+ "target": "ES2019",
19
+ "types": [],
20
+ // For nodejs:
21
+ // "lib": ["esnext"],
22
+ "types": ["node","jest"],
23
+ // and npm install -D @types/node
24
+
25
+ // Other Outputs
26
+ "sourceMap": true,
27
+ "declaration": true,
28
+ "declarationMap": true,
29
+
30
+ // Stricter Typechecking Options
31
+ "noUncheckedIndexedAccess": true,
32
+ //"exactOptionalPropertyTypes": true,
33
+
34
+ // Style Options
35
+ // "noImplicitReturns": true,
36
+ // "noImplicitOverride": true,
37
+ // "noUnusedLocals": true,
38
+ // "noUnusedParameters": true,
39
+ // "noFallthroughCasesInSwitch": true,
40
+ // "noPropertyAccessFromIndexSignature": true,
41
+
42
+ // Recommended Options
43
+ "strict": true,
44
+ "jsx": "react-jsx",
45
+ //"verbatimModuleSyntax": true,
46
+ "isolatedModules": true,
47
+ "noUncheckedSideEffectImports": true,
48
+ "moduleDetection": "force",
49
+ "skipLibCheck": true,
50
+ }
51
+ }