create-authhero 0.33.0 โ 0.35.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 +35 -0
- package/dist/create-authhero.js +247 -196
- package/dist/local/src/app.ts +31 -3
- package/dist/local/src/index.ts +1 -0
- package/package.json +2 -1
|
@@ -86,6 +86,41 @@ try {
|
|
|
86
86
|
);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
// Copy admin UI files from @authhero/react-admin package
|
|
90
|
+
const adminSourceDir = path.join(
|
|
91
|
+
__dirname,
|
|
92
|
+
"node_modules",
|
|
93
|
+
"@authhero",
|
|
94
|
+
"react-admin",
|
|
95
|
+
"dist",
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
if (fs.existsSync(adminSourceDir)) {
|
|
99
|
+
console.log("๐ฆ Copying admin UI assets...");
|
|
100
|
+
const adminTargetDir = path.join(targetDir, "admin");
|
|
101
|
+
copyDirectory(adminSourceDir, adminTargetDir);
|
|
102
|
+
|
|
103
|
+
// Inject runtime config into index.html
|
|
104
|
+
// Uses window.location.origin so the admin UI automatically points to its own server
|
|
105
|
+
const adminIndexPath = path.join(adminSourceDir, "index.html");
|
|
106
|
+
const adminHtml = fs.readFileSync(adminIndexPath, "utf-8")
|
|
107
|
+
.replace(/src="\.\/assets\//g, 'src="/admin/assets/')
|
|
108
|
+
.replace(/href="\.\/assets\//g, 'href="/admin/assets/');
|
|
109
|
+
const configScript = `<script>window.__AUTHHERO_ADMIN_CONFIG__={domain:window.location.origin,basePath:"/admin"}</script>`;
|
|
110
|
+
const injectedHtml = adminHtml.replace("</head>", configScript + "\n</head>");
|
|
111
|
+
|
|
112
|
+
// Write injected HTML to CDN assets (for direct /admin/ access)
|
|
113
|
+
fs.writeFileSync(path.join(adminTargetDir, "index.html"), injectedHtml);
|
|
114
|
+
|
|
115
|
+
// Write as TS module for worker to import (for SPA fallback on deep links)
|
|
116
|
+
const srcDir = path.join(__dirname, "src");
|
|
117
|
+
fs.writeFileSync(
|
|
118
|
+
path.join(srcDir, "admin-index-html.ts"),
|
|
119
|
+
`export default ${JSON.stringify(injectedHtml)};\n`,
|
|
120
|
+
);
|
|
121
|
+
console.log("โ
Admin UI assets copied and configured");
|
|
122
|
+
}
|
|
123
|
+
|
|
89
124
|
console.log(`โ
Assets copied to ${targetDir}`);
|
|
90
125
|
} catch (error) {
|
|
91
126
|
console.error("โ Error copying assets:", error.message);
|
package/dist/create-authhero.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { Command as
|
|
2
|
+
import { Command as P } from "commander";
|
|
3
3
|
import m from "inquirer";
|
|
4
|
-
import
|
|
5
|
-
import
|
|
4
|
+
import s from "fs";
|
|
5
|
+
import i from "path";
|
|
6
6
|
import { spawn as E } from "child_process";
|
|
7
|
-
const
|
|
7
|
+
const D = new P(), p = {
|
|
8
8
|
local: {
|
|
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: (n, e, r, a, o) => {
|
|
13
|
+
const t = a ? "workspace:*" : "latest";
|
|
14
14
|
return {
|
|
15
|
-
name:
|
|
15
|
+
name: n,
|
|
16
16
|
version: "1.0.0",
|
|
17
17
|
type: "module",
|
|
18
18
|
scripts: {
|
|
@@ -23,6 +23,7 @@ const T = new I(), p = {
|
|
|
23
23
|
},
|
|
24
24
|
dependencies: {
|
|
25
25
|
"@authhero/kysely-adapter": t,
|
|
26
|
+
...o && { "@authhero/react-admin": t },
|
|
26
27
|
"@authhero/widget": t,
|
|
27
28
|
"@hono/swagger-ui": "^0.5.0",
|
|
28
29
|
"@hono/zod-openapi": "^0.19.0",
|
|
@@ -48,10 +49,10 @@ const T = new I(), p = {
|
|
|
48
49
|
name: "Cloudflare Workers (D1)",
|
|
49
50
|
description: "Cloudflare Workers setup with D1 database",
|
|
50
51
|
templateDir: "cloudflare",
|
|
51
|
-
packageJson: (
|
|
52
|
-
const t =
|
|
52
|
+
packageJson: (n, e, r, a, o) => {
|
|
53
|
+
const t = a ? "workspace:*" : "latest";
|
|
53
54
|
return {
|
|
54
|
-
name:
|
|
55
|
+
name: n,
|
|
55
56
|
version: "1.0.0",
|
|
56
57
|
type: "module",
|
|
57
58
|
scripts: {
|
|
@@ -71,6 +72,7 @@ const T = new I(), p = {
|
|
|
71
72
|
dependencies: {
|
|
72
73
|
"@authhero/drizzle": t,
|
|
73
74
|
"@authhero/kysely-adapter": t,
|
|
75
|
+
...o && { "@authhero/react-admin": t },
|
|
74
76
|
"@authhero/widget": t,
|
|
75
77
|
"@hono/swagger-ui": "^0.5.0",
|
|
76
78
|
"@hono/zod-openapi": "^0.19.0",
|
|
@@ -96,10 +98,10 @@ const T = new I(), p = {
|
|
|
96
98
|
name: "AWS SST (Lambda + DynamoDB)",
|
|
97
99
|
description: "Serverless AWS deployment with Lambda, DynamoDB, and SST",
|
|
98
100
|
templateDir: "aws-sst",
|
|
99
|
-
packageJson: (
|
|
100
|
-
const t =
|
|
101
|
+
packageJson: (n, e, r, a, o) => {
|
|
102
|
+
const t = a ? "workspace:*" : "latest";
|
|
101
103
|
return {
|
|
102
|
-
name:
|
|
104
|
+
name: n,
|
|
103
105
|
version: "1.0.0",
|
|
104
106
|
type: "module",
|
|
105
107
|
scripts: {
|
|
@@ -111,6 +113,7 @@ const T = new I(), p = {
|
|
|
111
113
|
},
|
|
112
114
|
dependencies: {
|
|
113
115
|
"@authhero/aws": t,
|
|
116
|
+
...o && { "@authhero/react-admin": t },
|
|
114
117
|
"@authhero/widget": t,
|
|
115
118
|
"@aws-sdk/client-dynamodb": "^3.0.0",
|
|
116
119
|
"@aws-sdk/lib-dynamodb": "^3.0.0",
|
|
@@ -133,27 +136,28 @@ const T = new I(), p = {
|
|
|
133
136
|
seedFile: "seed.ts"
|
|
134
137
|
}
|
|
135
138
|
};
|
|
136
|
-
function N(
|
|
137
|
-
|
|
138
|
-
const
|
|
139
|
-
|
|
139
|
+
function N(n, e) {
|
|
140
|
+
s.readdirSync(n).forEach((a) => {
|
|
141
|
+
const o = i.join(n, a), t = i.join(e, a);
|
|
142
|
+
s.lstatSync(o).isDirectory() ? (s.mkdirSync(t, { recursive: !0 }), N(o, t)) : s.copyFileSync(o, t);
|
|
140
143
|
});
|
|
141
144
|
}
|
|
142
|
-
function
|
|
143
|
-
const
|
|
145
|
+
function R(n, e = !1, r = "authhero-local", a) {
|
|
146
|
+
const o = n ? "control_plane" : "main", t = n ? "Control Plane" : "Main", c = [
|
|
144
147
|
"https://manage.authhero.net/auth-callback",
|
|
145
148
|
"https://local.authhero.net/auth-callback",
|
|
146
149
|
"http://localhost:5173/auth-callback",
|
|
147
|
-
"https://localhost:3000/auth-callback"
|
|
148
|
-
|
|
150
|
+
"https://localhost:3000/auth-callback",
|
|
151
|
+
...a ? ["https://localhost:3000/admin/auth-callback"] : []
|
|
152
|
+
], d = e ? [
|
|
149
153
|
`https://localhost.emobix.co.uk:8443/test/a/${r}/callback`,
|
|
150
154
|
`https://localhost:8443/test/a/${r}/callback`
|
|
151
|
-
] : [],
|
|
155
|
+
] : [], f = [...c, ...d], h = [
|
|
152
156
|
"https://manage.authhero.net",
|
|
153
157
|
"https://local.authhero.net",
|
|
154
158
|
"http://localhost:5173",
|
|
155
159
|
"https://localhost:3000"
|
|
156
|
-
],
|
|
160
|
+
], C = e ? ["https://localhost:8443/", "https://localhost.emobix.co.uk:8443/"] : [], y = [...h, ...C], S = e ? `
|
|
157
161
|
// Create OpenID Conformance Suite test clients and user
|
|
158
162
|
console.log("Creating conformance test clients and user...");
|
|
159
163
|
|
|
@@ -171,7 +175,7 @@ function P(o, e = !1, r = "authhero-local") {
|
|
|
171
175
|
];
|
|
172
176
|
|
|
173
177
|
try {
|
|
174
|
-
await adapters.clients.create("${
|
|
178
|
+
await adapters.clients.create("${o}", {
|
|
175
179
|
client_id: "conformance-test",
|
|
176
180
|
client_secret: "conformanceTestSecret123",
|
|
177
181
|
name: "Conformance Test Client",
|
|
@@ -189,7 +193,7 @@ function P(o, e = !1, r = "authhero-local") {
|
|
|
189
193
|
}
|
|
190
194
|
|
|
191
195
|
try {
|
|
192
|
-
await adapters.clients.create("${
|
|
196
|
+
await adapters.clients.create("${o}", {
|
|
193
197
|
client_id: "conformance-test2",
|
|
194
198
|
client_secret: "conformanceTestSecret456",
|
|
195
199
|
name: "Conformance Test Client 2",
|
|
@@ -209,7 +213,7 @@ function P(o, e = !1, r = "authhero-local") {
|
|
|
209
213
|
// Create a conformance test user with ALL OIDC profile claims populated
|
|
210
214
|
// This is required for OIDCC-5.4 (VerifyScopesReturnedInUserInfoClaims) test
|
|
211
215
|
try {
|
|
212
|
-
await adapters.users.create("${
|
|
216
|
+
await adapters.users.create("${o}", {
|
|
213
217
|
user_id: \`\${USERNAME_PASSWORD_PROVIDER}|conformance-user\`,
|
|
214
218
|
email: "conformance@example.com",
|
|
215
219
|
email_verified: true,
|
|
@@ -244,7 +248,7 @@ function P(o, e = !1, r = "authhero-local") {
|
|
|
244
248
|
try {
|
|
245
249
|
const bcrypt = await import("bcryptjs");
|
|
246
250
|
const hashedPassword = await bcrypt.hash("ConformanceTest123!", 10);
|
|
247
|
-
await adapters.passwords.create("${
|
|
251
|
+
await adapters.passwords.create("${o}", {
|
|
248
252
|
user_id: \`\${USERNAME_PASSWORD_PROVIDER}|conformance-user\`,
|
|
249
253
|
password: hashedPassword,
|
|
250
254
|
});
|
|
@@ -276,34 +280,82 @@ async function main() {
|
|
|
276
280
|
await seed(adapters, {
|
|
277
281
|
adminUsername,
|
|
278
282
|
adminPassword,
|
|
279
|
-
tenantId: "${
|
|
283
|
+
tenantId: "${o}",
|
|
280
284
|
tenantName: "${t}",
|
|
281
|
-
isControlPlane: ${
|
|
282
|
-
|
|
283
|
-
|
|
285
|
+
isControlPlane: ${!!n},${n ? `
|
|
286
|
+
clientId: "default_client",` : ""}
|
|
287
|
+
callbacks: ${JSON.stringify(f)},
|
|
288
|
+
allowedLogoutUrls: ${JSON.stringify(y)},
|
|
284
289
|
});
|
|
285
|
-
${
|
|
290
|
+
${S}
|
|
286
291
|
await db.destroy();
|
|
287
292
|
}
|
|
288
293
|
|
|
289
294
|
main().catch(console.error);
|
|
290
295
|
`;
|
|
291
296
|
}
|
|
292
|
-
function
|
|
293
|
-
|
|
297
|
+
function U(n, e) {
|
|
298
|
+
const r = e ? `import fs from "fs";
|
|
299
|
+
` : "", a = e ? `
|
|
300
|
+
const adminDistPath = path.resolve(
|
|
301
|
+
__dirname,
|
|
302
|
+
"../node_modules/@authhero/react-admin/dist",
|
|
303
|
+
);
|
|
304
|
+
const adminIndexPath = path.join(adminDistPath, "index.html");
|
|
305
|
+
` : "", o = e ? `
|
|
306
|
+
// Add admin UI handler if the package is installed
|
|
307
|
+
if (fs.existsSync(adminIndexPath)) {
|
|
308
|
+
const issuer =
|
|
309
|
+
process.env.ISSUER || \`https://localhost:\${process.env.PORT || 3000}/\`;
|
|
310
|
+
const rawHtml = fs.readFileSync(adminIndexPath, "utf-8")
|
|
311
|
+
.replace(/src="\\.\\//g, 'src="/admin/')
|
|
312
|
+
.replace(/href="\\.\\//g, 'href="/admin/');
|
|
313
|
+
const configJson = JSON.stringify({
|
|
314
|
+
domain: issuer.replace(/\\/$/, ""),${n ? `
|
|
315
|
+
clientId: CONTROL_PLANE_CLIENT_ID,` : ""}
|
|
316
|
+
basePath: "/admin",
|
|
317
|
+
}).replace(/</g, "\\\\u003c");
|
|
318
|
+
configWithHandlers.adminIndexHtml = rawHtml.replace(
|
|
319
|
+
"</head>",
|
|
320
|
+
\`<script>window.__AUTHHERO_ADMIN_CONFIG__=\${configJson};<\/script>\\n</head>\`,
|
|
321
|
+
);
|
|
322
|
+
configWithHandlers.adminHandler = serveStatic({
|
|
323
|
+
root: adminDistPath,
|
|
324
|
+
rewriteRequestPath: (p: string) => p.replace("/admin", ""),
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
` : "";
|
|
328
|
+
return n ? `import { Context } from "hono";
|
|
294
329
|
import { swaggerUI } from "@hono/swagger-ui";
|
|
295
330
|
import { AuthHeroConfig, DataAdapters } from "authhero";
|
|
296
331
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
297
332
|
import { initMultiTenant } from "@authhero/multi-tenancy";
|
|
333
|
+
import path from "path";
|
|
334
|
+
${r}import { fileURLToPath } from "url";
|
|
298
335
|
|
|
336
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
337
|
+
|
|
338
|
+
const widgetPath = path.resolve(
|
|
339
|
+
__dirname,
|
|
340
|
+
"../node_modules/@authhero/widget/dist/authhero-widget",
|
|
341
|
+
);
|
|
342
|
+
${a}
|
|
299
343
|
// Control plane configuration
|
|
300
344
|
const CONTROL_PLANE_TENANT_ID = "control_plane";
|
|
301
345
|
const CONTROL_PLANE_CLIENT_ID = "default_client";
|
|
302
346
|
|
|
303
347
|
export default function createApp(config: AuthHeroConfig & { dataAdapter: DataAdapters }) {
|
|
348
|
+
const configWithHandlers: AuthHeroConfig & { dataAdapter: DataAdapters } = {
|
|
349
|
+
...config,
|
|
350
|
+
widgetHandler: serveStatic({
|
|
351
|
+
root: widgetPath,
|
|
352
|
+
rewriteRequestPath: (p) => p.replace("/u/widget", ""),
|
|
353
|
+
}),
|
|
354
|
+
};
|
|
355
|
+
${o}
|
|
304
356
|
// Initialize multi-tenant AuthHero - syncs resource servers, roles, and connections by default
|
|
305
357
|
const { app } = initMultiTenant({
|
|
306
|
-
...
|
|
358
|
+
...configWithHandlers,
|
|
307
359
|
controlPlane: {
|
|
308
360
|
tenantId: CONTROL_PLANE_TENANT_ID,
|
|
309
361
|
clientId: CONTROL_PLANE_CLIENT_ID,
|
|
@@ -328,23 +380,7 @@ export default function createApp(config: AuthHeroConfig & { dataAdapter: DataAd
|
|
|
328
380
|
controlPlaneTenant: CONTROL_PLANE_TENANT_ID,
|
|
329
381
|
});
|
|
330
382
|
})
|
|
331
|
-
.get("/docs", swaggerUI({ url: "/api/v2/spec" }))
|
|
332
|
-
// Serve widget assets from @authhero/widget package
|
|
333
|
-
.get(
|
|
334
|
-
"/u/widget/*",
|
|
335
|
-
serveStatic({
|
|
336
|
-
root: "./node_modules/@authhero/widget/dist/authhero-widget",
|
|
337
|
-
rewriteRequestPath: (path) => path.replace("/u/widget", ""),
|
|
338
|
-
}),
|
|
339
|
-
)
|
|
340
|
-
// Serve static assets (CSS, JS) from authhero package
|
|
341
|
-
.get(
|
|
342
|
-
"/u/*",
|
|
343
|
-
serveStatic({
|
|
344
|
-
root: "./node_modules/authhero/dist/assets/u",
|
|
345
|
-
rewriteRequestPath: (path) => path.replace("/u", ""),
|
|
346
|
-
}),
|
|
347
|
-
);
|
|
383
|
+
.get("/docs", swaggerUI({ url: "/api/v2/spec" }));
|
|
348
384
|
|
|
349
385
|
return app;
|
|
350
386
|
}
|
|
@@ -352,9 +388,26 @@ export default function createApp(config: AuthHeroConfig & { dataAdapter: DataAd
|
|
|
352
388
|
import { AuthHeroConfig, init } from "authhero";
|
|
353
389
|
import { swaggerUI } from "@hono/swagger-ui";
|
|
354
390
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
391
|
+
import path from "path";
|
|
392
|
+
${r}import { fileURLToPath } from "url";
|
|
355
393
|
|
|
394
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
395
|
+
|
|
396
|
+
const widgetPath = path.resolve(
|
|
397
|
+
__dirname,
|
|
398
|
+
"../node_modules/@authhero/widget/dist/authhero-widget",
|
|
399
|
+
);
|
|
400
|
+
${a}
|
|
356
401
|
export default function createApp(config: AuthHeroConfig) {
|
|
357
|
-
const
|
|
402
|
+
const configWithHandlers: AuthHeroConfig = {
|
|
403
|
+
...config,
|
|
404
|
+
widgetHandler: serveStatic({
|
|
405
|
+
root: widgetPath,
|
|
406
|
+
rewriteRequestPath: (p) => p.replace("/u/widget", ""),
|
|
407
|
+
}),
|
|
408
|
+
};
|
|
409
|
+
${o}
|
|
410
|
+
const { app } = init(configWithHandlers);
|
|
358
411
|
|
|
359
412
|
app
|
|
360
413
|
.onError((err, ctx) => {
|
|
@@ -371,29 +424,13 @@ export default function createApp(config: AuthHeroConfig) {
|
|
|
371
424
|
status: "running",
|
|
372
425
|
});
|
|
373
426
|
})
|
|
374
|
-
.get("/docs", swaggerUI({ url: "/api/v2/spec" }))
|
|
375
|
-
// Serve widget assets from @authhero/widget package
|
|
376
|
-
.get(
|
|
377
|
-
"/u/widget/*",
|
|
378
|
-
serveStatic({
|
|
379
|
-
root: "./node_modules/@authhero/widget/dist/authhero-widget",
|
|
380
|
-
rewriteRequestPath: (path) => path.replace("/u/widget", ""),
|
|
381
|
-
}),
|
|
382
|
-
)
|
|
383
|
-
// Serve static assets (CSS, JS) from authhero package
|
|
384
|
-
.get(
|
|
385
|
-
"/u/*",
|
|
386
|
-
serveStatic({
|
|
387
|
-
root: "./node_modules/authhero/dist/assets/u",
|
|
388
|
-
rewriteRequestPath: (path) => path.replace("/u", ""),
|
|
389
|
-
}),
|
|
390
|
-
);
|
|
427
|
+
.get("/docs", swaggerUI({ url: "/api/v2/spec" }));
|
|
391
428
|
|
|
392
429
|
return app;
|
|
393
430
|
}
|
|
394
431
|
`;
|
|
395
432
|
}
|
|
396
|
-
function O(
|
|
433
|
+
function O(n) {
|
|
397
434
|
return `import { D1Dialect } from "kysely-d1";
|
|
398
435
|
import { Kysely } from "kysely";
|
|
399
436
|
import createAdapters from "@authhero/kysely-adapter";
|
|
@@ -420,9 +457,9 @@ export default {
|
|
|
420
457
|
adminUsername,
|
|
421
458
|
adminPassword,
|
|
422
459
|
issuer,
|
|
423
|
-
tenantId: "${
|
|
424
|
-
tenantName: "${
|
|
425
|
-
isControlPlane: ${
|
|
460
|
+
tenantId: "${n ? "control_plane" : "main"}",
|
|
461
|
+
tenantName: "${n ? "Control Plane" : "Main"}",
|
|
462
|
+
isControlPlane: ${!!n},
|
|
426
463
|
});
|
|
427
464
|
|
|
428
465
|
return new Response(
|
|
@@ -453,12 +490,15 @@ export default {
|
|
|
453
490
|
};
|
|
454
491
|
`;
|
|
455
492
|
}
|
|
456
|
-
function
|
|
457
|
-
|
|
493
|
+
function L(n, e) {
|
|
494
|
+
const r = e ? `import adminIndexHtml from "./admin-index-html";
|
|
495
|
+
` : "", a = e ? ` adminIndexHtml,
|
|
496
|
+
` : "";
|
|
497
|
+
return n ? `import { Context } from "hono";
|
|
458
498
|
import { swaggerUI } from "@hono/swagger-ui";
|
|
459
499
|
import { AuthHeroConfig, DataAdapters } from "authhero";
|
|
460
500
|
import { initMultiTenant } from "@authhero/multi-tenancy";
|
|
461
|
-
|
|
501
|
+
${r}
|
|
462
502
|
// Control plane configuration
|
|
463
503
|
const CONTROL_PLANE_TENANT_ID = "control_plane";
|
|
464
504
|
const CONTROL_PLANE_CLIENT_ID = "default_client";
|
|
@@ -467,7 +507,7 @@ export default function createApp(config: AuthHeroConfig & { dataAdapter: DataAd
|
|
|
467
507
|
// Initialize multi-tenant AuthHero - syncs resource servers, roles, and connections by default
|
|
468
508
|
const { app } = initMultiTenant({
|
|
469
509
|
...config,
|
|
470
|
-
controlPlane: {
|
|
510
|
+
${a} controlPlane: {
|
|
471
511
|
tenantId: CONTROL_PLANE_TENANT_ID,
|
|
472
512
|
clientId: CONTROL_PLANE_CLIENT_ID,
|
|
473
513
|
},
|
|
@@ -499,9 +539,11 @@ export default function createApp(config: AuthHeroConfig & { dataAdapter: DataAd
|
|
|
499
539
|
import { cors } from "hono/cors";
|
|
500
540
|
import { AuthHeroConfig, init } from "authhero";
|
|
501
541
|
import { swaggerUI } from "@hono/swagger-ui";
|
|
502
|
-
|
|
542
|
+
${r}
|
|
503
543
|
export default function createApp(config: AuthHeroConfig) {
|
|
504
|
-
const { app } = init(
|
|
544
|
+
const { app } = init({
|
|
545
|
+
...config,
|
|
546
|
+
${a} });
|
|
505
547
|
|
|
506
548
|
// Enable CORS for all origins in development
|
|
507
549
|
app.use("*", cors({
|
|
@@ -533,8 +575,8 @@ export default function createApp(config: AuthHeroConfig) {
|
|
|
533
575
|
}
|
|
534
576
|
`;
|
|
535
577
|
}
|
|
536
|
-
function j(
|
|
537
|
-
return
|
|
578
|
+
function j(n) {
|
|
579
|
+
return n ? `import { Context } from "hono";
|
|
538
580
|
import { swaggerUI } from "@hono/swagger-ui";
|
|
539
581
|
import { AuthHeroConfig, DataAdapters } from "authhero";
|
|
540
582
|
import { initMultiTenant } from "@authhero/multi-tenancy";
|
|
@@ -639,7 +681,7 @@ export default function createApp(config: AppConfig) {
|
|
|
639
681
|
}
|
|
640
682
|
`;
|
|
641
683
|
}
|
|
642
|
-
function
|
|
684
|
+
function $(n) {
|
|
643
685
|
return `import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
|
|
644
686
|
import { DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb";
|
|
645
687
|
import createAdapters from "@authhero/aws";
|
|
@@ -668,9 +710,9 @@ async function main() {
|
|
|
668
710
|
await seed(adapters, {
|
|
669
711
|
adminUsername,
|
|
670
712
|
adminPassword,
|
|
671
|
-
tenantId: "${
|
|
672
|
-
tenantName: "${
|
|
673
|
-
isControlPlane: ${
|
|
713
|
+
tenantId: "${n ? "control_plane" : "main"}",
|
|
714
|
+
tenantName: "${n ? "Control Plane" : "Main"}",
|
|
715
|
+
isControlPlane: ${!!n},
|
|
674
716
|
});
|
|
675
717
|
|
|
676
718
|
console.log("โ
Database seeded successfully!");
|
|
@@ -679,24 +721,24 @@ async function main() {
|
|
|
679
721
|
main().catch(console.error);
|
|
680
722
|
`;
|
|
681
723
|
}
|
|
682
|
-
function
|
|
683
|
-
const r =
|
|
684
|
-
|
|
685
|
-
|
|
724
|
+
function H(n, e) {
|
|
725
|
+
const r = i.join(n, "src");
|
|
726
|
+
s.writeFileSync(
|
|
727
|
+
i.join(r, "app.ts"),
|
|
686
728
|
j(e)
|
|
687
|
-
),
|
|
688
|
-
|
|
689
|
-
|
|
729
|
+
), s.writeFileSync(
|
|
730
|
+
i.join(r, "seed.ts"),
|
|
731
|
+
$(e)
|
|
690
732
|
);
|
|
691
733
|
}
|
|
692
|
-
function
|
|
734
|
+
function I() {
|
|
693
735
|
console.log("\\n" + "โ".repeat(50)), console.log("๐ AuthHero deployed to AWS!"), console.log("๐ Check SST output for your API URL"), console.log(
|
|
694
736
|
"๐ Open your server URL /setup to complete initial setup"
|
|
695
737
|
), console.log("๐ Portal available at https://local.authhero.net"), console.log("โ".repeat(50) + "\\n");
|
|
696
738
|
}
|
|
697
|
-
function
|
|
698
|
-
const e =
|
|
699
|
-
|
|
739
|
+
function M(n) {
|
|
740
|
+
const e = i.join(n, ".github", "workflows");
|
|
741
|
+
s.mkdirSync(e, { recursive: !0 });
|
|
700
742
|
const r = `name: Unit tests
|
|
701
743
|
|
|
702
744
|
on: push
|
|
@@ -718,7 +760,7 @@ jobs:
|
|
|
718
760
|
|
|
719
761
|
- run: npm run type-check
|
|
720
762
|
- run: npm test
|
|
721
|
-
`,
|
|
763
|
+
`, a = `name: Deploy to Dev
|
|
722
764
|
|
|
723
765
|
on:
|
|
724
766
|
push:
|
|
@@ -754,7 +796,7 @@ jobs:
|
|
|
754
796
|
with:
|
|
755
797
|
apiToken: \${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
756
798
|
command: deploy
|
|
757
|
-
`,
|
|
799
|
+
`, o = `name: Deploy to Production
|
|
758
800
|
|
|
759
801
|
on:
|
|
760
802
|
release:
|
|
@@ -783,9 +825,9 @@ jobs:
|
|
|
783
825
|
apiToken: \${{ secrets.PROD_CLOUDFLARE_API_TOKEN }}
|
|
784
826
|
command: deploy --env production
|
|
785
827
|
`;
|
|
786
|
-
|
|
828
|
+
s.writeFileSync(i.join(e, "unit-tests.yml"), r), s.writeFileSync(i.join(e, "deploy-dev.yml"), a), s.writeFileSync(i.join(e, "release.yml"), o), console.log("\\n๐ฆ GitHub CI workflows created!");
|
|
787
829
|
}
|
|
788
|
-
function
|
|
830
|
+
function F(n) {
|
|
789
831
|
const e = {
|
|
790
832
|
branches: ["main"],
|
|
791
833
|
plugins: [
|
|
@@ -794,39 +836,39 @@ function M(o) {
|
|
|
794
836
|
"@semantic-release/github"
|
|
795
837
|
]
|
|
796
838
|
};
|
|
797
|
-
|
|
798
|
-
|
|
839
|
+
s.writeFileSync(
|
|
840
|
+
i.join(n, ".releaserc.json"),
|
|
799
841
|
JSON.stringify(e, null, 2)
|
|
800
842
|
);
|
|
801
|
-
const r =
|
|
802
|
-
|
|
803
|
-
...
|
|
843
|
+
const r = i.join(n, "package.json"), a = JSON.parse(s.readFileSync(r, "utf-8"));
|
|
844
|
+
a.devDependencies = {
|
|
845
|
+
...a.devDependencies,
|
|
804
846
|
"semantic-release": "^24.0.0"
|
|
805
|
-
},
|
|
806
|
-
...
|
|
847
|
+
}, a.scripts = {
|
|
848
|
+
...a.scripts,
|
|
807
849
|
test: 'echo "No tests yet"',
|
|
808
850
|
"type-check": "tsc --noEmit"
|
|
809
|
-
},
|
|
851
|
+
}, s.writeFileSync(r, JSON.stringify(a, null, 2));
|
|
810
852
|
}
|
|
811
|
-
function
|
|
812
|
-
return new Promise((r,
|
|
813
|
-
const
|
|
853
|
+
function b(n, e) {
|
|
854
|
+
return new Promise((r, a) => {
|
|
855
|
+
const o = E(n, [], {
|
|
814
856
|
cwd: e,
|
|
815
857
|
shell: !0,
|
|
816
858
|
stdio: "inherit"
|
|
817
859
|
});
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
}),
|
|
860
|
+
o.on("close", (t) => {
|
|
861
|
+
t === 0 ? r() : a(new Error(`Command failed with exit code ${t}`));
|
|
862
|
+
}), o.on("error", a);
|
|
821
863
|
});
|
|
822
864
|
}
|
|
823
|
-
function
|
|
824
|
-
const
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
),
|
|
829
|
-
|
|
865
|
+
function W(n, e, r) {
|
|
866
|
+
const a = i.join(n, "src");
|
|
867
|
+
s.writeFileSync(
|
|
868
|
+
i.join(a, "app.ts"),
|
|
869
|
+
L(e, r)
|
|
870
|
+
), s.writeFileSync(
|
|
871
|
+
i.join(a, "seed.ts"),
|
|
830
872
|
O(e)
|
|
831
873
|
);
|
|
832
874
|
}
|
|
@@ -837,29 +879,29 @@ function x() {
|
|
|
837
879
|
), console.log("๐ Portal available at https://local.authhero.net"), console.log("โ".repeat(50) + `
|
|
838
880
|
`);
|
|
839
881
|
}
|
|
840
|
-
function
|
|
882
|
+
function k() {
|
|
841
883
|
console.log(`
|
|
842
884
|
` + "โ".repeat(50)), console.log("โ
Self-signed certificates generated with openssl"), console.log("โ ๏ธ You may need to trust the certificate in your browser"), console.log("๐ AuthHero server running at https://localhost:3000"), console.log("๐ API documentation available at https://localhost:3000/docs"), console.log(
|
|
843
885
|
"๐ Open https://localhost:3000/setup to complete initial setup"
|
|
844
886
|
), console.log("๐ Portal available at https://local.authhero.net"), console.log("โ".repeat(50) + `
|
|
845
887
|
`);
|
|
846
888
|
}
|
|
847
|
-
|
|
889
|
+
D.version("1.0.0").description("Create a new AuthHero project").argument("[project-name]", "name of the project").option("-t, --template <type>", "template type: local or cloudflare").option(
|
|
848
890
|
"--package-manager <pm>",
|
|
849
891
|
"package manager to use: npm, yarn, pnpm, or bun"
|
|
850
|
-
).option("--multi-tenant", "enable multi-tenant mode").option("--skip-install", "skip installing dependencies").option("--skip-migrate", "skip running database migrations").option("--skip-start", "skip starting the development server").option("--github-ci", "include GitHub CI workflows with semantic versioning").option("--conformance", "add OpenID conformance suite test clients").option(
|
|
892
|
+
).option("--multi-tenant", "enable multi-tenant mode").option("--admin-ui", "include admin UI at /admin").option("--skip-install", "skip installing dependencies").option("--skip-migrate", "skip running database migrations").option("--skip-start", "skip starting the development server").option("--github-ci", "include GitHub CI workflows with semantic versioning").option("--conformance", "add OpenID conformance suite test clients").option(
|
|
851
893
|
"--conformance-alias <alias>",
|
|
852
894
|
"alias for conformance suite (default: authhero-local)"
|
|
853
895
|
).option(
|
|
854
896
|
"--workspace",
|
|
855
897
|
"use workspace:* dependencies for local monorepo development"
|
|
856
|
-
).option("-y, --yes", "skip all prompts and use defaults/provided options").action(async (
|
|
898
|
+
).option("-y, --yes", "skip all prompts and use defaults/provided options").action(async (n, e) => {
|
|
857
899
|
const r = e.yes === !0;
|
|
858
900
|
console.log(`
|
|
859
901
|
๐ Welcome to AuthHero!
|
|
860
902
|
`);
|
|
861
|
-
let
|
|
862
|
-
|
|
903
|
+
let a = n;
|
|
904
|
+
a || (r ? (a = "auth-server", console.log(`Using default project name: ${a}`)) : a = (await m.prompt([
|
|
863
905
|
{
|
|
864
906
|
type: "input",
|
|
865
907
|
name: "projectName",
|
|
@@ -868,10 +910,10 @@ T.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
868
910
|
validate: (u) => u !== "" || "Project name cannot be empty"
|
|
869
911
|
}
|
|
870
912
|
])).projectName);
|
|
871
|
-
const
|
|
872
|
-
|
|
873
|
-
let
|
|
874
|
-
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)),
|
|
913
|
+
const o = i.join(process.cwd(), a);
|
|
914
|
+
s.existsSync(o) && (console.error(`โ Project "${a}" already exists.`), process.exit(1));
|
|
915
|
+
let t;
|
|
916
|
+
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([
|
|
875
917
|
{
|
|
876
918
|
type: "list",
|
|
877
919
|
name: "setupType",
|
|
@@ -898,64 +940,73 @@ T.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
898
940
|
]
|
|
899
941
|
}
|
|
900
942
|
])).setupType;
|
|
901
|
-
let
|
|
902
|
-
e.multiTenant !== void 0 ?
|
|
943
|
+
let c;
|
|
944
|
+
e.multiTenant !== void 0 ? c = e.multiTenant : r ? c = !1 : c = (await m.prompt([
|
|
903
945
|
{
|
|
904
946
|
type: "confirm",
|
|
905
947
|
name: "multiTenant",
|
|
906
|
-
message:
|
|
907
|
-
(Allows managing multiple tenants from a control plane)`,
|
|
948
|
+
message: "Would you like to enable multi-tenant mode?",
|
|
908
949
|
default: !1
|
|
909
950
|
}
|
|
910
|
-
])).multiTenant;
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
951
|
+
])).multiTenant, c && console.log("Multi-tenant mode: enabled");
|
|
952
|
+
let d = !1;
|
|
953
|
+
(t === "local" || t === "cloudflare") && (e.adminUi !== void 0 ? d = e.adminUi : r ? d = !0 : d = (await m.prompt([
|
|
954
|
+
{
|
|
955
|
+
type: "confirm",
|
|
956
|
+
name: "adminUi",
|
|
957
|
+
message: "Would you like to include the admin UI at /admin?",
|
|
958
|
+
default: !0
|
|
959
|
+
}
|
|
960
|
+
])).adminUi, d && console.log("Admin UI: enabled (available at /admin)"));
|
|
961
|
+
const f = e.conformance || !1, h = e.conformanceAlias || "authhero-local";
|
|
962
|
+
f && console.log(
|
|
963
|
+
`OpenID Conformance Suite: enabled (alias: ${h})`
|
|
914
964
|
);
|
|
915
|
-
const
|
|
916
|
-
|
|
917
|
-
const
|
|
918
|
-
|
|
919
|
-
|
|
965
|
+
const C = e.workspace || !1;
|
|
966
|
+
C && console.log("Workspace mode: enabled (using workspace:* dependencies)");
|
|
967
|
+
const y = p[t];
|
|
968
|
+
s.mkdirSync(o, { recursive: !0 }), s.writeFileSync(
|
|
969
|
+
i.join(o, "package.json"),
|
|
920
970
|
JSON.stringify(
|
|
921
|
-
|
|
971
|
+
y.packageJson(a, c, f, C, d),
|
|
922
972
|
null,
|
|
923
973
|
2
|
|
924
974
|
)
|
|
925
975
|
);
|
|
926
|
-
const
|
|
976
|
+
const S = y.templateDir, _ = i.join(
|
|
927
977
|
import.meta.url.replace("file://", "").replace("/create-authhero.js", ""),
|
|
928
|
-
|
|
978
|
+
S
|
|
929
979
|
);
|
|
930
|
-
if (
|
|
931
|
-
const
|
|
932
|
-
|
|
933
|
-
const
|
|
934
|
-
|
|
980
|
+
if (s.existsSync(_) ? N(_, o) : (console.error(`โ Template directory not found: ${_}`), process.exit(1)), t === "cloudflare" && W(o, c, d), t === "cloudflare") {
|
|
981
|
+
const l = i.join(o, "wrangler.toml"), u = i.join(o, "wrangler.local.toml");
|
|
982
|
+
s.existsSync(l) && s.copyFileSync(l, u);
|
|
983
|
+
const g = i.join(o, ".dev.vars.example"), w = i.join(o, ".dev.vars");
|
|
984
|
+
s.existsSync(g) && s.copyFileSync(g, w), console.log(
|
|
935
985
|
"๐ Created wrangler.local.toml and .dev.vars for local development"
|
|
936
986
|
);
|
|
937
987
|
}
|
|
938
|
-
let
|
|
939
|
-
if (
|
|
988
|
+
let A = !1;
|
|
989
|
+
if (t === "cloudflare" && (e.githubCi !== void 0 ? (A = e.githubCi, A && console.log("Including GitHub CI workflows with semantic versioning")) : r || (A = (await m.prompt([
|
|
940
990
|
{
|
|
941
991
|
type: "confirm",
|
|
942
992
|
name: "includeGithubCi",
|
|
943
993
|
message: "Would you like to include GitHub CI with semantic versioning?",
|
|
944
994
|
default: !1
|
|
945
995
|
}
|
|
946
|
-
])).includeGithubCi),
|
|
947
|
-
const
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
996
|
+
])).includeGithubCi), A && (M(o), F(o))), t === "local") {
|
|
997
|
+
const l = R(
|
|
998
|
+
c,
|
|
999
|
+
f,
|
|
1000
|
+
h,
|
|
1001
|
+
d
|
|
951
1002
|
);
|
|
952
|
-
|
|
953
|
-
const u =
|
|
954
|
-
|
|
1003
|
+
s.writeFileSync(i.join(o, "src/seed.ts"), l);
|
|
1004
|
+
const u = U(c, d);
|
|
1005
|
+
s.writeFileSync(i.join(o, "src/app.ts"), u);
|
|
955
1006
|
}
|
|
956
|
-
if (
|
|
957
|
-
const
|
|
958
|
-
alias:
|
|
1007
|
+
if (t === "aws-sst" && H(o, c), f) {
|
|
1008
|
+
const l = {
|
|
1009
|
+
alias: h,
|
|
959
1010
|
description: "AuthHero Conformance Test",
|
|
960
1011
|
server: {
|
|
961
1012
|
discoveryUrl: "http://host.docker.internal:3000/.well-known/openid-configuration"
|
|
@@ -972,32 +1023,32 @@ T.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
972
1023
|
resourceUrl: "http://host.docker.internal:3000/userinfo"
|
|
973
1024
|
}
|
|
974
1025
|
};
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
JSON.stringify(
|
|
1026
|
+
s.writeFileSync(
|
|
1027
|
+
i.join(o, "conformance-config.json"),
|
|
1028
|
+
JSON.stringify(l, null, 2)
|
|
978
1029
|
), console.log(
|
|
979
1030
|
"๐ Created conformance-config.json for OpenID Conformance Suite"
|
|
980
1031
|
);
|
|
981
1032
|
}
|
|
982
|
-
const
|
|
1033
|
+
const T = c ? "multi-tenant" : "single-tenant";
|
|
983
1034
|
console.log(
|
|
984
1035
|
`
|
|
985
|
-
โ
Project "${
|
|
1036
|
+
โ
Project "${a}" has been created with ${y.name} (${T}) setup!
|
|
986
1037
|
`
|
|
987
1038
|
);
|
|
988
|
-
let
|
|
989
|
-
if (e.skipInstall ?
|
|
1039
|
+
let v;
|
|
1040
|
+
if (e.skipInstall ? v = !1 : r ? v = !0 : v = (await m.prompt([
|
|
990
1041
|
{
|
|
991
1042
|
type: "confirm",
|
|
992
1043
|
name: "shouldInstall",
|
|
993
1044
|
message: "Would you like to install dependencies now?",
|
|
994
1045
|
default: !0
|
|
995
1046
|
}
|
|
996
|
-
])).shouldInstall,
|
|
997
|
-
let
|
|
1047
|
+
])).shouldInstall, v) {
|
|
1048
|
+
let l;
|
|
998
1049
|
e.packageManager ? (["npm", "yarn", "pnpm", "bun"].includes(e.packageManager) || (console.error(
|
|
999
1050
|
`โ Invalid package manager: ${e.packageManager}`
|
|
1000
|
-
), console.error("Valid options: npm, yarn, pnpm, bun"), process.exit(1)),
|
|
1051
|
+
), console.error("Valid options: npm, yarn, pnpm, bun"), process.exit(1)), l = e.packageManager) : r ? l = "pnpm" : l = (await m.prompt([
|
|
1001
1052
|
{
|
|
1002
1053
|
type: "list",
|
|
1003
1054
|
name: "packageManager",
|
|
@@ -1011,65 +1062,65 @@ T.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
1011
1062
|
default: "pnpm"
|
|
1012
1063
|
}
|
|
1013
1064
|
])).packageManager, console.log(`
|
|
1014
|
-
๐ฆ Installing dependencies with ${
|
|
1065
|
+
๐ฆ Installing dependencies with ${l}...
|
|
1015
1066
|
`);
|
|
1016
1067
|
try {
|
|
1017
|
-
const u =
|
|
1018
|
-
if (await
|
|
1068
|
+
const u = l === "pnpm" ? "pnpm install --ignore-workspace" : `${l} install`;
|
|
1069
|
+
if (await b(u, o), t === "local" && (console.log(`
|
|
1019
1070
|
๐ง Building native modules...
|
|
1020
|
-
`), await
|
|
1071
|
+
`), await b("npm rebuild better-sqlite3", o)), console.log(`
|
|
1021
1072
|
โ
Dependencies installed successfully!
|
|
1022
|
-
`), (
|
|
1023
|
-
let
|
|
1024
|
-
r ?
|
|
1073
|
+
`), (t === "local" || t === "cloudflare") && !e.skipMigrate) {
|
|
1074
|
+
let w;
|
|
1075
|
+
r ? w = !0 : w = (await m.prompt([
|
|
1025
1076
|
{
|
|
1026
1077
|
type: "confirm",
|
|
1027
1078
|
name: "shouldMigrate",
|
|
1028
1079
|
message: "Would you like to run database migrations?",
|
|
1029
1080
|
default: !0
|
|
1030
1081
|
}
|
|
1031
|
-
])).shouldMigrate,
|
|
1082
|
+
])).shouldMigrate, w && (console.log(`
|
|
1032
1083
|
๐ Running migrations...
|
|
1033
|
-
`), await
|
|
1084
|
+
`), await b(`${l} run migrate`, o));
|
|
1034
1085
|
}
|
|
1035
|
-
let
|
|
1036
|
-
e.skipStart || r ?
|
|
1086
|
+
let g;
|
|
1087
|
+
e.skipStart || r ? g = !1 : g = (await m.prompt([
|
|
1037
1088
|
{
|
|
1038
1089
|
type: "confirm",
|
|
1039
1090
|
name: "shouldStart",
|
|
1040
1091
|
message: "Would you like to start the development server?",
|
|
1041
1092
|
default: !0
|
|
1042
1093
|
}
|
|
1043
|
-
])).shouldStart,
|
|
1044
|
-
`), await
|
|
1094
|
+
])).shouldStart, g && (t === "cloudflare" ? x() : t === "aws-sst" ? I() : k(), console.log(`๐ Starting development server...
|
|
1095
|
+
`), await b(`${l} run dev`, o)), r && !g && (console.log(`
|
|
1045
1096
|
โ
Setup complete!`), console.log(`
|
|
1046
|
-
To start the development server:`), console.log(` cd ${
|
|
1097
|
+
To start the development server:`), console.log(` cd ${a}`), console.log(" npm run dev"), t === "cloudflare" ? x() : t === "aws-sst" ? I() : k());
|
|
1047
1098
|
} catch (u) {
|
|
1048
1099
|
console.error(`
|
|
1049
1100
|
โ An error occurred:`, u), process.exit(1);
|
|
1050
1101
|
}
|
|
1051
1102
|
}
|
|
1052
|
-
|
|
1103
|
+
v || (console.log("Next steps:"), console.log(` cd ${a}`), t === "local" ? (console.log(" npm install"), console.log(" npm run migrate"), console.log(" npm run dev"), console.log(
|
|
1053
1104
|
`
|
|
1054
1105
|
Open https://localhost:3000/setup to complete initial setup`
|
|
1055
|
-
)) :
|
|
1106
|
+
)) : t === "cloudflare" ? (console.log(" npm install"), console.log(
|
|
1056
1107
|
" npm run migrate # or npm run db:migrate:remote for production"
|
|
1057
1108
|
), console.log(" npm run dev # or npm run dev:remote for production"), console.log(
|
|
1058
1109
|
`
|
|
1059
1110
|
Open https://localhost:3000/setup to complete initial setup`
|
|
1060
|
-
)) :
|
|
1111
|
+
)) : t === "aws-sst" && (console.log(" npm install"), console.log(" npm run dev # Deploys to AWS in development mode"), console.log(
|
|
1061
1112
|
`
|
|
1062
1113
|
Open your server URL /setup to complete initial setup`
|
|
1063
1114
|
)), console.log(`
|
|
1064
|
-
Server will be available at: https://localhost:3000`), console.log("Portal available at: https://local.authhero.net"),
|
|
1115
|
+
Server will be available at: https://localhost:3000`), console.log("Portal available at: https://local.authhero.net"), f && (console.log(`
|
|
1065
1116
|
๐งช OpenID Conformance Suite Testing:`), console.log(
|
|
1066
1117
|
" 1. Clone and start the conformance suite (if not already running):"
|
|
1067
1118
|
), console.log(
|
|
1068
1119
|
" git clone https://gitlab.com/openid/conformance-suite.git"
|
|
1069
1120
|
), console.log(" cd conformance-suite && mvn clean package"), console.log(" docker-compose up -d"), console.log(" 2. Open https://localhost.emobix.co.uk:8443"), console.log(
|
|
1070
1121
|
" 3. Create a test plan and use conformance-config.json for settings"
|
|
1071
|
-
), console.log(` 4. Use alias: ${
|
|
1122
|
+
), console.log(` 4. Use alias: ${h}`)), console.log(`
|
|
1072
1123
|
For more information, visit: https://authhero.net/docs
|
|
1073
1124
|
`));
|
|
1074
1125
|
});
|
|
1075
|
-
|
|
1126
|
+
D.parse(process.argv);
|
package/dist/local/src/app.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { AuthHeroConfig, init } from "authhero";
|
|
|
3
3
|
import { swaggerUI } from "@hono/swagger-ui";
|
|
4
4
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
5
5
|
import path from "path";
|
|
6
|
+
import fs from "fs";
|
|
6
7
|
import { fileURLToPath } from "url";
|
|
7
8
|
|
|
8
9
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -13,9 +14,15 @@ const widgetPath = path.resolve(
|
|
|
13
14
|
"../node_modules/@authhero/widget/dist/authhero-widget",
|
|
14
15
|
);
|
|
15
16
|
|
|
17
|
+
const adminDistPath = path.resolve(
|
|
18
|
+
__dirname,
|
|
19
|
+
"../node_modules/@authhero/react-admin/dist",
|
|
20
|
+
);
|
|
21
|
+
const adminIndexPath = path.join(adminDistPath, "index.html");
|
|
22
|
+
|
|
16
23
|
export default function createApp(config: AuthHeroConfig) {
|
|
17
|
-
// Configure widget
|
|
18
|
-
const
|
|
24
|
+
// Configure widget and admin handlers before init()
|
|
25
|
+
const configWithHandlers: AuthHeroConfig = {
|
|
19
26
|
...config,
|
|
20
27
|
widgetHandler: serveStatic({
|
|
21
28
|
root: widgetPath,
|
|
@@ -23,7 +30,28 @@ export default function createApp(config: AuthHeroConfig) {
|
|
|
23
30
|
}),
|
|
24
31
|
};
|
|
25
32
|
|
|
26
|
-
|
|
33
|
+
// Add admin UI handler if the package is installed
|
|
34
|
+
if (fs.existsSync(adminIndexPath)) {
|
|
35
|
+
const issuer =
|
|
36
|
+
process.env.ISSUER || `https://localhost:${process.env.PORT || 3000}/`;
|
|
37
|
+
const rawHtml = fs.readFileSync(adminIndexPath, "utf-8")
|
|
38
|
+
.replace(/src="\.\/assets\//g, 'src="/admin/assets/')
|
|
39
|
+
.replace(/href="\.\/assets\//g, 'href="/admin/assets/');
|
|
40
|
+
const configJson = JSON.stringify({
|
|
41
|
+
domain: issuer.replace(/\/$/, ""),
|
|
42
|
+
basePath: "/admin",
|
|
43
|
+
}).replace(/</g, "\\u003c");
|
|
44
|
+
configWithHandlers.adminIndexHtml = rawHtml.replace(
|
|
45
|
+
"</head>",
|
|
46
|
+
`<script>window.__AUTHHERO_ADMIN_CONFIG__=${configJson};</script>\n</head>`,
|
|
47
|
+
);
|
|
48
|
+
configWithHandlers.adminHandler = serveStatic({
|
|
49
|
+
root: adminDistPath,
|
|
50
|
+
rewriteRequestPath: (p: string) => p.replace("/admin", ""),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const { app } = init(configWithHandlers);
|
|
27
55
|
|
|
28
56
|
app
|
|
29
57
|
.get("/", async (ctx: Context) => {
|
package/dist/local/src/index.ts
CHANGED
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/markusahlstrand/authhero"
|
|
7
7
|
},
|
|
8
|
-
"version": "0.
|
|
8
|
+
"version": "0.35.0",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"main": "dist/create-authhero.js",
|
|
11
11
|
"bin": {
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"scripts": {
|
|
31
31
|
"build": "tsc && vite build",
|
|
32
|
+
"dev": "pnpm build && rm -rf auth-server && node dist/create-authhero.js auth-server --workspace --skip-install --skip-start && pnpm -w install --force --filter auth-server... && pnpm --filter auth-server migrate && pnpm --filter auth-server dev",
|
|
32
33
|
"start": "pnpm build && node dist/create-authhero.js"
|
|
33
34
|
}
|
|
34
35
|
}
|