create-authhero 0.36.0 → 0.38.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/dist/cloudflare/copy-assets.js +1 -1
- package/dist/create-authhero.js +106 -105
- package/dist/local/src/app.ts +1 -0
- package/dist/local/src/index.ts +3 -65
- package/package.json +1 -1
|
@@ -107,7 +107,7 @@ try {
|
|
|
107
107
|
.readFileSync(adminIndexPath, "utf-8")
|
|
108
108
|
.replace(/src="\.\/assets\//g, 'src="/admin/assets/')
|
|
109
109
|
.replace(/href="\.\/assets\//g, 'href="/admin/assets/');
|
|
110
|
-
const configScript = `<script>window.__AUTHHERO_ADMIN_CONFIG__={domain:window.location.origin,basePath:"/admin"}</script>`;
|
|
110
|
+
const configScript = `<script>window.__AUTHHERO_ADMIN_CONFIG__={domain:window.location.origin,clientId:"default",basePath:"/admin"}</script>`;
|
|
111
111
|
const injectedHtml = adminHtml.replace(
|
|
112
112
|
"</head>",
|
|
113
113
|
configScript + "\n</head>",
|
package/dist/create-authhero.js
CHANGED
|
@@ -9,10 +9,10 @@ const D = new P(), p = {
|
|
|
9
9
|
name: "Local (SQLite)",
|
|
10
10
|
description: "Local development setup with SQLite database - great for getting started",
|
|
11
11
|
templateDir: "local",
|
|
12
|
-
packageJson: (
|
|
13
|
-
const t =
|
|
12
|
+
packageJson: (a, e, n, r, o) => {
|
|
13
|
+
const t = r ? "workspace:*" : "latest";
|
|
14
14
|
return {
|
|
15
|
-
name:
|
|
15
|
+
name: a,
|
|
16
16
|
version: "1.0.0",
|
|
17
17
|
type: "module",
|
|
18
18
|
scripts: {
|
|
@@ -33,7 +33,7 @@ const D = new P(), p = {
|
|
|
33
33
|
hono: "^4.6.0",
|
|
34
34
|
kysely: "latest",
|
|
35
35
|
...e && { "@authhero/multi-tenancy": t },
|
|
36
|
-
...
|
|
36
|
+
...n && { bcryptjs: "latest" }
|
|
37
37
|
},
|
|
38
38
|
devDependencies: {
|
|
39
39
|
"@types/better-sqlite3": "^7.6.0",
|
|
@@ -49,10 +49,10 @@ const D = new P(), p = {
|
|
|
49
49
|
name: "Cloudflare Workers (D1)",
|
|
50
50
|
description: "Cloudflare Workers setup with D1 database",
|
|
51
51
|
templateDir: "cloudflare",
|
|
52
|
-
packageJson: (
|
|
53
|
-
const t =
|
|
52
|
+
packageJson: (a, e, n, r, o) => {
|
|
53
|
+
const t = r ? "workspace:*" : "latest";
|
|
54
54
|
return {
|
|
55
|
-
name:
|
|
55
|
+
name: a,
|
|
56
56
|
version: "1.0.0",
|
|
57
57
|
type: "module",
|
|
58
58
|
scripts: {
|
|
@@ -81,7 +81,7 @@ const D = new P(), p = {
|
|
|
81
81
|
kysely: "latest",
|
|
82
82
|
"kysely-d1": "latest",
|
|
83
83
|
...e && { "@authhero/multi-tenancy": t },
|
|
84
|
-
...
|
|
84
|
+
...n && { bcryptjs: "latest" }
|
|
85
85
|
},
|
|
86
86
|
devDependencies: {
|
|
87
87
|
"@cloudflare/workers-types": "^4.0.0",
|
|
@@ -98,10 +98,10 @@ const D = new P(), p = {
|
|
|
98
98
|
name: "AWS SST (Lambda + DynamoDB)",
|
|
99
99
|
description: "Serverless AWS deployment with Lambda, DynamoDB, and SST",
|
|
100
100
|
templateDir: "aws-sst",
|
|
101
|
-
packageJson: (
|
|
102
|
-
const t =
|
|
101
|
+
packageJson: (a, e, n, r, o) => {
|
|
102
|
+
const t = r ? "workspace:*" : "latest";
|
|
103
103
|
return {
|
|
104
|
-
name:
|
|
104
|
+
name: a,
|
|
105
105
|
version: "1.0.0",
|
|
106
106
|
type: "module",
|
|
107
107
|
scripts: {
|
|
@@ -122,7 +122,7 @@ const D = new P(), p = {
|
|
|
122
122
|
authhero: t,
|
|
123
123
|
hono: "^4.6.0",
|
|
124
124
|
...e && { "@authhero/multi-tenancy": t },
|
|
125
|
-
...
|
|
125
|
+
...n && { bcryptjs: "latest" }
|
|
126
126
|
},
|
|
127
127
|
devDependencies: {
|
|
128
128
|
"@types/aws-lambda": "^8.10.0",
|
|
@@ -136,22 +136,22 @@ const D = new P(), p = {
|
|
|
136
136
|
seedFile: "seed.ts"
|
|
137
137
|
}
|
|
138
138
|
};
|
|
139
|
-
function N(
|
|
140
|
-
s.readdirSync(
|
|
141
|
-
const o = i.join(
|
|
139
|
+
function N(a, e) {
|
|
140
|
+
s.readdirSync(a).forEach((r) => {
|
|
141
|
+
const o = i.join(a, r), t = i.join(e, r);
|
|
142
142
|
s.lstatSync(o).isDirectory() ? (s.mkdirSync(t, { recursive: !0 }), N(o, t)) : s.copyFileSync(o, t);
|
|
143
143
|
});
|
|
144
144
|
}
|
|
145
|
-
function R(
|
|
146
|
-
const o =
|
|
145
|
+
function R(a, e = !1, n = "authhero-local", r) {
|
|
146
|
+
const o = a ? "control_plane" : "main", t = a ? "Control Plane" : "Main", c = [
|
|
147
147
|
"https://manage.authhero.net/auth-callback",
|
|
148
148
|
"https://local.authhero.net/auth-callback",
|
|
149
149
|
"http://localhost:5173/auth-callback",
|
|
150
150
|
"https://localhost:3000/auth-callback",
|
|
151
|
-
...
|
|
151
|
+
...r ? ["https://localhost:3000/admin/auth-callback"] : []
|
|
152
152
|
], d = e ? [
|
|
153
|
-
`https://localhost.emobix.co.uk:8443/test/a/${
|
|
154
|
-
`https://localhost:8443/test/a/${
|
|
153
|
+
`https://localhost.emobix.co.uk:8443/test/a/${n}/callback`,
|
|
154
|
+
`https://localhost:8443/test/a/${n}/callback`
|
|
155
155
|
] : [], f = [...c, ...d], h = [
|
|
156
156
|
"https://manage.authhero.net",
|
|
157
157
|
"https://local.authhero.net",
|
|
@@ -162,8 +162,8 @@ function R(n, e = !1, r = "authhero-local", a) {
|
|
|
162
162
|
console.log("Creating conformance test clients and user...");
|
|
163
163
|
|
|
164
164
|
const conformanceCallbacks = [
|
|
165
|
-
"https://localhost.emobix.co.uk:8443/test/a/${
|
|
166
|
-
"https://localhost:8443/test/a/${
|
|
165
|
+
"https://localhost.emobix.co.uk:8443/test/a/${n}/callback",
|
|
166
|
+
"https://localhost:8443/test/a/${n}/callback",
|
|
167
167
|
];
|
|
168
168
|
const conformanceLogoutUrls = [
|
|
169
169
|
"https://localhost:8443/",
|
|
@@ -282,8 +282,8 @@ async function main() {
|
|
|
282
282
|
adminPassword,
|
|
283
283
|
tenantId: "${o}",
|
|
284
284
|
tenantName: "${t}",
|
|
285
|
-
isControlPlane: ${!!
|
|
286
|
-
clientId: "
|
|
285
|
+
isControlPlane: ${!!a},
|
|
286
|
+
clientId: "default"
|
|
287
287
|
callbacks: ${JSON.stringify(f)},
|
|
288
288
|
allowedLogoutUrls: ${JSON.stringify(y)},
|
|
289
289
|
});
|
|
@@ -294,9 +294,9 @@ ${S}
|
|
|
294
294
|
main().catch(console.error);
|
|
295
295
|
`;
|
|
296
296
|
}
|
|
297
|
-
function U(
|
|
298
|
-
const
|
|
299
|
-
` : "",
|
|
297
|
+
function U(a, e) {
|
|
298
|
+
const n = e ? `import fs from "fs";
|
|
299
|
+
` : "", r = e ? `
|
|
300
300
|
const adminDistPath = path.resolve(
|
|
301
301
|
__dirname,
|
|
302
302
|
"../node_modules/@authhero/react-admin/dist",
|
|
@@ -311,8 +311,8 @@ const adminIndexPath = path.join(adminDistPath, "index.html");
|
|
|
311
311
|
.replace(/src="\\.\\//g, 'src="/admin/')
|
|
312
312
|
.replace(/href="\\.\\//g, 'href="/admin/');
|
|
313
313
|
const configJson = JSON.stringify({
|
|
314
|
-
domain: issuer.replace(/\\/$/, "")
|
|
315
|
-
clientId: CONTROL_PLANE_CLIENT_ID
|
|
314
|
+
domain: issuer.replace(/\\/$/, ""),
|
|
315
|
+
clientId: ${a ? "CONTROL_PLANE_CLIENT_ID," : '"default",'}
|
|
316
316
|
basePath: "/admin",
|
|
317
317
|
}).replace(/</g, "\\\\u003c");
|
|
318
318
|
configWithHandlers.adminIndexHtml = rawHtml.replace(
|
|
@@ -325,13 +325,13 @@ const adminIndexPath = path.join(adminDistPath, "index.html");
|
|
|
325
325
|
});
|
|
326
326
|
}
|
|
327
327
|
` : "";
|
|
328
|
-
return
|
|
328
|
+
return a ? `import { Context } from "hono";
|
|
329
329
|
import { swaggerUI } from "@hono/swagger-ui";
|
|
330
330
|
import { AuthHeroConfig, DataAdapters } from "authhero";
|
|
331
331
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
332
332
|
import { initMultiTenant } from "@authhero/multi-tenancy";
|
|
333
333
|
import path from "path";
|
|
334
|
-
${
|
|
334
|
+
${n}import { fileURLToPath } from "url";
|
|
335
335
|
|
|
336
336
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
337
337
|
|
|
@@ -339,10 +339,10 @@ const widgetPath = path.resolve(
|
|
|
339
339
|
__dirname,
|
|
340
340
|
"../node_modules/@authhero/widget/dist/authhero-widget",
|
|
341
341
|
);
|
|
342
|
-
${
|
|
342
|
+
${r}
|
|
343
343
|
// Control plane configuration
|
|
344
344
|
const CONTROL_PLANE_TENANT_ID = "control_plane";
|
|
345
|
-
const CONTROL_PLANE_CLIENT_ID = "
|
|
345
|
+
const CONTROL_PLANE_CLIENT_ID = "default";
|
|
346
346
|
|
|
347
347
|
export default function createApp(config: AuthHeroConfig & { dataAdapter: DataAdapters }) {
|
|
348
348
|
const configWithHandlers: AuthHeroConfig & { dataAdapter: DataAdapters } = {
|
|
@@ -389,7 +389,7 @@ import { AuthHeroConfig, init } from "authhero";
|
|
|
389
389
|
import { swaggerUI } from "@hono/swagger-ui";
|
|
390
390
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
391
391
|
import path from "path";
|
|
392
|
-
${
|
|
392
|
+
${n}import { fileURLToPath } from "url";
|
|
393
393
|
|
|
394
394
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
395
395
|
|
|
@@ -397,7 +397,7 @@ const widgetPath = path.resolve(
|
|
|
397
397
|
__dirname,
|
|
398
398
|
"../node_modules/@authhero/widget/dist/authhero-widget",
|
|
399
399
|
);
|
|
400
|
-
${
|
|
400
|
+
${r}
|
|
401
401
|
export default function createApp(config: AuthHeroConfig) {
|
|
402
402
|
const configWithHandlers: AuthHeroConfig = {
|
|
403
403
|
...config,
|
|
@@ -430,7 +430,7 @@ ${o}
|
|
|
430
430
|
}
|
|
431
431
|
`;
|
|
432
432
|
}
|
|
433
|
-
function O(
|
|
433
|
+
function O(a) {
|
|
434
434
|
return `import { D1Dialect } from "kysely-d1";
|
|
435
435
|
import { Kysely } from "kysely";
|
|
436
436
|
import createAdapters from "@authhero/kysely-adapter";
|
|
@@ -457,9 +457,10 @@ export default {
|
|
|
457
457
|
adminUsername,
|
|
458
458
|
adminPassword,
|
|
459
459
|
issuer,
|
|
460
|
-
tenantId: "${
|
|
461
|
-
tenantName: "${
|
|
462
|
-
isControlPlane: ${!!
|
|
460
|
+
tenantId: "${a ? "control_plane" : "main"}",
|
|
461
|
+
tenantName: "${a ? "Control Plane" : "Main"}",
|
|
462
|
+
isControlPlane: ${!!a},
|
|
463
|
+
clientId: "default",
|
|
463
464
|
});
|
|
464
465
|
|
|
465
466
|
return new Response(
|
|
@@ -490,24 +491,24 @@ export default {
|
|
|
490
491
|
};
|
|
491
492
|
`;
|
|
492
493
|
}
|
|
493
|
-
function L(
|
|
494
|
-
const
|
|
495
|
-
` : "",
|
|
494
|
+
function L(a, e) {
|
|
495
|
+
const n = e ? `import adminIndexHtml from "./admin-index-html";
|
|
496
|
+
` : "", r = e ? ` adminIndexHtml,
|
|
496
497
|
` : "";
|
|
497
|
-
return
|
|
498
|
+
return a ? `import { Context } from "hono";
|
|
498
499
|
import { swaggerUI } from "@hono/swagger-ui";
|
|
499
500
|
import { AuthHeroConfig, DataAdapters } from "authhero";
|
|
500
501
|
import { initMultiTenant } from "@authhero/multi-tenancy";
|
|
501
|
-
${
|
|
502
|
+
${n}
|
|
502
503
|
// Control plane configuration
|
|
503
504
|
const CONTROL_PLANE_TENANT_ID = "control_plane";
|
|
504
|
-
const CONTROL_PLANE_CLIENT_ID = "
|
|
505
|
+
const CONTROL_PLANE_CLIENT_ID = "default";
|
|
505
506
|
|
|
506
507
|
export default function createApp(config: AuthHeroConfig & { dataAdapter: DataAdapters }) {
|
|
507
508
|
// Initialize multi-tenant AuthHero - syncs resource servers, roles, and connections by default
|
|
508
509
|
const { app } = initMultiTenant({
|
|
509
510
|
...config,
|
|
510
|
-
${
|
|
511
|
+
${r} controlPlane: {
|
|
511
512
|
tenantId: CONTROL_PLANE_TENANT_ID,
|
|
512
513
|
clientId: CONTROL_PLANE_CLIENT_ID,
|
|
513
514
|
},
|
|
@@ -539,11 +540,11 @@ ${a} controlPlane: {
|
|
|
539
540
|
import { cors } from "hono/cors";
|
|
540
541
|
import { AuthHeroConfig, init } from "authhero";
|
|
541
542
|
import { swaggerUI } from "@hono/swagger-ui";
|
|
542
|
-
${
|
|
543
|
+
${n}
|
|
543
544
|
export default function createApp(config: AuthHeroConfig) {
|
|
544
545
|
const { app } = init({
|
|
545
546
|
...config,
|
|
546
|
-
${
|
|
547
|
+
${r} });
|
|
547
548
|
|
|
548
549
|
// Enable CORS for all origins in development
|
|
549
550
|
app.use("*", cors({
|
|
@@ -575,15 +576,15 @@ ${a} });
|
|
|
575
576
|
}
|
|
576
577
|
`;
|
|
577
578
|
}
|
|
578
|
-
function j(
|
|
579
|
-
return
|
|
579
|
+
function j(a) {
|
|
580
|
+
return a ? `import { Context } from "hono";
|
|
580
581
|
import { swaggerUI } from "@hono/swagger-ui";
|
|
581
582
|
import { AuthHeroConfig, DataAdapters } from "authhero";
|
|
582
583
|
import { initMultiTenant } from "@authhero/multi-tenancy";
|
|
583
584
|
|
|
584
585
|
// Control plane configuration
|
|
585
586
|
const CONTROL_PLANE_TENANT_ID = "control_plane";
|
|
586
|
-
const CONTROL_PLANE_CLIENT_ID = "
|
|
587
|
+
const CONTROL_PLANE_CLIENT_ID = "default";
|
|
587
588
|
|
|
588
589
|
interface AppConfig extends AuthHeroConfig {
|
|
589
590
|
dataAdapter: DataAdapters;
|
|
@@ -681,7 +682,7 @@ export default function createApp(config: AppConfig) {
|
|
|
681
682
|
}
|
|
682
683
|
`;
|
|
683
684
|
}
|
|
684
|
-
function $(
|
|
685
|
+
function $(a) {
|
|
685
686
|
return `import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
|
|
686
687
|
import { DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb";
|
|
687
688
|
import createAdapters from "@authhero/aws";
|
|
@@ -710,9 +711,9 @@ async function main() {
|
|
|
710
711
|
await seed(adapters, {
|
|
711
712
|
adminUsername,
|
|
712
713
|
adminPassword,
|
|
713
|
-
tenantId: "${
|
|
714
|
-
tenantName: "${
|
|
715
|
-
isControlPlane: ${!!
|
|
714
|
+
tenantId: "${a ? "control_plane" : "main"}",
|
|
715
|
+
tenantName: "${a ? "Control Plane" : "Main"}",
|
|
716
|
+
isControlPlane: ${!!a},
|
|
716
717
|
});
|
|
717
718
|
|
|
718
719
|
console.log("✅ Database seeded successfully!");
|
|
@@ -721,23 +722,23 @@ async function main() {
|
|
|
721
722
|
main().catch(console.error);
|
|
722
723
|
`;
|
|
723
724
|
}
|
|
724
|
-
function H(
|
|
725
|
-
const
|
|
725
|
+
function H(a, e) {
|
|
726
|
+
const n = i.join(a, "src");
|
|
726
727
|
s.writeFileSync(
|
|
727
|
-
i.join(
|
|
728
|
+
i.join(n, "app.ts"),
|
|
728
729
|
j(e)
|
|
729
730
|
), s.writeFileSync(
|
|
730
|
-
i.join(
|
|
731
|
+
i.join(n, "seed.ts"),
|
|
731
732
|
$(e)
|
|
732
733
|
);
|
|
733
734
|
}
|
|
734
|
-
function
|
|
735
|
+
function x() {
|
|
735
736
|
console.log("\\n" + "─".repeat(50)), console.log("🔐 AuthHero deployed to AWS!"), console.log("📚 Check SST output for your API URL"), console.log("🚀 Open your server URL /setup to complete initial setup"), console.log("🌐 Portal available at https://local.authhero.net"), console.log("─".repeat(50) + "\\n");
|
|
736
737
|
}
|
|
737
|
-
function M(
|
|
738
|
-
const e = i.join(
|
|
738
|
+
function M(a) {
|
|
739
|
+
const e = i.join(a, ".github", "workflows");
|
|
739
740
|
s.mkdirSync(e, { recursive: !0 });
|
|
740
|
-
const
|
|
741
|
+
const n = `name: Unit tests
|
|
741
742
|
|
|
742
743
|
on: push
|
|
743
744
|
|
|
@@ -758,7 +759,7 @@ jobs:
|
|
|
758
759
|
|
|
759
760
|
- run: npm run type-check
|
|
760
761
|
- run: npm test
|
|
761
|
-
`,
|
|
762
|
+
`, r = `name: Deploy to Dev
|
|
762
763
|
|
|
763
764
|
on:
|
|
764
765
|
push:
|
|
@@ -823,9 +824,9 @@ jobs:
|
|
|
823
824
|
apiToken: \${{ secrets.PROD_CLOUDFLARE_API_TOKEN }}
|
|
824
825
|
command: deploy --env production
|
|
825
826
|
`;
|
|
826
|
-
s.writeFileSync(i.join(e, "unit-tests.yml"),
|
|
827
|
+
s.writeFileSync(i.join(e, "unit-tests.yml"), n), s.writeFileSync(i.join(e, "deploy-dev.yml"), r), s.writeFileSync(i.join(e, "release.yml"), o), console.log("\\n📦 GitHub CI workflows created!");
|
|
827
828
|
}
|
|
828
|
-
function F(
|
|
829
|
+
function F(a) {
|
|
829
830
|
const e = {
|
|
830
831
|
branches: ["main"],
|
|
831
832
|
plugins: [
|
|
@@ -835,42 +836,42 @@ function F(n) {
|
|
|
835
836
|
]
|
|
836
837
|
};
|
|
837
838
|
s.writeFileSync(
|
|
838
|
-
i.join(
|
|
839
|
+
i.join(a, ".releaserc.json"),
|
|
839
840
|
JSON.stringify(e, null, 2)
|
|
840
841
|
);
|
|
841
|
-
const
|
|
842
|
-
|
|
843
|
-
...
|
|
842
|
+
const n = i.join(a, "package.json"), r = JSON.parse(s.readFileSync(n, "utf-8"));
|
|
843
|
+
r.devDependencies = {
|
|
844
|
+
...r.devDependencies,
|
|
844
845
|
"semantic-release": "^24.0.0"
|
|
845
|
-
},
|
|
846
|
-
...
|
|
846
|
+
}, r.scripts = {
|
|
847
|
+
...r.scripts,
|
|
847
848
|
test: 'echo "No tests yet"',
|
|
848
849
|
"type-check": "tsc --noEmit"
|
|
849
|
-
}, s.writeFileSync(
|
|
850
|
+
}, s.writeFileSync(n, JSON.stringify(r, null, 2));
|
|
850
851
|
}
|
|
851
|
-
function b(
|
|
852
|
-
return new Promise((
|
|
853
|
-
const o = E(
|
|
852
|
+
function b(a, e) {
|
|
853
|
+
return new Promise((n, r) => {
|
|
854
|
+
const o = E(a, [], {
|
|
854
855
|
cwd: e,
|
|
855
856
|
shell: !0,
|
|
856
857
|
stdio: "inherit"
|
|
857
858
|
});
|
|
858
859
|
o.on("close", (t) => {
|
|
859
|
-
t === 0 ?
|
|
860
|
-
}), o.on("error",
|
|
860
|
+
t === 0 ? n() : r(new Error(`Command failed with exit code ${t}`));
|
|
861
|
+
}), o.on("error", r);
|
|
861
862
|
});
|
|
862
863
|
}
|
|
863
|
-
function W(
|
|
864
|
-
const
|
|
864
|
+
function W(a, e, n) {
|
|
865
|
+
const r = i.join(a, "src");
|
|
865
866
|
s.writeFileSync(
|
|
866
|
-
i.join(
|
|
867
|
-
L(e,
|
|
867
|
+
i.join(r, "app.ts"),
|
|
868
|
+
L(e, n)
|
|
868
869
|
), s.writeFileSync(
|
|
869
|
-
i.join(
|
|
870
|
+
i.join(r, "seed.ts"),
|
|
870
871
|
O(e)
|
|
871
872
|
);
|
|
872
873
|
}
|
|
873
|
-
function
|
|
874
|
+
function _() {
|
|
874
875
|
console.log(`
|
|
875
876
|
` + "─".repeat(50)), console.log("🔐 AuthHero server running at https://localhost:3000"), console.log("📚 API documentation available at https://localhost:3000/docs"), console.log("🚀 Open https://localhost:3000/setup to complete initial setup"), console.log("🌐 Portal available at https://local.authhero.net"), console.log("─".repeat(50) + `
|
|
876
877
|
`);
|
|
@@ -889,13 +890,13 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
889
890
|
).option(
|
|
890
891
|
"--workspace",
|
|
891
892
|
"use workspace:* dependencies for local monorepo development"
|
|
892
|
-
).option("-y, --yes", "skip all prompts and use defaults/provided options").action(async (
|
|
893
|
-
const
|
|
893
|
+
).option("-y, --yes", "skip all prompts and use defaults/provided options").action(async (a, e) => {
|
|
894
|
+
const n = e.yes === !0;
|
|
894
895
|
console.log(`
|
|
895
896
|
🔐 Welcome to AuthHero!
|
|
896
897
|
`);
|
|
897
|
-
let
|
|
898
|
-
|
|
898
|
+
let r = a;
|
|
899
|
+
r || (n ? (r = "auth-server", console.log(`Using default project name: ${r}`)) : r = (await m.prompt([
|
|
899
900
|
{
|
|
900
901
|
type: "input",
|
|
901
902
|
name: "projectName",
|
|
@@ -904,8 +905,8 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
904
905
|
validate: (u) => u !== "" || "Project name cannot be empty"
|
|
905
906
|
}
|
|
906
907
|
])).projectName);
|
|
907
|
-
const o = i.join(process.cwd(),
|
|
908
|
-
s.existsSync(o) && (console.error(`❌ Project "${
|
|
908
|
+
const o = i.join(process.cwd(), r);
|
|
909
|
+
s.existsSync(o) && (console.error(`❌ Project "${r}" already exists.`), process.exit(1));
|
|
909
910
|
let t;
|
|
910
911
|
e.template ? (["local", "cloudflare", "aws-sst"].includes(e.template) || (console.error(`❌ Invalid template: ${e.template}`), console.error("Valid options: local, cloudflare, aws-sst"), process.exit(1)), t = e.template, console.log(`Using template: ${p[t].name}`)) : t = (await m.prompt([
|
|
911
912
|
{
|
|
@@ -935,7 +936,7 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
935
936
|
}
|
|
936
937
|
])).setupType;
|
|
937
938
|
let c;
|
|
938
|
-
e.multiTenant !== void 0 ? c = e.multiTenant :
|
|
939
|
+
e.multiTenant !== void 0 ? c = e.multiTenant : n ? c = !1 : c = (await m.prompt([
|
|
939
940
|
{
|
|
940
941
|
type: "confirm",
|
|
941
942
|
name: "multiTenant",
|
|
@@ -944,7 +945,7 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
944
945
|
}
|
|
945
946
|
])).multiTenant, c && console.log("Multi-tenant mode: enabled");
|
|
946
947
|
let d = !1;
|
|
947
|
-
(t === "local" || t === "cloudflare") && (e.adminUi !== void 0 ? d = e.adminUi :
|
|
948
|
+
(t === "local" || t === "cloudflare") && (e.adminUi !== void 0 ? d = e.adminUi : n ? d = !0 : d = (await m.prompt([
|
|
948
949
|
{
|
|
949
950
|
type: "confirm",
|
|
950
951
|
name: "adminUi",
|
|
@@ -963,7 +964,7 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
963
964
|
i.join(o, "package.json"),
|
|
964
965
|
JSON.stringify(
|
|
965
966
|
y.packageJson(
|
|
966
|
-
|
|
967
|
+
r,
|
|
967
968
|
c,
|
|
968
969
|
f,
|
|
969
970
|
C,
|
|
@@ -973,11 +974,11 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
973
974
|
2
|
|
974
975
|
)
|
|
975
976
|
);
|
|
976
|
-
const S = y.templateDir,
|
|
977
|
+
const S = y.templateDir, I = i.join(
|
|
977
978
|
import.meta.url.replace("file://", "").replace("/create-authhero.js", ""),
|
|
978
979
|
S
|
|
979
980
|
);
|
|
980
|
-
if (s.existsSync(
|
|
981
|
+
if (s.existsSync(I) ? N(I, o) : (console.error(`❌ Template directory not found: ${I}`), process.exit(1)), t === "cloudflare" && W(o, c, d), t === "cloudflare") {
|
|
981
982
|
const l = i.join(o, "wrangler.toml"), u = i.join(o, "wrangler.local.toml");
|
|
982
983
|
s.existsSync(l) && s.copyFileSync(l, u);
|
|
983
984
|
const g = i.join(o, ".dev.vars.example"), w = i.join(o, ".dev.vars");
|
|
@@ -986,7 +987,7 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
986
987
|
);
|
|
987
988
|
}
|
|
988
989
|
let A = !1;
|
|
989
|
-
if (t === "cloudflare" && (e.githubCi !== void 0 ? (A = e.githubCi, A && console.log("Including GitHub CI workflows with semantic versioning")) :
|
|
990
|
+
if (t === "cloudflare" && (e.githubCi !== void 0 ? (A = e.githubCi, A && console.log("Including GitHub CI workflows with semantic versioning")) : n || (A = (await m.prompt([
|
|
990
991
|
{
|
|
991
992
|
type: "confirm",
|
|
992
993
|
name: "includeGithubCi",
|
|
@@ -1033,11 +1034,11 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
1033
1034
|
const T = c ? "multi-tenant" : "single-tenant";
|
|
1034
1035
|
console.log(
|
|
1035
1036
|
`
|
|
1036
|
-
✅ Project "${
|
|
1037
|
+
✅ Project "${r}" has been created with ${y.name} (${T}) setup!
|
|
1037
1038
|
`
|
|
1038
1039
|
);
|
|
1039
1040
|
let v;
|
|
1040
|
-
if (e.skipInstall ? v = !1 :
|
|
1041
|
+
if (e.skipInstall ? v = !1 : n ? v = !0 : v = (await m.prompt([
|
|
1041
1042
|
{
|
|
1042
1043
|
type: "confirm",
|
|
1043
1044
|
name: "shouldInstall",
|
|
@@ -1048,7 +1049,7 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
1048
1049
|
let l;
|
|
1049
1050
|
e.packageManager ? (["npm", "yarn", "pnpm", "bun"].includes(e.packageManager) || (console.error(
|
|
1050
1051
|
`❌ Invalid package manager: ${e.packageManager}`
|
|
1051
|
-
), console.error("Valid options: npm, yarn, pnpm, bun"), process.exit(1)), l = e.packageManager) :
|
|
1052
|
+
), console.error("Valid options: npm, yarn, pnpm, bun"), process.exit(1)), l = e.packageManager) : n ? l = "pnpm" : l = (await m.prompt([
|
|
1052
1053
|
{
|
|
1053
1054
|
type: "list",
|
|
1054
1055
|
name: "packageManager",
|
|
@@ -1072,7 +1073,7 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
1072
1073
|
✅ Dependencies installed successfully!
|
|
1073
1074
|
`), (t === "local" || t === "cloudflare") && !e.skipMigrate) {
|
|
1074
1075
|
let w;
|
|
1075
|
-
|
|
1076
|
+
n ? w = !0 : w = (await m.prompt([
|
|
1076
1077
|
{
|
|
1077
1078
|
type: "confirm",
|
|
1078
1079
|
name: "shouldMigrate",
|
|
@@ -1084,23 +1085,23 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
1084
1085
|
`), await b(`${l} run migrate`, o));
|
|
1085
1086
|
}
|
|
1086
1087
|
let g;
|
|
1087
|
-
e.skipStart ||
|
|
1088
|
+
e.skipStart || n ? g = !1 : g = (await m.prompt([
|
|
1088
1089
|
{
|
|
1089
1090
|
type: "confirm",
|
|
1090
1091
|
name: "shouldStart",
|
|
1091
1092
|
message: "Would you like to start the development server?",
|
|
1092
1093
|
default: !0
|
|
1093
1094
|
}
|
|
1094
|
-
])).shouldStart, g && (t === "cloudflare" ?
|
|
1095
|
-
`), await b(`${l} run dev`, o)),
|
|
1095
|
+
])).shouldStart, g && (t === "cloudflare" ? _() : t === "aws-sst" ? x() : k(), console.log(`🚀 Starting development server...
|
|
1096
|
+
`), await b(`${l} run dev`, o)), n && !g && (console.log(`
|
|
1096
1097
|
✅ Setup complete!`), console.log(`
|
|
1097
|
-
To start the development server:`), console.log(` cd ${
|
|
1098
|
+
To start the development server:`), console.log(` cd ${r}`), console.log(" npm run dev"), t === "cloudflare" ? _() : t === "aws-sst" ? x() : k());
|
|
1098
1099
|
} catch (u) {
|
|
1099
1100
|
console.error(`
|
|
1100
1101
|
❌ An error occurred:`, u), process.exit(1);
|
|
1101
1102
|
}
|
|
1102
1103
|
}
|
|
1103
|
-
v || (console.log("Next steps:"), console.log(` cd ${
|
|
1104
|
+
v || (console.log("Next steps:"), console.log(` cd ${r}`), t === "local" ? (console.log(" npm install"), console.log(" npm run migrate"), console.log(" npm run dev"), console.log(
|
|
1104
1105
|
`
|
|
1105
1106
|
Open https://localhost:3000/setup to complete initial setup`
|
|
1106
1107
|
)) : t === "cloudflare" ? (console.log(" npm install"), console.log(
|
package/dist/local/src/app.ts
CHANGED
|
@@ -40,6 +40,7 @@ export default function createApp(config: AuthHeroConfig) {
|
|
|
40
40
|
.replace(/href="\.\/assets\//g, 'href="/admin/assets/');
|
|
41
41
|
const configJson = JSON.stringify({
|
|
42
42
|
domain: issuer.replace(/\/$/, ""),
|
|
43
|
+
clientId: "default",
|
|
43
44
|
basePath: "/admin",
|
|
44
45
|
}).replace(/</g, "\\u003c");
|
|
45
46
|
configWithHandlers.adminIndexHtml = rawHtml.replace(
|
package/dist/local/src/index.ts
CHANGED
|
@@ -4,62 +4,6 @@ import { Kysely } from "kysely";
|
|
|
4
4
|
import Database from "better-sqlite3";
|
|
5
5
|
import createAdapters from "@authhero/kysely-adapter";
|
|
6
6
|
import createApp from "./app";
|
|
7
|
-
import fs from "fs";
|
|
8
|
-
import path from "path";
|
|
9
|
-
import { execSync } from "child_process";
|
|
10
|
-
import https from "https";
|
|
11
|
-
|
|
12
|
-
// Generate self-signed certificates for local HTTPS if they don't exist
|
|
13
|
-
const certDir = path.join(process.cwd(), ".certs");
|
|
14
|
-
const keyPath = path.join(certDir, "localhost-key.pem");
|
|
15
|
-
const certPath = path.join(certDir, "localhost.pem");
|
|
16
|
-
|
|
17
|
-
function ensureCertificates() {
|
|
18
|
-
if (!fs.existsSync(certDir)) {
|
|
19
|
-
fs.mkdirSync(certDir, { recursive: true });
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (!fs.existsSync(keyPath) || !fs.existsSync(certPath)) {
|
|
23
|
-
console.log("🔑 Generating self-signed certificates for local HTTPS...");
|
|
24
|
-
|
|
25
|
-
// Try mkcert first (if installed), otherwise fall back to openssl
|
|
26
|
-
try {
|
|
27
|
-
execSync(`which mkcert`, { stdio: "ignore" });
|
|
28
|
-
execSync(
|
|
29
|
-
`mkcert -key-file ${keyPath} -cert-file ${certPath} localhost 127.0.0.1`,
|
|
30
|
-
{
|
|
31
|
-
stdio: "inherit",
|
|
32
|
-
},
|
|
33
|
-
);
|
|
34
|
-
console.log("✅ Certificates generated with mkcert");
|
|
35
|
-
} catch {
|
|
36
|
-
// Fall back to openssl
|
|
37
|
-
try {
|
|
38
|
-
execSync(
|
|
39
|
-
`openssl req -x509 -newkey rsa:2048 -keyout "${keyPath}" -out "${certPath}" -days 365 -nodes -subj "/CN=localhost"`,
|
|
40
|
-
{ stdio: "inherit" },
|
|
41
|
-
);
|
|
42
|
-
console.log("✅ Self-signed certificates generated with openssl");
|
|
43
|
-
console.log(
|
|
44
|
-
"⚠️ You may need to trust the certificate in your browser",
|
|
45
|
-
);
|
|
46
|
-
} catch (err) {
|
|
47
|
-
console.error(
|
|
48
|
-
"❌ Failed to generate certificates. Please install mkcert or openssl",
|
|
49
|
-
);
|
|
50
|
-
console.error(
|
|
51
|
-
" Install mkcert: brew install mkcert && mkcert -install",
|
|
52
|
-
);
|
|
53
|
-
process.exit(1);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
key: fs.readFileSync(keyPath),
|
|
60
|
-
cert: fs.readFileSync(certPath),
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
7
|
|
|
64
8
|
// Initialize SQLite database
|
|
65
9
|
let db: Kysely<any>;
|
|
@@ -90,19 +34,15 @@ const app = createApp({
|
|
|
90
34
|
"https://manage.authhero.net",
|
|
91
35
|
"https://local.authhero.net",
|
|
92
36
|
"http://localhost:5173",
|
|
93
|
-
"https://localhost:5173",
|
|
94
37
|
],
|
|
95
38
|
});
|
|
96
39
|
|
|
97
40
|
// Start the server
|
|
98
41
|
const port = Number(process.env.PORT) || 3000;
|
|
99
|
-
const issuer = process.env.ISSUER || `
|
|
100
|
-
|
|
101
|
-
// Get or generate certificates
|
|
102
|
-
const { key, cert } = ensureCertificates();
|
|
42
|
+
const issuer = process.env.ISSUER || `http://localhost:${port}/`;
|
|
103
43
|
|
|
104
|
-
console.log(`🔐 AuthHero server running at
|
|
105
|
-
console.log(`📚 API documentation available at
|
|
44
|
+
console.log(`🔐 AuthHero server running at http://localhost:${port}`);
|
|
45
|
+
console.log(`📚 API documentation available at http://localhost:${port}/docs`);
|
|
106
46
|
console.log(`🌐 Portal available at https://local.authhero.net`);
|
|
107
47
|
|
|
108
48
|
serve({
|
|
@@ -113,6 +53,4 @@ serve({
|
|
|
113
53
|
});
|
|
114
54
|
},
|
|
115
55
|
port,
|
|
116
|
-
createServer: https.createServer,
|
|
117
|
-
serverOptions: { key, cert },
|
|
118
56
|
});
|