@eventcatalog/core 4.12.0 → 4.12.1

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 (33) hide show
  1. package/dist/analytics/analytics.cjs +1 -1
  2. package/dist/analytics/analytics.js +2 -2
  3. package/dist/analytics/log-build.cjs +1 -1
  4. package/dist/analytics/log-build.js +3 -3
  5. package/dist/{chunk-Q46W7LGT.js → chunk-DZZDBFUM.js} +1 -1
  6. package/dist/{chunk-DWTU2R2Z.js → chunk-EVXNBTRA.js} +1 -1
  7. package/dist/{chunk-SQXIGSIJ.js → chunk-HH6GPY4H.js} +1 -1
  8. package/dist/{chunk-MZ5QBEFA.js → chunk-HHZFKWX7.js} +1 -1
  9. package/dist/{chunk-UC3HZHW4.js → chunk-UWSBZYF5.js} +3 -3
  10. package/dist/constants.cjs +1 -1
  11. package/dist/constants.js +1 -1
  12. package/dist/eventcatalog.cjs +1 -1
  13. package/dist/eventcatalog.js +13 -13
  14. package/dist/federation/federate.js +4 -4
  15. package/dist/generate.cjs +1 -1
  16. package/dist/generate.js +3 -3
  17. package/dist/runtime-dependencies/manifest.json +1 -3
  18. package/dist/runtime-dependencies/set-cookie-parser.mjs +3 -0
  19. package/dist/utils/cli-logger.cjs +1 -1
  20. package/dist/utils/cli-logger.js +2 -2
  21. package/eventcatalog/auth.config.ts +3 -4
  22. package/eventcatalog/src/components/Header.astro +101 -33
  23. package/eventcatalog/src/enterprise/auth/[...auth].ts +1 -1
  24. package/eventcatalog/src/enterprise/auth/login.astro +2 -2
  25. package/eventcatalog/src/enterprise/auth/middleware/middleware-auth.ts +1 -1
  26. package/eventcatalog/src/utils/auth-astro/client.ts +89 -0
  27. package/eventcatalog/src/utils/auth-astro/config.ts +24 -0
  28. package/eventcatalog/src/utils/auth-astro/server.ts +74 -0
  29. package/package.json +3 -2
  30. package/dist/runtime-dependencies/auth-astro.mjs +0 -3
  31. package/dist/runtime-dependencies/auth-astro__client.mjs +0 -3
  32. package/dist/runtime-dependencies/auth-astro__server.mjs +0 -3
  33. package/dist/{chunk-U4YJSTGV.js → chunk-WRLNLWPW.js} +7 -7
@@ -36,7 +36,7 @@ module.exports = __toCommonJS(analytics_exports);
36
36
  var import_os = __toESM(require("os"), 1);
37
37
 
38
38
  // package.json
39
- var version = "4.12.0";
39
+ var version = "4.12.1";
40
40
 
41
41
  // src/constants.ts
42
42
  var VERSION = version;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "../chunk-SQXIGSIJ.js";
4
- import "../chunk-MZ5QBEFA.js";
3
+ } from "../chunk-HH6GPY4H.js";
4
+ import "../chunk-HHZFKWX7.js";
5
5
  export {
6
6
  raiseEvent
7
7
  };
@@ -176,7 +176,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
176
176
  var import_os = __toESM(require("os"), 1);
177
177
 
178
178
  // package.json
179
- var version = "4.12.0";
179
+ var version = "4.12.1";
180
180
 
181
181
  // src/constants.ts
182
182
  var VERSION = version;
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  log_build_default
3
- } from "../chunk-UC3HZHW4.js";
3
+ } from "../chunk-UWSBZYF5.js";
4
+ import "../chunk-HH6GPY4H.js";
4
5
  import "../chunk-ZAZHAVKB.js";
5
- import "../chunk-SQXIGSIJ.js";
6
- import "../chunk-MZ5QBEFA.js";
6
+ import "../chunk-HHZFKWX7.js";
7
7
  import "../chunk-RFIXKATC.js";
8
8
  export {
9
9
  log_build_default as default
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-MZ5QBEFA.js";
3
+ } from "./chunk-HHZFKWX7.js";
4
4
 
5
5
  // src/utils/cli-logger.ts
6
6
  import pc from "picocolors";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  logger
3
- } from "./chunk-Q46W7LGT.js";
3
+ } from "./chunk-DZZDBFUM.js";
4
4
  import {
5
5
  cleanup,
6
6
  getEventCatalogConfigFile
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-MZ5QBEFA.js";
3
+ } from "./chunk-HHZFKWX7.js";
4
4
 
5
5
  // src/analytics/analytics.js
6
6
  import os from "os";
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "4.12.0";
2
+ var version = "4.12.1";
3
3
 
4
4
  // src/constants.ts
5
5
  var VERSION = version;
@@ -1,11 +1,11 @@
1
+ import {
2
+ raiseEvent
3
+ } from "./chunk-HH6GPY4H.js";
1
4
  import {
2
5
  countResources,
3
6
  hashCatalogContent,
4
7
  serializeCounts
5
8
  } from "./chunk-ZAZHAVKB.js";
6
- import {
7
- raiseEvent
8
- } from "./chunk-SQXIGSIJ.js";
9
9
  import {
10
10
  getEventCatalogConfigFile,
11
11
  verifyRequiredFieldsAreInCatalogConfigFile
@@ -25,7 +25,7 @@ __export(constants_exports, {
25
25
  module.exports = __toCommonJS(constants_exports);
26
26
 
27
27
  // package.json
28
- var version = "4.12.0";
28
+ var version = "4.12.1";
29
29
 
30
30
  // src/constants.ts
31
31
  var VERSION = version;
package/dist/constants.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-MZ5QBEFA.js";
3
+ } from "./chunk-HHZFKWX7.js";
4
4
  export {
5
5
  VERSION
6
6
  };
@@ -181,7 +181,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
181
181
  var import_picocolors = __toESM(require("picocolors"), 1);
182
182
 
183
183
  // package.json
184
- var version = "4.12.0";
184
+ var version = "4.12.1";
185
185
 
186
186
  // src/constants.ts
187
187
  var VERSION = version;
@@ -1,25 +1,25 @@
1
+ import {
2
+ log_build_default
3
+ } from "./chunk-UWSBZYF5.js";
4
+ import "./chunk-HH6GPY4H.js";
5
+ import "./chunk-ZAZHAVKB.js";
1
6
  import {
2
7
  runMigrations
3
8
  } from "./chunk-XUAF2H54.js";
4
9
  import "./chunk-CA4U2JP7.js";
5
- import {
6
- log_build_default
7
- } from "./chunk-UC3HZHW4.js";
8
- import "./chunk-ZAZHAVKB.js";
9
10
  import {
10
11
  FederationConflictError,
11
12
  FederationDiagnosticError,
12
13
  federateCatalog
13
- } from "./chunk-U4YJSTGV.js";
14
- import "./chunk-WRNH5C3U.js";
15
- import "./chunk-5EPNFDT5.js";
16
- import "./chunk-A2RZR3U4.js";
17
- import "./chunk-R7Z5ALYI.js";
14
+ } from "./chunk-WRLNLWPW.js";
18
15
  import {
19
16
  getFederationDiagnosticCounts,
20
17
  getVisibleFederationDiagnostics
21
18
  } from "./chunk-JJPB6EOZ.js";
22
19
  import "./chunk-FV56YFM4.js";
20
+ import "./chunk-WRNH5C3U.js";
21
+ import "./chunk-5EPNFDT5.js";
22
+ import "./chunk-A2RZR3U4.js";
23
23
  import "./chunk-SDZQJTJW.js";
24
24
  import "./chunk-352FGP6W.js";
25
25
  import {
@@ -30,10 +30,10 @@ import {
30
30
  } from "./chunk-MDWB5HLO.js";
31
31
  import {
32
32
  generate
33
- } from "./chunk-DWTU2R2Z.js";
33
+ } from "./chunk-EVXNBTRA.js";
34
34
  import {
35
35
  logger
36
- } from "./chunk-Q46W7LGT.js";
36
+ } from "./chunk-DZZDBFUM.js";
37
37
  import {
38
38
  resolve_catalog_dependencies_default
39
39
  } from "./chunk-36RYTYT5.js";
@@ -47,7 +47,7 @@ import {
47
47
  import {
48
48
  watch
49
49
  } from "./chunk-U63GDPPY.js";
50
- import "./chunk-SQXIGSIJ.js";
50
+ import "./chunk-R7Z5ALYI.js";
51
51
  import {
52
52
  getAstroConfigPath
53
53
  } from "./chunk-VIJJ7JKH.js";
@@ -63,7 +63,7 @@ import {
63
63
  } from "./chunk-LFQJXLHG.js";
64
64
  import {
65
65
  VERSION
66
- } from "./chunk-MZ5QBEFA.js";
66
+ } from "./chunk-HHZFKWX7.js";
67
67
  import {
68
68
  getEventCatalogConfigFile,
69
69
  verifyRequiredFieldsAreInCatalogConfigFile
@@ -2,15 +2,15 @@ import {
2
2
  FederationConflictError,
3
3
  FederationDiagnosticError,
4
4
  federateCatalog
5
- } from "../chunk-U4YJSTGV.js";
5
+ } from "../chunk-WRLNLWPW.js";
6
+ import "../chunk-JJPB6EOZ.js";
7
+ import "../chunk-FV56YFM4.js";
6
8
  import "../chunk-WRNH5C3U.js";
7
9
  import "../chunk-5EPNFDT5.js";
8
10
  import "../chunk-A2RZR3U4.js";
9
- import "../chunk-R7Z5ALYI.js";
10
- import "../chunk-JJPB6EOZ.js";
11
- import "../chunk-FV56YFM4.js";
12
11
  import "../chunk-SDZQJTJW.js";
13
12
  import "../chunk-352FGP6W.js";
13
+ import "../chunk-R7Z5ALYI.js";
14
14
  import "../chunk-RFIXKATC.js";
15
15
  export {
16
16
  FederationConflictError,
package/dist/generate.cjs CHANGED
@@ -112,7 +112,7 @@ var getEventCatalogConfigFile = async (projectDirectory) => {
112
112
  var import_picocolors = __toESM(require("picocolors"), 1);
113
113
 
114
114
  // package.json
115
- var version = "4.12.0";
115
+ var version = "4.12.1";
116
116
 
117
117
  // src/constants.ts
118
118
  var VERSION = version;
package/dist/generate.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  generate
3
- } from "./chunk-DWTU2R2Z.js";
4
- import "./chunk-Q46W7LGT.js";
5
- import "./chunk-MZ5QBEFA.js";
3
+ } from "./chunk-EVXNBTRA.js";
4
+ import "./chunk-DZZDBFUM.js";
5
+ import "./chunk-HHZFKWX7.js";
6
6
  import "./chunk-RFIXKATC.js";
7
7
  export {
8
8
  generate
@@ -65,9 +65,6 @@
65
65
  "astro/logger/node": "astro__logger__node.mjs",
66
66
  "astro/types": "astro__types.mjs",
67
67
  "astro/zod": "astro__zod.mjs",
68
- "auth-astro": "auth-astro.mjs",
69
- "auth-astro/client": "auth-astro__client.mjs",
70
- "auth-astro/server": "auth-astro__server.mjs",
71
68
  "boxen": "boxen.mjs",
72
69
  "commander": "commander.mjs",
73
70
  "cross-env": "cross-env.mjs",
@@ -123,6 +120,7 @@
123
120
  "remark-gfm": "remark-gfm.mjs",
124
121
  "rimraf": "rimraf.mjs",
125
122
  "semver": "semver.mjs",
123
+ "set-cookie-parser": "set-cookie-parser.mjs",
126
124
  "shelljs": "shelljs.mjs",
127
125
  "sonner": "sonner.mjs",
128
126
  "sql.js": "sql.js.mjs",
@@ -0,0 +1,3 @@
1
+ export * from "set-cookie-parser";
2
+ import * as dependency from "set-cookie-parser";
3
+ export default dependency.default;
@@ -36,7 +36,7 @@ module.exports = __toCommonJS(cli_logger_exports);
36
36
  var import_picocolors = __toESM(require("picocolors"), 1);
37
37
 
38
38
  // package.json
39
- var version = "4.12.0";
39
+ var version = "4.12.1";
40
40
 
41
41
  // src/constants.ts
42
42
  var VERSION = version;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  logger
3
- } from "../chunk-Q46W7LGT.js";
4
- import "../chunk-MZ5QBEFA.js";
3
+ } from "../chunk-DZZDBFUM.js";
4
+ import "../chunk-HHZFKWX7.js";
5
5
  export {
6
6
  logger
7
7
  };
@@ -1,4 +1,4 @@
1
- import { defineConfig } from 'auth-astro';
1
+ import { defineConfig } from '@utils/auth-astro/config';
2
2
  import { join } from 'node:path';
3
3
  import GitHub from '@auth/core/providers/github';
4
4
  import Okta from '@auth/core/providers/okta';
@@ -22,9 +22,8 @@ const getAuthProviders = async () => {
22
22
  // GitHub provider
23
23
  if (authConfig.providers?.github) {
24
24
  const githubConfig = authConfig.providers.github;
25
- // GitHub sends an RFC 9207 `iss` parameter on OAuth callbacks. Pin the issuer so
26
- // validation works even when the resolved @auth/core copy predates the upstream
27
- // default (auth-astro's peer range can hoist an older @auth/core in user projects).
25
+ // GitHub sends an RFC 9207 `iss` parameter on OAuth callbacks. Pin the issuer,
26
+ // including for GitHub Enterprise base URLs, so validation works.
28
27
  const githubBaseUrl = githubConfig?.enterprise?.baseUrl ?? 'https://github.com';
29
28
  providers.push(
30
29
  GitHub({
@@ -8,7 +8,7 @@ import {
8
8
  isEventCatalogChatVisible,
9
9
  isEventCatalogChatEnabled,
10
10
  } from '@utils/feature';
11
- import { getSession } from 'auth-astro/server';
11
+ import { getSession } from '@utils/auth-astro/server';
12
12
  import { isAuthEnabled, isSSR } from '@utils/feature';
13
13
  import { EnvironmentDropdown } from './EnvironmentDropdown';
14
14
  import ChatPanelButton from './ChatPanel/ChatPanelButton';
@@ -28,6 +28,27 @@ const logo = {
28
28
  };
29
29
 
30
30
  const repositoryUrl = catalog?.repositoryUrl || 'https://github.com/event-catalog/eventcatalog';
31
+
32
+ const user = session?.user as { name?: string; email?: string; image?: string; provider?: string } | undefined;
33
+ const userName = user?.name || user?.email || 'User';
34
+ const userInitials =
35
+ userName
36
+ .split(/[\s@.]+/)
37
+ .filter(Boolean)
38
+ .map((part) => part[0])
39
+ .join('')
40
+ .substring(0, 2)
41
+ .toUpperCase() || 'U';
42
+ // Google avatar URLs are blocked by some browsers' tracking protection, so fall back to initials
43
+ const userImage = user?.image && !user.image.includes('googleusercontent.com') ? user.image : undefined;
44
+ const providerNames: Record<string, string> = {
45
+ github: 'GitHub',
46
+ google: 'Google',
47
+ okta: 'Okta',
48
+ auth0: 'Auth0',
49
+ 'microsoft-entra-id': 'Microsoft Entra ID',
50
+ };
51
+ const providerName = user?.provider ? providerNames[user.provider] || user.provider : undefined;
31
52
  ---
32
53
 
33
54
  <nav
@@ -58,46 +79,90 @@ const repositoryUrl = catalog?.repositoryUrl || 'https://github.com/event-catalo
58
79
  <button
59
80
  id="profile-menu-button"
60
81
  type="button"
61
- class="flex items-center focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-gray-400 rounded-full"
82
+ class="group flex items-center gap-1 rounded-full p-0.5 pr-1.5 text-[rgb(var(--ec-icon-color))] hover:text-[rgb(var(--ec-icon-hover))] hover:bg-[rgb(var(--ec-dropdown-hover))] aria-expanded:bg-[rgb(var(--ec-dropdown-hover))] transition-colors focus:outline-hidden focus-visible:ring-2 focus-visible:ring-[rgb(var(--ec-accent))]"
62
83
  aria-expanded="false"
63
- aria-haspopup="true"
64
- aria-label="User menu"
84
+ aria-haspopup="menu"
85
+ aria-controls="profile-dropdown"
86
+ aria-label={`Account menu for ${userName}`}
65
87
  >
66
- {session.user?.image && !session.user?.image?.includes('googleusercontent.com') ? (
88
+ {userImage ? (
67
89
  <img
68
- src={session.user.image}
69
- alt={session.user?.name || 'User'}
70
- class="h-9 w-9 rounded-full border-2 border-gray-200 hover:border-gray-400 transition-all shadow-xs"
90
+ src={userImage}
91
+ alt=""
92
+ class="h-8 w-8 rounded-full object-cover ring-1 ring-[rgb(var(--ec-page-border))]"
71
93
  />
72
94
  ) : (
73
- <div class="h-9 w-9 rounded-full border-2 border-gray-200 hover:border-gray-400 transition-all bg-gray-100 hover:bg-gray-200 flex items-center justify-center text-sm font-medium text-gray-600 shadow-xs">
74
- {session.user?.name
75
- ? session.user.name
76
- .split(' ')
77
- .map((n) => n[0])
78
- .join('')
79
- .substring(0, 2)
80
- .toUpperCase()
81
- : 'U'}
82
- </div>
95
+ <span class="h-8 w-8 rounded-full bg-[rgb(var(--ec-accent-subtle))] text-[rgb(var(--ec-accent))] ring-1 ring-[rgb(var(--ec-page-border))] flex items-center justify-center text-xs font-semibold">
96
+ {userInitials}
97
+ </span>
83
98
  )}
99
+ <svg
100
+ viewBox="0 0 24 24"
101
+ class="h-4 w-4 transition-transform group-aria-expanded:rotate-180"
102
+ fill="none"
103
+ stroke="currentColor"
104
+ stroke-width="2"
105
+ stroke-linecap="round"
106
+ stroke-linejoin="round"
107
+ aria-hidden="true"
108
+ >
109
+ <path d="m6 9 6 6 6-6" />
110
+ </svg>
84
111
  </button>
85
112
  <div
86
113
  id="profile-dropdown"
87
- class="ec-hidden absolute right-0 mt-2 w-48 bg-[rgb(var(--ec-dropdown-bg))] rounded-lg shadow-md py-1 z-50 border-2 border-[rgb(var(--ec-dropdown-border))] overflow-hidden"
114
+ role="menu"
115
+ aria-labelledby="profile-menu-button"
116
+ class="ec-hidden absolute right-0 mt-2 w-64 bg-[rgb(var(--ec-dropdown-bg))] rounded-xl shadow-lg z-50 border border-[rgb(var(--ec-dropdown-border))] overflow-hidden"
88
117
  >
89
- <div class="px-4 py-2 text-sm text-[rgb(var(--ec-dropdown-text))] border-b border-[rgb(var(--ec-dropdown-border))]">
90
- <div class="font-semibold">{session.user?.name || 'User'}</div>
91
- {session.user?.email && (
92
- <div class="text-[rgb(var(--ec-icon-color))] text-xs mt-0.5">{session.user.email}</div>
118
+ <div class="flex items-center gap-3 px-4 py-3 border-b border-[rgb(var(--ec-dropdown-border))]">
119
+ {userImage ? (
120
+ <img
121
+ src={userImage}
122
+ alt=""
123
+ class="h-10 w-10 shrink-0 rounded-full object-cover ring-1 ring-[rgb(var(--ec-page-border))]"
124
+ />
125
+ ) : (
126
+ <span class="h-10 w-10 shrink-0 rounded-full bg-[rgb(var(--ec-accent-subtle))] text-[rgb(var(--ec-accent))] flex items-center justify-center text-sm font-semibold">
127
+ {userInitials}
128
+ </span>
93
129
  )}
130
+ <div class="min-w-0">
131
+ <div class="truncate text-sm font-semibold text-[rgb(var(--ec-dropdown-text))]">{userName}</div>
132
+ {user?.email && user.email !== userName && (
133
+ <div class="truncate text-xs font-normal text-[rgb(var(--ec-page-text-muted))]">{user.email}</div>
134
+ )}
135
+ {providerName && (
136
+ <div class="truncate text-xs font-normal text-[rgb(var(--ec-page-text-muted))]">
137
+ Signed in with {providerName}
138
+ </div>
139
+ )}
140
+ </div>
141
+ </div>
142
+ <div class="p-1">
143
+ <button
144
+ id="signout-btn"
145
+ type="button"
146
+ role="menuitem"
147
+ class="flex w-full items-center gap-2 rounded-lg px-3 py-2 text-left text-sm font-medium text-[rgb(var(--ec-dropdown-text))] hover:bg-[rgb(var(--ec-dropdown-hover))] focus:outline-hidden focus-visible:bg-[rgb(var(--ec-dropdown-hover))] transition-colors"
148
+ >
149
+ <svg
150
+ viewBox="0 0 24 24"
151
+ class="h-4 w-4 text-[rgb(var(--ec-icon-color))]"
152
+ fill="none"
153
+ stroke="currentColor"
154
+ stroke-width="2"
155
+ stroke-linecap="round"
156
+ stroke-linejoin="round"
157
+ aria-hidden="true"
158
+ >
159
+ <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" />
160
+ <polyline points="16 17 21 12 16 7" />
161
+ <line x1="21" x2="9" y1="12" y2="12" />
162
+ </svg>
163
+ Sign out
164
+ </button>
94
165
  </div>
95
- <button
96
- id="signout-btn"
97
- class="block w-full text-left px-4 py-2 text-sm text-[rgb(var(--ec-dropdown-text))] hover:bg-[rgb(var(--ec-dropdown-hover))] transition-colors font-medium"
98
- >
99
- Sign out
100
- </button>
101
166
  </div>
102
167
  </div>
103
168
  </div>
@@ -210,9 +275,15 @@ const repositoryUrl = catalog?.repositoryUrl || 'https://github.com/event-catalo
210
275
  <!-- Spacer to prevent content from being hidden under the fixed header -->
211
276
 
212
277
  <script>
213
- import { signOut } from 'auth-astro/client';
278
+ import { signOut } from '@utils/auth-astro/client';
214
279
 
215
280
  function initializeHeader() {
281
+ // ClientRouter fires astro:page-load on the first load too, and the header persists across
282
+ // navigations. Bind once per element so clicks don't toggle the menus open and shut again.
283
+ const header = document.getElementById('eventcatalog-header');
284
+ if (!header || header.dataset.initialized === 'true') return;
285
+ header.dataset.initialized = 'true';
286
+
216
287
  const menuToggle = document.getElementById('menu-toggle');
217
288
  const mobileMenu = document.getElementById('mobile-menu');
218
289
 
@@ -261,10 +332,7 @@ const repositoryUrl = catalog?.repositoryUrl || 'https://github.com/event-catalo
261
332
  }
262
333
  }
263
334
 
264
- // Initialize on first load
265
335
  initializeHeader();
266
-
267
- // Re-initialize after Astro view transitions (needed because of transition:persist on header)
268
336
  document.addEventListener('astro:page-load', initializeHeader);
269
337
  </script>
270
338
 
@@ -3,6 +3,6 @@
3
3
  * See /packages/core/eventcatalog/src/enterprise/LICENSE
4
4
  */
5
5
 
6
- import { AstroAuth } from 'auth-astro/server';
6
+ import { AstroAuth } from '@utils/auth-astro/server';
7
7
  export const prerender = false;
8
8
  export const { GET, POST } = AstroAuth();
@@ -5,7 +5,7 @@ const { title, logo } = config;
5
5
  import { join } from 'node:path';
6
6
  import { isAuthEnabled, isSSR } from '@utils/feature';
7
7
  import { buildUrl } from '@utils/url-builder';
8
- import { getSession } from 'auth-astro/server';
8
+ import { getSession } from '@utils/auth-astro/server';
9
9
 
10
10
  const catalogDirectory = process.env.PROJECT_DIR || process.cwd();
11
11
 
@@ -408,7 +408,7 @@ const providerConfig = {
408
408
  </html>
409
409
 
410
410
  <script>
411
- import { signIn } from 'auth-astro/client';
411
+ import { signIn } from '@utils/auth-astro/client';
412
412
 
413
413
  // Add event listeners to all provider login buttons
414
414
  const providerButtons = document.querySelectorAll('.provider-login-btn');
@@ -5,7 +5,7 @@
5
5
 
6
6
  // src/middleware/auth.ts
7
7
  import type { MiddlewareHandler } from 'astro';
8
- import { getSession } from 'auth-astro/server';
8
+ import { getSession } from '@utils/auth-astro/server';
9
9
  import { isAuthEnabled, isEventCatalogMCPAuthEnabled } from '@utils/feature';
10
10
  import jwt from 'jsonwebtoken';
11
11
  import { isLLMSTxtEnabled } from '@utils/feature';
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Adapted from auth-astro 4.2.0 (MIT, https://github.com/nowaythatworked/auth-astro).
3
+ * See ./config.ts for why this lives in Core.
4
+ */
5
+
6
+ interface AstroSignInOptions extends Record<string, unknown> {
7
+ /** Where to send the user after signing in. Defaults to the current page. */
8
+ callbackUrl?: string;
9
+ /** Redirect after signing in. Defaults to `true`. */
10
+ redirect?: boolean;
11
+ /** Base path for authentication. Defaults to `/api/auth`. */
12
+ prefix?: string;
13
+ }
14
+
15
+ interface AstroSignOutParams {
16
+ /** Where to send the user after signing out. Defaults to the current page. */
17
+ callbackUrl?: string;
18
+ /** Base path for authentication. Defaults to `/api/auth`. */
19
+ prefix?: string;
20
+ }
21
+
22
+ /**
23
+ * Starts a sign-in flow for a provider. Adds the CSRF token to the request.
24
+ */
25
+ export async function signIn(providerId?: string, options?: AstroSignInOptions, authorizationParams?: Record<string, string>) {
26
+ const { callbackUrl = window.location.href, redirect = true } = options ?? {};
27
+ const { prefix = '/api/auth', ...opts } = options ?? {};
28
+
29
+ const isCredentials = providerId === 'credentials';
30
+ const isEmail = providerId === 'email';
31
+ const isSupportingReturn = isCredentials || isEmail;
32
+
33
+ const signInUrl = `${prefix}/${isCredentials ? 'callback' : 'signin'}/${providerId}`;
34
+ const _signInUrl = `${signInUrl}?${new URLSearchParams(authorizationParams)}`;
35
+
36
+ const csrfTokenResponse = await fetch(`${prefix}/csrf`);
37
+ const { csrfToken } = await csrfTokenResponse.json();
38
+
39
+ const res = await fetch(_signInUrl, {
40
+ method: 'post',
41
+ headers: {
42
+ 'Content-Type': 'application/x-www-form-urlencoded',
43
+ 'X-Auth-Return-Redirect': '1',
44
+ },
45
+ body: new URLSearchParams({
46
+ ...(opts as Record<string, string>),
47
+ csrfToken,
48
+ callbackUrl,
49
+ }),
50
+ });
51
+
52
+ const data = await res.clone().json();
53
+ const error = new URL(data.url).searchParams.get('error');
54
+
55
+ if (redirect || !isSupportingReturn || !error) {
56
+ window.location.href = data.url ?? callbackUrl;
57
+ // The browser does not reload when only the hash changes
58
+ if (data.url.includes('#')) window.location.reload();
59
+ return;
60
+ }
61
+
62
+ return res;
63
+ }
64
+
65
+ /**
66
+ * Signs the user out by removing the session cookie. Adds the CSRF token to the request.
67
+ */
68
+ export async function signOut(options?: AstroSignOutParams) {
69
+ const { callbackUrl = window.location.href, prefix = '/api/auth' } = options ?? {};
70
+ const csrfTokenResponse = await fetch(`${prefix}/csrf`);
71
+ const { csrfToken } = await csrfTokenResponse.json();
72
+ const res = await fetch(`${prefix}/signout`, {
73
+ method: 'post',
74
+ headers: {
75
+ 'Content-Type': 'application/x-www-form-urlencoded',
76
+ 'X-Auth-Return-Redirect': '1',
77
+ },
78
+ body: new URLSearchParams({
79
+ csrfToken,
80
+ callbackUrl,
81
+ }),
82
+ });
83
+ const data = await res.json();
84
+
85
+ const url = data.url ?? callbackUrl;
86
+ window.location.href = url;
87
+ // The browser does not reload when only the hash changes
88
+ if (url.includes('#')) window.location.reload();
89
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Adapted from auth-astro 4.2.0 (MIT, https://github.com/nowaythatworked/auth-astro).
3
+ *
4
+ * Kept in Core so every Auth.js import resolves to Core's own `@auth/core`. The
5
+ * auth-astro package pins an older `@auth/core` peer range, which makes npm install
6
+ * a second, vulnerable copy in user projects.
7
+ */
8
+ import type { AuthConfig } from '@auth/core/types';
9
+
10
+ export interface AstroAuthConfig {
11
+ /**
12
+ * Base path for the auth routes.
13
+ * @default '/api/auth'
14
+ */
15
+ prefix?: string;
16
+ }
17
+
18
+ export interface FullAuthConfig extends AstroAuthConfig, Omit<AuthConfig, 'raw'> {}
19
+
20
+ export const defineConfig = (config: FullAuthConfig) => {
21
+ config.prefix ??= '/api/auth';
22
+ config.basePath = config.prefix;
23
+ return config;
24
+ };
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Adapted from auth-astro 4.2.0 (MIT, https://github.com/nowaythatworked/auth-astro).
3
+ * See ./config.ts for why this lives in Core.
4
+ */
5
+ import { Auth } from '@auth/core';
6
+ import type { AuthAction, Session } from '@auth/core/types';
7
+ import type { APIContext } from 'astro';
8
+ import { parseString } from 'set-cookie-parser';
9
+ import authConfig from 'auth:config';
10
+
11
+ const actions: AuthAction[] = ['providers', 'session', 'csrf', 'signin', 'signout', 'callback', 'verify-request', 'error'];
12
+
13
+ function AstroAuthHandler(prefix: string, options = authConfig) {
14
+ return async ({ cookies, request }: APIContext) => {
15
+ const url = new URL(request.url);
16
+ const action = url.pathname.slice(prefix.length + 1).split('/')[0] as AuthAction;
17
+
18
+ if (!actions.includes(action) || !url.pathname.startsWith(prefix + '/')) return;
19
+
20
+ const res = await Auth(request, options);
21
+ if (['callback', 'signin', 'signout'].includes(action)) {
22
+ // Multiple Set-Cookie headers can't be concatenated, so hand each one to Astro
23
+ const setCookies = res.headers.getSetCookie();
24
+ if (setCookies.length > 0) {
25
+ setCookies.forEach((cookie) => {
26
+ const { name, value, ...cookieOptions } = parseString(cookie);
27
+ cookies.set(name, value, cookieOptions as Parameters<(typeof cookies)['set']>[2]);
28
+ });
29
+ res.headers.delete('Set-Cookie');
30
+ }
31
+ }
32
+ return res;
33
+ };
34
+ }
35
+
36
+ /**
37
+ * Creates the Astro GET and POST endpoints for authentication.
38
+ */
39
+ export function AstroAuth(options = authConfig) {
40
+ const { AUTH_SECRET, AUTH_TRUST_HOST, VERCEL, NODE_ENV } = import.meta.env;
41
+
42
+ options.secret ??= AUTH_SECRET;
43
+ options.trustHost ??= !!(AUTH_TRUST_HOST ?? VERCEL ?? NODE_ENV !== 'production');
44
+
45
+ const { prefix = '/api/auth', ...authOptions } = options;
46
+
47
+ const handler = AstroAuthHandler(prefix, authOptions);
48
+ return {
49
+ async GET(context: APIContext) {
50
+ return await handler(context);
51
+ },
52
+ async POST(context: APIContext) {
53
+ return await handler(context);
54
+ },
55
+ };
56
+ }
57
+
58
+ /**
59
+ * Fetches the current session, or `null` if there is none.
60
+ */
61
+ export async function getSession(req: Request, options = authConfig): Promise<Session | null> {
62
+ options.secret ??= import.meta.env.AUTH_SECRET;
63
+ options.trustHost ??= true;
64
+
65
+ const url = new URL(`${options.prefix}/session`, req.url);
66
+ const response = await Auth(new Request(url, { headers: req.headers }), options);
67
+ const { status = 200 } = response;
68
+
69
+ const data = await response.json();
70
+
71
+ if (!data || !Object.keys(data).length) return null;
72
+ if (status === 200) return data;
73
+ throw new Error(data.message);
74
+ }
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "license": "SEE LICENSE IN LICENSE",
9
9
  "type": "module",
10
- "version": "4.12.0",
10
+ "version": "4.12.1",
11
11
  "publishConfig": {
12
12
  "access": "public"
13
13
  },
@@ -78,7 +78,6 @@
78
78
  "astro": "7.3.3",
79
79
  "astro-expressive-code": "^0.44.0",
80
80
  "astro-seo": "^0.8.4",
81
- "auth-astro": "^4.2.0",
82
81
  "boxen": "^8.0.1",
83
82
  "commander": "^12.1.0",
84
83
  "cross-env": "^7.0.3",
@@ -124,6 +123,7 @@
124
123
  "remark-gfm": "^4.0.1",
125
124
  "rimraf": "^6.1.3",
126
125
  "semver": "7.6.3",
126
+ "set-cookie-parser": "^2.7.1",
127
127
  "shelljs": "^0.9.0",
128
128
  "sonner": "^2.0.7",
129
129
  "sql.js": "^1.12.0",
@@ -155,6 +155,7 @@
155
155
  "@types/react-dom": "^19.2.3",
156
156
  "@types/react-syntax-highlighter": "^15.5.13",
157
157
  "@types/semver": "^7.5.8",
158
+ "@types/set-cookie-parser": "^2.4.10",
158
159
  "@types/shelljs": "^0.8.15",
159
160
  "@types/update-notifier": "^6.0.8",
160
161
  "@types/uuid": "^10.0.0",
@@ -1,3 +0,0 @@
1
- export * from "auth-astro";
2
- import * as dependency from "auth-astro";
3
- export default dependency.default;
@@ -1,3 +0,0 @@
1
- export * from "auth-astro/client";
2
- import * as dependency from "auth-astro/client";
3
- export default dependency.default;
@@ -1,3 +0,0 @@
1
- export * from "auth-astro/server";
2
- import * as dependency from "auth-astro/server";
3
- export default dependency.default;
@@ -1,3 +1,10 @@
1
+ import {
2
+ getFederationDiagnostics,
3
+ resolveFederationRules
4
+ } from "./chunk-JJPB6EOZ.js";
5
+ import {
6
+ isFederationEnabled
7
+ } from "./chunk-FV56YFM4.js";
1
8
  import {
2
9
  withFederationOutputTransaction
3
10
  } from "./chunk-WRNH5C3U.js";
@@ -10,13 +17,6 @@ import {
10
17
  import {
11
18
  createFederationContentCache
12
19
  } from "./chunk-R7Z5ALYI.js";
13
- import {
14
- getFederationDiagnostics,
15
- resolveFederationRules
16
- } from "./chunk-JJPB6EOZ.js";
17
- import {
18
- isFederationEnabled
19
- } from "./chunk-FV56YFM4.js";
20
20
  import {
21
21
  getEventCatalogConfigFile
22
22
  } from "./chunk-RFIXKATC.js";