create-authenik8-app 2.4.6 → 2.4.8

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 (87) hide show
  1. package/dist/src/bin/index.d.ts +3 -0
  2. package/dist/src/bin/index.d.ts.map +1 -0
  3. package/dist/src/bin/index.js +275 -0
  4. package/dist/src/bin/index.js.map +1 -0
  5. package/dist/src/lib/constants.d.ts +4 -0
  6. package/dist/src/lib/constants.d.ts.map +1 -0
  7. package/dist/src/lib/constants.js +25 -0
  8. package/dist/src/lib/constants.js.map +1 -0
  9. package/dist/src/lib/process.d.ts +7 -0
  10. package/dist/src/lib/process.d.ts.map +1 -0
  11. package/dist/src/lib/process.js +60 -0
  12. package/dist/src/lib/process.js.map +1 -0
  13. package/dist/src/lib/state.d.ts +8 -0
  14. package/dist/src/lib/state.d.ts.map +1 -0
  15. package/dist/src/lib/state.js +31 -0
  16. package/dist/src/lib/state.js.map +1 -0
  17. package/dist/src/lib/types.d.ts +19 -0
  18. package/dist/src/lib/types.d.ts.map +1 -0
  19. package/dist/src/lib/types.js +2 -0
  20. package/dist/src/lib/types.js.map +1 -0
  21. package/dist/src/lib/ui.d.ts +7 -0
  22. package/dist/src/lib/ui.d.ts.map +1 -0
  23. package/dist/src/lib/ui.js +124 -0
  24. package/dist/src/lib/ui.js.map +1 -0
  25. package/dist/src/steps/configurePrisma.d.ts +3 -0
  26. package/dist/src/steps/configurePrisma.d.ts.map +1 -0
  27. package/dist/src/steps/configurePrisma.js +62 -0
  28. package/dist/src/steps/configurePrisma.js.map +1 -0
  29. package/dist/src/steps/createProject.d.ts +5 -0
  30. package/dist/src/steps/createProject.d.ts.map +1 -0
  31. package/dist/src/steps/createProject.js +202 -0
  32. package/dist/src/steps/createProject.js.map +1 -0
  33. package/dist/src/steps/finalSetup.d.ts +7 -0
  34. package/dist/src/steps/finalSetup.d.ts.map +1 -0
  35. package/dist/src/steps/finalSetup.js +110 -0
  36. package/dist/src/steps/finalSetup.js.map +1 -0
  37. package/dist/src/steps/installAuth.d.ts +3 -0
  38. package/dist/src/steps/installAuth.d.ts.map +1 -0
  39. package/dist/src/steps/installAuth.js +16 -0
  40. package/dist/src/steps/installAuth.js.map +1 -0
  41. package/dist/src/steps/installDeps.d.ts +5 -0
  42. package/dist/src/steps/installDeps.d.ts.map +1 -0
  43. package/dist/src/steps/installDeps.js +99 -0
  44. package/dist/src/steps/installDeps.js.map +1 -0
  45. package/dist/src/steps/prompts.d.ts +3 -0
  46. package/dist/src/steps/prompts.d.ts.map +1 -0
  47. package/dist/src/steps/prompts.js +93 -0
  48. package/dist/src/steps/prompts.js.map +1 -0
  49. package/dist/src/tests/templated-routes.test.d.ts +2 -0
  50. package/dist/src/tests/templated-routes.test.d.ts.map +1 -0
  51. package/dist/src/tests/templated-routes.test.js +325 -0
  52. package/dist/src/tests/templated-routes.test.js.map +1 -0
  53. package/dist/src/utils/hash.d.ts +4 -0
  54. package/dist/src/utils/hash.d.ts.map +1 -0
  55. package/dist/src/utils/hash.js +17 -0
  56. package/dist/src/utils/hash.js.map +1 -0
  57. package/dist/src/utils/output.d.ts +3 -0
  58. package/dist/src/utils/output.d.ts.map +1 -0
  59. package/dist/src/utils/output.js +81 -0
  60. package/dist/src/utils/output.js.map +1 -0
  61. package/dist/templates/THREAT_MODEL.md +138 -0
  62. package/dist/templates/express-auth/src/controllers/protected.controller.d.ts +8 -0
  63. package/dist/templates/express-auth/src/controllers/protected.controller.d.ts.map +1 -0
  64. package/dist/templates/express-auth/src/controllers/protected.controller.js +50 -0
  65. package/dist/templates/express-auth/src/controllers/protected.controller.js.map +1 -0
  66. package/dist/templates/express-auth/src/routes/protected.routes.d.ts +2 -0
  67. package/dist/templates/express-auth/src/routes/protected.routes.d.ts.map +1 -0
  68. package/dist/templates/express-auth/src/routes/protected.routes.js +16 -0
  69. package/dist/templates/express-auth/src/routes/protected.routes.js.map +1 -0
  70. package/dist/templates/express-auth/src/utils/security.d.ts +8 -0
  71. package/dist/templates/express-auth/src/utils/security.d.ts.map +1 -0
  72. package/dist/templates/express-auth/src/utils/security.js +55 -0
  73. package/dist/templates/express-auth/src/utils/security.js.map +1 -0
  74. package/dist/templates/express-base/controllers/base.controller.d.ts +12 -0
  75. package/dist/templates/express-base/controllers/base.controller.d.ts.map +1 -0
  76. package/dist/templates/express-base/controllers/base.controller.js +77 -0
  77. package/dist/templates/express-base/controllers/base.controller.js.map +1 -0
  78. package/dist/templates/express-base/routes/base.routes.d.ts +2 -0
  79. package/dist/templates/express-base/routes/base.routes.d.ts.map +1 -0
  80. package/dist/templates/express-base/routes/base.routes.js +20 -0
  81. package/dist/templates/express-base/routes/base.routes.js.map +1 -0
  82. package/dist/templates/express-base/utils/security.d.ts +5 -0
  83. package/dist/templates/express-base/utils/security.d.ts.map +1 -0
  84. package/dist/templates/express-base/utils/security.js +40 -0
  85. package/dist/templates/express-base/utils/security.js.map +1 -0
  86. package/dist/templates/package.json +27 -0
  87. package/package.json +4 -3
@@ -0,0 +1,93 @@
1
+ import inquirer from "inquirer";
2
+ import { hasBun } from "./finalSetup.js";
3
+ export async function runPrompts(state, isProduction) {
4
+ const bunAvailable = hasBun();
5
+ return inquirer.prompt([
6
+ {
7
+ type: "list",
8
+ name: "framework",
9
+ message: "Choose framework:",
10
+ choices: [
11
+ "Express",
12
+ { name: "Fastify (coming soon)", value: "Fastify", disabled: "Coming soon" },
13
+ ],
14
+ default: "Express",
15
+ },
16
+ {
17
+ type: "list",
18
+ name: "authMode",
19
+ message: "Choose authentication setup:",
20
+ choices: [
21
+ { name: "JWT only", value: "base" },
22
+ { name: "Email + Password Auth", value: "auth" },
23
+ { name: "Full Auth (Password + OAuth)", value: "auth-oauth" },
24
+ ],
25
+ default: "base",
26
+ },
27
+ {
28
+ type: "checkbox",
29
+ name: "oauthProviders",
30
+ message: "Choose OAuth providers:",
31
+ choices: [
32
+ { name: "Google", value: "google" },
33
+ { name: "GitHub", value: "github" },
34
+ ],
35
+ //default: ["google"],
36
+ when: (answers) => answers.authMode === "auth-oauth",
37
+ validate: (choices) => Array.isArray(choices) && choices.length > 0
38
+ ? true
39
+ : "Select at least one OAuth provider",
40
+ },
41
+ {
42
+ type: "confirm",
43
+ name: "usePrisma",
44
+ message: "Use Prisma?",
45
+ default: true,
46
+ when: (answers) => answers.authMode === "base"
47
+ },
48
+ {
49
+ type: "list",
50
+ name: "database",
51
+ message: "Choose database:",
52
+ choices: [
53
+ { name: "PostgreSQL", value: "postgresql" },
54
+ { name: "SQLite ", value: "sqlite" },
55
+ ],
56
+ when: (answers) => answers.usePrisma || answers.authMode === "auth" || answers.authMode === "auth-oauth",
57
+ default: "sqlite",
58
+ },
59
+ {
60
+ type: "confirm",
61
+ name: "useGit",
62
+ message: "Initialize git?",
63
+ default: true,
64
+ },
65
+ {
66
+ type: "list",
67
+ name: "runtime",
68
+ message: "Choose runtime:",
69
+ choices: [
70
+ {
71
+ name: bunAvailable
72
+ ? "Bun (fast, no build step)"
73
+ : "Bun (not installed)",
74
+ value: "bun",
75
+ disabled: !bunAvailable && "Bun not found",
76
+ },
77
+ {
78
+ name: "Node (stable, widely supported)",
79
+ value: "node",
80
+ },
81
+ ],
82
+ when: () => isProduction,
83
+ default: bunAvailable ? "bun" : "node"
84
+ },
85
+ ])
86
+ .then((result) => {
87
+ if (result.runtime === "bun" && !bunAvailable) {
88
+ result.runtime = "node";
89
+ }
90
+ return result;
91
+ });
92
+ }
93
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/steps/prompts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=templated-routes.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templated-routes.test.d.ts","sourceRoot":"","sources":["../../../src/tests/templated-routes.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,325 @@
1
+ import express from "express";
2
+ import { createRequire } from "node:module";
3
+ import request from "supertest";
4
+ import { beforeEach, describe, expect, it, vi } from "vitest";
5
+ const authenik8CoreMock = vi.hoisted(() => ({
6
+ createAuthenik8: vi.fn(),
7
+ }));
8
+ const dotenvMock = vi.hoisted(() => ({
9
+ config: vi.fn(),
10
+ }));
11
+ vi.mock("authenik8-core", () => ({
12
+ createAuthenik8: authenik8CoreMock.createAuthenik8,
13
+ }));
14
+ vi.mock("dotenv", () => ({
15
+ default: dotenvMock,
16
+ config: dotenvMock.config,
17
+ }));
18
+ const require = createRequire(import.meta.url);
19
+ const jwt = require("jsonwebtoken");
20
+ const jwtSecret = "templated-route-test-secret";
21
+ class InMemoryRedis {
22
+ hashes = new Map();
23
+ async hset(key, field, value) {
24
+ const hash = this.hashes.get(key) ?? new Map();
25
+ hash.set(field, value);
26
+ this.hashes.set(key, hash);
27
+ return 1;
28
+ }
29
+ async hgetall(key) {
30
+ return Object.fromEntries(this.hashes.get(key) ?? []);
31
+ }
32
+ async hdel(key, field) {
33
+ const hash = this.hashes.get(key);
34
+ if (!hash)
35
+ return 0;
36
+ return hash.delete(field) ? 1 : 0;
37
+ }
38
+ async del(key) {
39
+ return this.hashes.delete(key) ? 1 : 0;
40
+ }
41
+ async expire(_key, _ttl) {
42
+ return 1;
43
+ }
44
+ clear() {
45
+ this.hashes.clear();
46
+ }
47
+ async seedSession(userId, session) {
48
+ const storedSession = {
49
+ token: session.token ?? `stored-token-${session.sessionId}`,
50
+ device: session.device ?? "Chrome on Linux",
51
+ ip: session.ip ?? "127.0.0.1",
52
+ sessionId: session.sessionId,
53
+ createdAt: session.createdAt ?? "2026-05-02T00:00:00.000Z",
54
+ };
55
+ await this.hset(`sessions:${userId}`, session.sessionId, JSON.stringify(storedSession));
56
+ await this.expire(`sessions:${userId}`, 60 * 60);
57
+ return storedSession;
58
+ }
59
+ }
60
+ const redis = new InMemoryRedis();
61
+ let redisForAuthFactory;
62
+ const signTestToken = (payload) => jwt.sign(payload, jwtSecret);
63
+ const adminToken = () => signTestToken({ id: "admin-user", role: "admin" });
64
+ const userToken = () => signTestToken({ id: "regular-user", role: "user" });
65
+ const getBearerToken = (authorization) => {
66
+ if (typeof authorization !== "string")
67
+ return undefined;
68
+ const [scheme, token] = authorization.split(" ");
69
+ return scheme === "Bearer" ? token : undefined;
70
+ };
71
+ const createAdminActions = (sessionStore) => ({
72
+ async listSessions(userId) {
73
+ const rawSessions = await sessionStore.hgetall(`sessions:${userId}`);
74
+ return Object.values(rawSessions).map((serializedSession) => JSON.parse(serializedSession));
75
+ },
76
+ async revokeSession(userId, sessionId) {
77
+ await sessionStore.hdel(`sessions:${userId}`, sessionId);
78
+ },
79
+ async revokeAllSessions(userId) {
80
+ await sessionStore.del(`sessions:${userId}`);
81
+ },
82
+ });
83
+ const createMockAuth = (sessionStore) => ({
84
+ requireAdmin(req, res, next) {
85
+ const token = getBearerToken(req.headers.authorization);
86
+ if (!token) {
87
+ return res.status(401).json({ error: "Unauthorized" });
88
+ }
89
+ try {
90
+ const decoded = jwt.verify(token, jwtSecret);
91
+ if (decoded.role !== "admin") {
92
+ return res.status(403).json({ error: "Forbidden" });
93
+ }
94
+ if (sessionStore) {
95
+ req.adminActions =
96
+ createAdminActions(sessionStore);
97
+ }
98
+ next();
99
+ }
100
+ catch {
101
+ res.status(403).json({ error: "Forbidden" });
102
+ }
103
+ },
104
+ authenticateJWT(req, res, next) {
105
+ const token = getBearerToken(req.headers.authorization);
106
+ if (!token) {
107
+ return res.status(401).json({ error: "Unauthorized" });
108
+ }
109
+ try {
110
+ jwt.verify(token, jwtSecret);
111
+ next();
112
+ }
113
+ catch {
114
+ res.status(403).json({ error: "Forbidden" });
115
+ }
116
+ },
117
+ signToken: (payload) => jwt.sign(payload, jwtSecret),
118
+ verifyToken: async (token) => jwt.verify(token, jwtSecret),
119
+ guestToken: async (payload) => jwt.sign(payload, jwtSecret),
120
+ refreshToken: async () => ({
121
+ accessToken: jwt.sign({ id: "refreshed-user", role: "user" }, jwtSecret),
122
+ refreshToken: "next-refresh-token",
123
+ }),
124
+ incognito: vi.fn(),
125
+ rateLimit: (_req, _res, next) => next(),
126
+ ipWhitelist: (_req, _res, next) => next(),
127
+ helmet: (_req, _res, next) => next(),
128
+ });
129
+ const appWithRouter = (router) => {
130
+ const app = express();
131
+ app.use(express.json());
132
+ app.use(router);
133
+ return app;
134
+ };
135
+ const send = (app, method, path) => {
136
+ if (method === "delete") {
137
+ return request(app).delete(path);
138
+ }
139
+ return request(app).get(path);
140
+ };
141
+ const routeTemplates = [
142
+ {
143
+ name: "templates/express-auth/src/routes/protected.routes.ts",
144
+ guardedRoute: {
145
+ method: "get",
146
+ path: "/protected",
147
+ expectedBody: { message: "Protected route" },
148
+ },
149
+ async createApp(sessionStore) {
150
+ const { createProtectedRoutes } = await import("../../templates/express-auth/src/routes/protected.routes.js");
151
+ return appWithRouter(createProtectedRoutes(createMockAuth(sessionStore)));
152
+ },
153
+ },
154
+ {
155
+ name: "templates/express-base/routes/base.routes.ts",
156
+ guardedRoute: {
157
+ method: "get",
158
+ path: "/admin",
159
+ expectedBody: { message: "Admin only" },
160
+ },
161
+ async createApp(sessionStore) {
162
+ const { createBaseRoutes } = await import("../../templates/express-base/routes/base.routes.js");
163
+ return appWithRouter(createBaseRoutes(createMockAuth(sessionStore)));
164
+ },
165
+ },
166
+ //{
167
+ //name: "templates/express-auth+/src/auth/routes/protected.routes.ts",
168
+ // guardedRoute: {
169
+ // method: "get",
170
+ //path: "/protected",
171
+ //expectedBody: { message: "Protected route" },
172
+ //},
173
+ //async createApp(sessionStore?: InMemoryRedis) {
174
+ //redisForAuthFactory = sessionStore;
175
+ //const [ { default: protectedRoutes }] = await Promise.all([
176
+ //import("../../templates/express-auth+/src/auth/auth.js"),
177
+ //import("../../templates/express-auth+/src/auth/routes/protected.routes.js"),
178
+ //]);
179
+ //const authModule = await import("../../templates/express-auth+/src/auth/auth.js");
180
+ //const routesModule = await import("../../templates/express-auth+/src/auth/routes/protected.routes.js");
181
+ //await authModule.initAuth();
182
+ // await initAuth();
183
+ // /const protectedRoutes = routesModule.default as unknown as Router ;
184
+ // return appWithRouter(protectedRoutes);
185
+ //},
186
+ //},
187
+ ];
188
+ const sessionRoutes = [
189
+ {
190
+ name: "list sessions",
191
+ method: "get",
192
+ path: "/admin/sessions/user-a",
193
+ },
194
+ {
195
+ name: "revoke one session",
196
+ method: "delete",
197
+ path: "/admin/sessions/user-a/session-a",
198
+ },
199
+ {
200
+ name: "revoke all sessions",
201
+ method: "delete",
202
+ path: "/admin/sessions/user-a",
203
+ },
204
+ ];
205
+ beforeEach(() => {
206
+ vi.resetModules();
207
+ vi.stubEnv("JWT_SECRET", "templated-route-test-jwt-secret-32");
208
+ vi.stubEnv("REFRESH_SECRET", "templated-route-test-refresh-secret-32");
209
+ vi.stubEnv("GOOGLE_CLIENT_ID", "google-client-id");
210
+ vi.stubEnv("GOOGLE_CLIENT_SECRET", "google-client-secret");
211
+ vi.stubEnv("GOOGLE_REDIRECT_URI", "https://example.com/auth/google/callback");
212
+ vi.stubEnv("GITHUB_CLIENT_ID", "github-client-id");
213
+ vi.stubEnv("GITHUB_CLIENT_SECRET", "github-client-secret");
214
+ vi.stubEnv("GITHUB_REDIRECT_URI", "https://example.com/auth/github/callback");
215
+ redis.clear();
216
+ redisForAuthFactory = undefined;
217
+ dotenvMock.config.mockReset();
218
+ authenik8CoreMock.createAuthenik8.mockReset();
219
+ authenik8CoreMock.createAuthenik8.mockImplementation(async () => createMockAuth(redisForAuthFactory));
220
+ });
221
+ describe.each(routeTemplates)("$name", (template) => {
222
+ describe("admin guard", () => {
223
+ const guardedRoutes = [template.guardedRoute, ...sessionRoutes];
224
+ it.each(guardedRoutes)("returns 401 with no token for $method $path", async (route) => {
225
+ const app = await template.createApp(redis);
226
+ const response = await send(app, route.method, route.path);
227
+ expect(response.status).toBe(401);
228
+ });
229
+ it.each(guardedRoutes)("returns 403 for non-admin users on $method $path", async (route) => {
230
+ const app = await template.createApp(redis);
231
+ const response = await send(app, route.method, route.path).set("Authorization", `Bearer ${userToken()}`);
232
+ expect(response.status).toBe(403);
233
+ });
234
+ it.each(guardedRoutes)("returns 403 for unauthenticated invalid tokens on $method $path", async (route) => {
235
+ const app = await template.createApp(redis);
236
+ const response = await send(app, route.method, route.path).set("Authorization", "Bearer not-a-valid-token");
237
+ expect(response.status).toBe(403);
238
+ });
239
+ it(`returns the happy path response for ${template.guardedRoute.method} ${template.guardedRoute.path}`, async () => {
240
+ const app = await template.createApp(redis);
241
+ const response = await send(app, template.guardedRoute.method, template.guardedRoute.path).set("Authorization", `Bearer ${adminToken()}`);
242
+ expect(response.status).toBe(200);
243
+ expect(response.body).toEqual(template.guardedRoute.expectedBody);
244
+ });
245
+ });
246
+ describe("session management", () => {
247
+ it.each(sessionRoutes)("returns 503 for $method $path when Redis is not configured", async (route) => {
248
+ const app = await template.createApp(undefined);
249
+ const response = await send(app, route.method, route.path).set("Authorization", `Bearer ${adminToken()}`);
250
+ expect(response.status).toBe(503);
251
+ expect(response.body).toEqual({
252
+ success: false,
253
+ message: "Session management unavailable",
254
+ });
255
+ });
256
+ it("lists sessions without exposing stored tokens", async () => {
257
+ const app = await template.createApp(redis);
258
+ await redis.seedSession("user-a", {
259
+ sessionId: "session-a",
260
+ token: "sensitive-token-a",
261
+ device: "Firefox on macOS",
262
+ ip: "10.0.0.1",
263
+ });
264
+ await redis.seedSession("user-a", {
265
+ sessionId: "session-b",
266
+ token: "sensitive-token-b",
267
+ device: "Safari on iOS",
268
+ ip: "10.0.0.2",
269
+ });
270
+ const response = await request(app)
271
+ .get("/admin/sessions/user-a")
272
+ .set("Authorization", `Bearer ${adminToken()}`);
273
+ expect(response.status).toBe(200);
274
+ expect(response.body.sessions).toEqual([
275
+ {
276
+ device: "Firefox on macOS",
277
+ ip: "10.0.0.1",
278
+ sessionId: "session-a",
279
+ createdAt: "2026-05-02T00:00:00.000Z",
280
+ },
281
+ {
282
+ device: "Safari on iOS",
283
+ ip: "10.0.0.2",
284
+ sessionId: "session-b",
285
+ createdAt: "2026-05-02T00:00:00.000Z",
286
+ },
287
+ ]);
288
+ expect(JSON.stringify(response.body)).not.toContain("sensitive-token");
289
+ expect(response.body.sessions).toEqual(expect.arrayContaining([expect.not.objectContaining({ token: expect.anything() })]));
290
+ });
291
+ it("revokes one session without affecting other sessions or users", async () => {
292
+ const app = await template.createApp(redis);
293
+ await redis.seedSession("user-a", { sessionId: "session-a", token: "user-a-token-a" });
294
+ await redis.seedSession("user-a", { sessionId: "session-b", token: "user-a-token-b" });
295
+ await redis.seedSession("user-b", { sessionId: "session-c", token: "user-b-token-c" });
296
+ const response = await request(app)
297
+ .delete("/admin/sessions/user-a/session-a")
298
+ .set("Authorization", `Bearer ${adminToken()}`);
299
+ expect(response.status).toBe(200);
300
+ expect(response.body).toEqual({ success: true, message: "Session revoked" });
301
+ expect(await redis.hgetall("sessions:user-a")).toEqual({
302
+ "session-b": expect.any(String),
303
+ });
304
+ expect(await redis.hgetall("sessions:user-b")).toEqual({
305
+ "session-c": expect.any(String),
306
+ });
307
+ });
308
+ it("revokes all sessions for only the targeted user", async () => {
309
+ const app = await template.createApp(redis);
310
+ await redis.seedSession("user-a", { sessionId: "session-a", token: "user-a-token-a" });
311
+ await redis.seedSession("user-a", { sessionId: "session-b", token: "user-a-token-b" });
312
+ await redis.seedSession("user-b", { sessionId: "session-c", token: "user-b-token-c" });
313
+ const response = await request(app)
314
+ .delete("/admin/sessions/user-a")
315
+ .set("Authorization", `Bearer ${adminToken()}`);
316
+ expect(response.status).toBe(200);
317
+ expect(response.body).toEqual({ success: true, message: "All sessions revoked" });
318
+ expect(await redis.hgetall("sessions:user-a")).toEqual({});
319
+ expect(await redis.hgetall("sessions:user-b")).toEqual({
320
+ "session-c": expect.any(String),
321
+ });
322
+ });
323
+ });
324
+ });
325
+ //# sourceMappingURL=templated-routes.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templated-routes.test.js","sourceRoot":"","sources":["../../../src/tests/templated-routes.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { PackageManager } from "../steps/installDeps.js";
2
+ export declare function getBestHashLib(_pm: PackageManager): "bcryptjs";
3
+ export declare function generateHashModule(_hashLib: "bcryptjs"): string;
4
+ //# sourceMappingURL=hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../../src/utils/hash.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE9D,wBAAgB,cAAc,CAAC,GAAG,EAAE,cAAc,GAAG,UAAU,CAE9D;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,UAAU,GAAG,MAAM,CAY/D"}
@@ -0,0 +1,17 @@
1
+ export function getBestHashLib(_pm) {
2
+ return "bcryptjs";
3
+ }
4
+ export function generateHashModule(_hashLib) {
5
+ return `
6
+ import bcrypt from "bcryptjs";
7
+
8
+ export const hashPassword = (password: string) => {
9
+ return bcrypt.hash(password, 10);
10
+ };
11
+
12
+ export const comparePassword = (password: string, hash: string) => {
13
+ return bcrypt.compare(password, hash);
14
+ };
15
+ `;
16
+ }
17
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../../src/utils/hash.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,cAAc,CAAC,GAAmB;IAChD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,QAAoB;IACrD,OAAO;;;;;;;;;;CAUR,CAAC;AACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { CliState } from "../lib/types.js";
2
+ export declare function printSummary(state: CliState, isProduction: boolean): void;
3
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../../src/utils/output.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAsBhD,wBAAgB,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,GAAG,IAAI,CAsEzE"}
@@ -0,0 +1,81 @@
1
+ import chalk from "chalk";
2
+ function selectedOAuthProviders(state) {
3
+ const providers = state.oauthProviders?.filter((provider) => provider === "google" || provider === "github");
4
+ return providers?.length ? providers : ["google", "github"];
5
+ }
6
+ function oauthProviderLabel(state) {
7
+ return selectedOAuthProviders(state)
8
+ .map((provider) => provider === "github" ? "GitHub" : "Google")
9
+ .join("/");
10
+ }
11
+ function oauthRouteLines(state) {
12
+ return selectedOAuthProviders(state)
13
+ .map((provider) => ` GET /auth/${provider}`)
14
+ .join("\n");
15
+ }
16
+ export function printSummary(state, isProduction) {
17
+ console.log(chalk.green.bold("\nšŸŽ‰ Authenik8 app created successfully!\n"));
18
+ console.log(chalk.white(`
19
+ Next steps:
20
+
21
+ cd ${state.projectName}
22
+ ${state.usePrisma ? "npm run prisma:migrate\n" : ""}redis-server --daemonize yes
23
+ npm run dev
24
+
25
+ Before running, review .env and replace generated development values for deployed environments.
26
+ ${state.authMode === "auth-oauth" ? `For OAuth, set real ${oauthProviderLabel(state)} client IDs, secrets, and redirect URLs in .env.\n` : ""}
27
+
28
+ Auth Features:
29
+ ${state.authMode === "base"
30
+ ? "āœ“ JWT only"
31
+ : state.authMode === "auth"
32
+ ? "āœ“ Email + Password"
33
+ : `āœ“ Password + OAuth (${oauthProviderLabel(state)})`}
34
+
35
+ šŸ›  Stack:
36
+ āœ” Express
37
+ āœ” ${state.usePrisma ? (state.database === "postgresql" ? "PostgreSQL" : "SQLite") : "No database"}
38
+ āœ” ${state.usePrisma ? "Prisma ORM" : "No ORM"}
39
+
40
+ šŸ“” API Routes:
41
+ ${state.authMode === "base"
42
+ ? `
43
+ GET /public
44
+ GET /guest
45
+ GET /protected
46
+ POST /refresh
47
+ `
48
+ : state.authMode === "auth"
49
+ ? `
50
+ POST /auth/register
51
+ POST /auth/login
52
+ POST /auth/refresh
53
+ GET /protected
54
+ `
55
+ : `
56
+ POST /auth/register
57
+ POST /auth/login
58
+ POST /auth/refresh
59
+ ${oauthRouteLines(state)}
60
+ GET /protected
61
+ `}
62
+ āœ… Done! Enjoying authenik8?
63
+ ⭐ Star us → github.com/COD434/create-authenik8-app
64
+ šŸ’¬ Drop feedback → github.com/COD434/create-authenik8-app/discussions
65
+
66
+ šŸ”„ You're ready to build.
67
+ `));
68
+ if (isProduction) {
69
+ console.log(`
70
+ šŸš€ Production Ready Enabled:
71
+
72
+ āœ” PM2 installed
73
+ āœ” Cluster mode enabled
74
+ āœ” Memory auto-restart (300MB)
75
+
76
+ Run:
77
+ npm run pm2:start
78
+ `);
79
+ }
80
+ }
81
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../../src/utils/output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,SAAS,sBAAsB,CAAC,KAAe;IAC7C,MAAM,SAAS,GAAG,KAAK,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC1D,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,QAAQ,CAC/C,CAAC;IAEF,OAAO,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAe;IACzC,OAAO,sBAAsB,CAAC,KAAK,CAAC;SACjC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;SAC9D,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED,SAAS,eAAe,CAAC,KAAe;IACtC,OAAO,sBAAsB,CAAC,KAAK,CAAC;SACjC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,kBAAkB,QAAQ,EAAE,CAAC;SAC/C,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAe,EAAE,YAAqB;IACjE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC,CAAC;IAE5E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC;;;KAGrB,KAAK,CAAC,WAAW;EACpB,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,EAAE;;;;EAIjD,KAAK,CAAC,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,uBAAuB,kBAAkB,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC,CAAC,EAAE;;;EAI3I,KAAK,CAAC,QAAQ,KAAK,MAAM;QACvB,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,KAAK,CAAC,QAAQ,KAAK,MAAM;YAC3B,CAAC,CAAC,oBAAoB;YACtB,CAAC,CAAC,uBAAuB,kBAAkB,CAAC,KAAK,CAAC,GACtD;;;;IAII,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,aAAa;IAC7F,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ;;;EAI3C,KAAK,CAAC,QAAQ,KAAK,MAAM;QACvB,CAAC,CAAC;;;;;CAKL;QACG,CAAC,CAAC,KAAK,CAAC,QAAQ,KAAK,MAAM;YAC3B,CAAC,CAAC;;;;;CAKL;YACG,CAAC,CAAC;;;;EAIJ,eAAe,CAAC,KAAK,CAAC;;CAGxB;;;;;;CAMC,CAAC,CAAC,CAAC;IAEF,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;CASf,CAAC,CAAC;IACD,CAAC;AACH,CAAC"}