zudoku 0.3.1-dev.8 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/LICENSE.md +21 -0
  2. package/dist/config/config.d.ts +0 -3
  3. package/dist/lib/authentication/authentication.d.ts +1 -0
  4. package/dist/lib/authentication/components/CallbackHandler.d.ts +3 -0
  5. package/dist/lib/authentication/components/CallbackHandler.js +34 -0
  6. package/dist/lib/authentication/components/CallbackHandler.js.map +1 -0
  7. package/dist/lib/authentication/providers/auth0.js +11 -6
  8. package/dist/lib/authentication/providers/auth0.js.map +1 -1
  9. package/dist/lib/authentication/providers/openid.d.ts +4 -13
  10. package/dist/lib/authentication/providers/openid.js +50 -49
  11. package/dist/lib/authentication/providers/openid.js.map +1 -1
  12. package/dist/lib/components/Header.js +2 -4
  13. package/dist/lib/components/Header.js.map +1 -1
  14. package/dist/lib/components/Layout.js +5 -1
  15. package/dist/lib/components/Layout.js.map +1 -1
  16. package/dist/lib/components/context/ZudokuProvider.js +1 -3
  17. package/dist/lib/components/context/ZudokuProvider.js.map +1 -1
  18. package/dist/lib/core/DevPortalContext.d.ts +1 -4
  19. package/dist/lib/core/DevPortalContext.js +2 -2
  20. package/dist/lib/core/DevPortalContext.js.map +1 -1
  21. package/dist/lib/core/plugins.d.ts +2 -4
  22. package/dist/lib/core/plugins.js.map +1 -1
  23. package/dist/lib/plugins/openapi/OperationList.js +3 -4
  24. package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
  25. package/dist/lib/plugins/openapi/OperationListItem.js +2 -3
  26. package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
  27. package/dist/lib/plugins/openapi/ParameterListItem.js +1 -1
  28. package/dist/lib/plugins/openapi/ParameterListItem.js.map +1 -1
  29. package/dist/lib/plugins/openapi/playground/PlaygroundDialog.js +2 -2
  30. package/dist/lib/plugins/openapi/playground/PlaygroundDialog.js.map +1 -1
  31. package/lib/{AuthenticationPlugin-CH5NSVOu.js → AuthenticationPlugin-owbEUimP.js} +3 -3
  32. package/lib/{AuthenticationPlugin-CH5NSVOu.js.map → AuthenticationPlugin-owbEUimP.js.map} +1 -1
  33. package/lib/{CategoryHeading-z15xh7Jb.js → CategoryHeading-DnPprxtD.js} +2 -2
  34. package/lib/{CategoryHeading-z15xh7Jb.js.map → CategoryHeading-DnPprxtD.js.map} +1 -1
  35. package/lib/{Combination-DTfV-c98.js → Combination-DruV0zX_.js} +3 -3
  36. package/lib/{Combination-DTfV-c98.js.map → Combination-DruV0zX_.js.map} +1 -1
  37. package/lib/ErrorPage-PUg985n_.js +18 -0
  38. package/lib/ErrorPage-PUg985n_.js.map +1 -0
  39. package/lib/{Input-CzXNm7xb.js → Input-CBfi9Yjc.js} +4 -4
  40. package/lib/{Input-CzXNm7xb.js.map → Input-CBfi9Yjc.js.map} +1 -1
  41. package/lib/{Markdown-CEccPMI_.js → Markdown-Chb9VIBv.js} +2 -2
  42. package/lib/{Markdown-CEccPMI_.js.map → Markdown-Chb9VIBv.js.map} +1 -1
  43. package/lib/{MdxPage-CnqOoqvp.js → MdxPage-CIBHMwTd.js} +5 -5
  44. package/lib/{MdxPage-CnqOoqvp.js.map → MdxPage-CIBHMwTd.js.map} +1 -1
  45. package/lib/{OperationList-CJajXSzC.js → OperationList-CZiSz5JH.js} +115 -120
  46. package/lib/OperationList-CZiSz5JH.js.map +1 -0
  47. package/lib/{Route-BpMrPUVN.js → Route-Cle-r-bq.js} +4 -4
  48. package/lib/{Route-BpMrPUVN.js.map → Route-Cle-r-bq.js.map} +1 -1
  49. package/lib/{Spinner-BT_AYFrA.js → SidebarBadge-Ba0PhibA.js} +66 -76
  50. package/lib/SidebarBadge-Ba0PhibA.js.map +1 -0
  51. package/lib/{SlotletProvider-ByLSCZQa.js → SlotletProvider-Dq80og6-.js} +4 -4
  52. package/lib/{SlotletProvider-ByLSCZQa.js.map → SlotletProvider-Dq80og6-.js.map} +1 -1
  53. package/lib/Spinner-CvXZ7QK4.js +15 -0
  54. package/lib/Spinner-CvXZ7QK4.js.map +1 -0
  55. package/lib/{ZudokuContext-BIZ8zHbZ.js → ZudokuContext-BQ45UjcB.js} +2 -2
  56. package/lib/{ZudokuContext-BIZ8zHbZ.js.map → ZudokuContext-BQ45UjcB.js.map} +1 -1
  57. package/lib/{index-B6zugCnN.js → index-Br1MQPxy.js} +595 -587
  58. package/lib/index-Br1MQPxy.js.map +1 -0
  59. package/lib/{index-Dz4LyXZI.js → index-DCJ9wEIV.js} +3 -3
  60. package/lib/{index-Dz4LyXZI.js.map → index-DCJ9wEIV.js.map} +1 -1
  61. package/lib/{index-7kcHaXD6.js → index-Yjb2PyPF.js} +4 -4
  62. package/lib/{index-7kcHaXD6.js.map → index-Yjb2PyPF.js.map} +1 -1
  63. package/lib/{urql-DrBfkb92.js → urql-YhcsXYy8.js} +2 -2
  64. package/lib/urql-YhcsXYy8.js.map +1 -0
  65. package/lib/{utils-Bh4upQ0e.js → utils-pDHePxa0.js} +3 -3
  66. package/lib/{utils-Bh4upQ0e.js.map → utils-pDHePxa0.js.map} +1 -1
  67. package/lib/zudoku.auth-auth0.js +24 -22
  68. package/lib/zudoku.auth-auth0.js.map +1 -1
  69. package/lib/zudoku.auth-clerk.js +1 -1
  70. package/lib/zudoku.auth-openid.js +527 -469
  71. package/lib/zudoku.auth-openid.js.map +1 -1
  72. package/lib/zudoku.components.js +434 -443
  73. package/lib/zudoku.components.js.map +1 -1
  74. package/lib/zudoku.openapi-worker.js +1 -1
  75. package/lib/zudoku.plugin-api-keys.js +6 -6
  76. package/lib/zudoku.plugin-custom-page.js +1 -1
  77. package/lib/zudoku.plugin-markdown.js +1 -1
  78. package/lib/zudoku.plugin-openapi.js +8 -7
  79. package/lib/zudoku.plugin-openapi.js.map +1 -1
  80. package/package.json +80 -100
  81. package/src/app/main.css +1 -1
  82. package/src/lib/authentication/authentication.ts +1 -0
  83. package/src/lib/authentication/components/CallbackHandler.tsx +59 -0
  84. package/src/lib/authentication/providers/auth0.tsx +13 -7
  85. package/src/lib/authentication/providers/openid.tsx +56 -58
  86. package/src/lib/components/Header.tsx +3 -10
  87. package/src/lib/components/Layout.tsx +6 -1
  88. package/src/lib/components/context/ZudokuProvider.tsx +1 -4
  89. package/src/lib/core/DevPortalContext.ts +2 -7
  90. package/src/lib/core/plugins.ts +1 -2
  91. package/src/lib/plugins/openapi/OperationList.tsx +3 -7
  92. package/src/lib/plugins/openapi/OperationListItem.tsx +2 -3
  93. package/src/lib/plugins/openapi/ParameterListItem.tsx +1 -1
  94. package/src/lib/plugins/openapi/playground/PlaygroundDialog.tsx +27 -5
  95. package/dist/lib/plugins/openapi/util/prose.d.ts +0 -1
  96. package/dist/lib/plugins/openapi/util/prose.js +0 -4
  97. package/dist/lib/plugins/openapi/util/prose.js.map +0 -1
  98. package/lib/OperationList-CJajXSzC.js.map +0 -1
  99. package/lib/Spinner-BT_AYFrA.js.map +0 -1
  100. package/lib/index-B6zugCnN.js.map +0 -1
  101. package/lib/urql-DrBfkb92.js.map +0 -1
  102. package/src/lib/plugins/openapi/util/prose.ts +0 -7
@@ -13,7 +13,7 @@ var ir = (t, e, n, r) => ({
13
13
  return m(t, e, r);
14
14
  }
15
15
  });
16
- import { C as Uo, c as Vo, m as Bo, f as Go } from "./urql-DrBfkb92.js";
16
+ import { C as Uo, c as Vo, m as Bo, f as Go } from "./urql-YhcsXYy8.js";
17
17
  import { a as Iu } from "./_commonjsHelpers-BVfed4GL.js";
18
18
  import { s as _u } from "./slugify-CiPVjteN.js";
19
19
  function Ou(t, e) {
@@ -1,12 +1,12 @@
1
1
  import { j as e } from "./jsx-runtime-B6kdoens.js";
2
- import { S as p, R as f } from "./SlotletProvider-ByLSCZQa.js";
3
- import { u as g, a as u, I as j, S as k, b as v, c as w, d as b, e as K, f as y } from "./Input-CzXNm7xb.js";
4
- import { b as N, L as x, O as E } from "./index-7kcHaXD6.js";
5
- import { u as h, t as A, j as S } from "./ZudokuContext-BIZ8zHbZ.js";
6
- import { B as l, p as I } from "./Combination-DTfV-c98.js";
2
+ import { S as p, R as f } from "./SlotletProvider-Dq80og6-.js";
3
+ import { u as g, a as u, I as j, S as k, b as v, c as w, d as b, e as K, f as y } from "./Input-CBfi9Yjc.js";
4
+ import { e as N, L as x, O as E } from "./index-Yjb2PyPF.js";
5
+ import { u as h, t as A, j as S } from "./ZudokuContext-BQ45UjcB.js";
6
+ import { B as l, p as I } from "./Combination-DruV0zX_.js";
7
7
  import { D as P } from "./DeveloperHint-BQSFXH01.js";
8
8
  import { useState as C } from "react";
9
- import { c as d, a as D } from "./Markdown-CEccPMI_.js";
9
+ import { c as d, a as D } from "./Markdown-Chb9VIBv.js";
10
10
  /**
11
11
  * @license lucide-react v0.378.0 - ISC
12
12
  *
@@ -1,5 +1,5 @@
1
1
  import { j as m } from "./jsx-runtime-B6kdoens.js";
2
- import { P as o } from "./Markdown-CEccPMI_.js";
2
+ import { P as o } from "./Markdown-Chb9VIBv.js";
3
3
  const l = (s) => ({
4
4
  getRoutes: () => s.map(({ path: e, element: t }) => ({
5
5
  path: e,
@@ -6,7 +6,7 @@ const u = (t, e) => Object.entries(t).flatMap(([a, r]) => {
6
6
  return {
7
7
  path: s.at(-1) === "index" ? s.slice(0, -1).join("/") : o,
8
8
  lazy: async () => {
9
- const { MdxPage: i } = await import("./MdxPage-CnqOoqvp.js"), { default: p, ...c } = await r();
9
+ const { MdxPage: i } = await import("./MdxPage-CIBHMwTd.js"), { default: p, ...c } = await r();
10
10
  return {
11
11
  element: /* @__PURE__ */ m.jsx(
12
12
  i,
@@ -1,14 +1,15 @@
1
1
  import "./jsx-runtime-B6kdoens.js";
2
- import { o as l } from "./index-B6zugCnN.js";
3
- import "./urql-DrBfkb92.js";
4
- import "./ZudokuContext-BIZ8zHbZ.js";
2
+ import { o as s } from "./index-Br1MQPxy.js";
3
+ import "./urql-YhcsXYy8.js";
4
+ import "./ZudokuContext-BQ45UjcB.js";
5
5
  import "zudoku/openapi-worker";
6
- import "./Combination-DTfV-c98.js";
7
- import "./Markdown-CEccPMI_.js";
6
+ import "./Combination-DruV0zX_.js";
7
+ import "./ErrorPage-PUg985n_.js";
8
+ import "./Markdown-Chb9VIBv.js";
8
9
  import "./joinPath-B7kNnUX4.js";
9
10
  import "./router-BiRCp01d.js";
10
- import "./index-7kcHaXD6.js";
11
+ import "./index-Yjb2PyPF.js";
11
12
  export {
12
- l as openApiPlugin
13
+ s as openApiPlugin
13
14
  };
14
15
  //# sourceMappingURL=zudoku.plugin-openapi.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"zudoku.plugin-openapi.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;"}
1
+ {"version":3,"file":"zudoku.plugin-openapi.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zudoku",
3
- "version": "0.3.1-dev.8",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -13,104 +13,73 @@
13
13
  "zudoku": "./cli.js"
14
14
  },
15
15
  "exports": {
16
- ".": "./src/index.ts",
17
- "./internal": "./src/internal.ts",
18
- "./auth/clerk": "./src/lib/authentication/providers/clerk.ts",
19
- "./auth/auth0": "./src/lib/authentication/providers/auth0.ts",
20
- "./auth/openid": "./src/lib/authentication/providers/openid.ts",
21
- "./plugins/api-keys": "./src/lib/plugins/api-keys/index.ts",
22
- "./plugins/markdown": "./src/lib/plugins/markdown/index.ts",
23
- "./plugins/openapi": "./src/lib/plugins/openapi/index.ts",
24
- "./plugins/redirect": "./src/lib/plugins/redirect/index.ts",
25
- "./plugins/custom-page": "./src/lib/plugins/custom-page/index.ts",
26
- "./plugins/search-inkeep": "./src/lib/plugins/search-inkeep/index.ts",
27
- "./openapi-worker": "./src/lib/plugins/openapi-worker.ts",
28
- "./components": "./src/lib/components/index.ts",
29
- "./vite": "./src/vite/plugin.ts",
30
- "./tailwind": "./src/app/tailwind.ts",
31
- "./app/*": "./src/app/*"
32
- },
33
- "publishConfig": {
34
- "module": "./dist/index.js",
35
- "types": "./dist/index.d.ts",
36
- "exports": {
37
- ".": {
38
- "import": "./dist/index.js",
39
- "types": "./dist/index.d.ts"
40
- },
41
- "./internal": {
42
- "import": "./dist/internal.js"
43
- },
44
- "./auth/clerk": {
45
- "import": "./lib/zudoku.auth-clerk.js",
46
- "types": "./dist/lib/authentication/providers/clerk.d.ts"
47
- },
48
- "./auth/auth0": {
49
- "import": "./lib/zudoku.auth-auth0.js",
50
- "types": "./dist/lib/authentication/providers/auth0.d.ts"
51
- },
52
- "./auth/openid": {
53
- "import": "./lib/zudoku.auth-openid.js",
54
- "types": "./dist/lib/authentication/providers/openid.d.ts"
55
- },
56
- "./plugins/api-keys": {
57
- "import": "./lib/zudoku.plugin-api-keys.js",
58
- "types": "./dist/lib/plugins/api-keys/index.d.ts"
59
- },
60
- "./plugins/markdown": {
61
- "import": "./lib/zudoku.plugin-markdown.js",
62
- "types": "./dist/lib/plugins/markdown/index.d.ts"
63
- },
64
- "./plugins/openapi": {
65
- "import": "./lib/zudoku.plugin-openapi.js",
66
- "types": "./dist/lib/plugins/openapi/index.d.ts"
67
- },
68
- "./plugins/redirect": {
69
- "import": "./lib/zudoku.plugin-redirect.js",
70
- "types": "./dist/lib/plugins/redirect/index.d.ts"
71
- },
72
- "./plugins/custom-page": {
73
- "import": "./lib/zudoku.plugin-custom-page.js",
74
- "types": "./dist/lib/plugins/custom-page/index.d.ts"
75
- },
76
- "./plugins/search-inkeep": {
77
- "import": "./lib/zudoku.plugin-search-inkeep.js",
78
- "types": "./dist/lib/plugins/search-inkeep/index.d.ts"
79
- },
80
- "./openapi-worker": {
81
- "import": "./lib/zudoku.openapi-worker.js",
82
- "types": "./dist/lib/plugins/openapi-worker.d.ts"
83
- },
84
- "./components": {
85
- "import": "./lib/zudoku.components.js",
86
- "types": "./dist/lib/components/index.d.ts"
87
- },
88
- "./vite": {
89
- "require": "./dist/vite/plugin.js",
90
- "import": "./dist/vite/plugin.js"
91
- },
92
- "./tailwind": {
93
- "require": "./dist/app/tailwind.js",
94
- "import": "./dist/app/tailwind.js"
95
- },
96
- "./main.css": {
97
- "require": "./src/app/main.css",
98
- "import": "./src/app/main.css"
99
- },
100
- "./app/*": {
101
- "import": "./src/app/*"
102
- }
16
+ ".": {
17
+ "import": "./dist/index.js",
18
+ "types": "./dist/index.d.ts"
19
+ },
20
+ "./internal": {
21
+ "import": "./dist/internal.js"
22
+ },
23
+ "./auth/clerk": {
24
+ "import": "./lib/zudoku.auth-clerk.js",
25
+ "types": "./dist/lib/authentication/providers/clerk.d.ts"
26
+ },
27
+ "./auth/auth0": {
28
+ "import": "./lib/zudoku.auth-auth0.js",
29
+ "types": "./dist/lib/authentication/providers/auth0.d.ts"
30
+ },
31
+ "./auth/openid": {
32
+ "import": "./lib/zudoku.auth-openid.js",
33
+ "types": "./dist/lib/authentication/providers/openid.d.ts"
34
+ },
35
+ "./plugins/api-keys": {
36
+ "import": "./lib/zudoku.plugin-api-keys.js",
37
+ "types": "./dist/lib/plugins/api-keys/index.d.ts"
38
+ },
39
+ "./plugins/markdown": {
40
+ "import": "./lib/zudoku.plugin-markdown.js",
41
+ "types": "./dist/lib/plugins/markdown/index.d.ts"
42
+ },
43
+ "./plugins/openapi": {
44
+ "import": "./lib/zudoku.plugin-openapi.js",
45
+ "types": "./dist/lib/plugins/openapi/index.d.ts"
46
+ },
47
+ "./plugins/redirect": {
48
+ "import": "./lib/zudoku.plugin-redirect.js",
49
+ "types": "./dist/lib/plugins/redirect/index.d.ts"
50
+ },
51
+ "./plugins/custom-page": {
52
+ "import": "./lib/zudoku.plugin-custom-page.js",
53
+ "types": "./dist/lib/plugins/custom-page/index.d.ts"
54
+ },
55
+ "./plugins/search-inkeep": {
56
+ "import": "./lib/zudoku.plugin-search-inkeep.js",
57
+ "types": "./dist/lib/plugins/search-inkeep/index.d.ts"
58
+ },
59
+ "./openapi-worker": {
60
+ "import": "./lib/zudoku.openapi-worker.js",
61
+ "types": "./dist/lib/plugins/openapi-worker.d.ts"
62
+ },
63
+ "./components": {
64
+ "import": "./lib/zudoku.components.js",
65
+ "types": "./dist/lib/components/index.d.ts"
66
+ },
67
+ "./vite": {
68
+ "require": "./dist/vite/plugin.js",
69
+ "import": "./dist/vite/plugin.js"
70
+ },
71
+ "./tailwind": {
72
+ "require": "./dist/app/tailwind.js",
73
+ "import": "./dist/app/tailwind.js"
74
+ },
75
+ "./main.css": {
76
+ "require": "./src/app/main.css",
77
+ "import": "./src/app/main.css"
78
+ },
79
+ "./app/*": {
80
+ "import": "./src/app/*"
103
81
  }
104
82
  },
105
- "scripts": {
106
- "build": "tsc --project tsconfig.json",
107
- "build:vite": "vite build && pnpm run hack:fix-worker-paths lib",
108
- "build:standalone:vite": "vite build --mode standalone --config vite.standalone.config.ts",
109
- "build:standalone:html": "cp ./src/app/standalone.html ./standalone/standalone.html && cp ./src/app/demo.html ./standalone/demo.html && cp ./src/app/demo-cdn.html ./standalone/index.html",
110
- "hack:fix-worker-paths": "node ./scripts/hack-worker.mjs",
111
- "clean": "tsc --build --clean",
112
- "test": "node --test --enable-source-maps"
113
- },
114
83
  "dependencies": {
115
84
  "@envelop/core": "5.0.1",
116
85
  "@graphql-typed-document-node/core": "3.2.0",
@@ -147,7 +116,7 @@
147
116
  "openapi-types": "12.1.3",
148
117
  "picocolors": "^1.0.1",
149
118
  "postcss": "8.4.39",
150
- "posthog-node": "^4.0.1",
119
+ "posthog-node": "^4.1.1",
151
120
  "prism-react-renderer": "2.3.1",
152
121
  "prismjs": "1.29.0",
153
122
  "react": "18.3.1",
@@ -216,5 +185,16 @@
216
185
  "optionalDependencies": {
217
186
  "@clerk/clerk-js": "5.11.0",
218
187
  "@inkeep/widgets": "^0.2.289"
219
- }
220
- }
188
+ },
189
+ "scripts": {
190
+ "build": "tsc --project tsconfig.json",
191
+ "build:vite": "vite build && pnpm run hack:fix-worker-paths lib",
192
+ "build:standalone:vite": "vite build --mode standalone --config vite.standalone.config.ts",
193
+ "build:standalone:html": "cp ./src/app/standalone.html ./standalone/standalone.html && cp ./src/app/demo.html ./standalone/demo.html && cp ./src/app/demo-cdn.html ./standalone/index.html",
194
+ "hack:fix-worker-paths": "node ./scripts/hack-worker.mjs",
195
+ "clean": "tsc --build --clean",
196
+ "test": "node --test --enable-source-maps"
197
+ },
198
+ "module": "./dist/index.js",
199
+ "types": "./dist/index.d.ts"
200
+ }
package/src/app/main.css CHANGED
@@ -249,7 +249,7 @@
249
249
  --popover: 222.2 84% 4.9%;
250
250
  --popover-foreground: 210 40% 98%;
251
251
  --primary: 217.2 91.2% 59.8%;
252
- --primary-foreground: 222.2 47.4% 11.2%;
252
+ --primary-foreground: 210 40% 98%;
253
253
  --secondary: 217.2 32.6% 17.5%;
254
254
  --secondary-foreground: 210 40% 98%;
255
255
  --muted: 217.2 32.6% 17.5%;
@@ -5,6 +5,7 @@ export interface AuthenticationProvider {
5
5
  signIn(options?: { redirectTo?: string }): Promise<void>;
6
6
  signOut(): Promise<void>;
7
7
  getAccessToken(): Promise<string>;
8
+ pageLoad?(): void;
8
9
  getAuthenticationPlugin?(): DevPortalPlugin;
9
10
  }
10
11
 
@@ -0,0 +1,59 @@
1
+ import logger from "loglevel";
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { useNavigate } from "react-router-dom";
4
+ import { DeveloperHint } from "../../components/DeveloperHint.js";
5
+ import { ErrorPage } from "../../components/ErrorPage.js";
6
+ import { Spinner } from "../../components/Spinner.js";
7
+ import { SyntaxHighlight } from "../../components/SyntaxHighlight.js";
8
+
9
+ export function CallbackHandler({
10
+ handleCallback,
11
+ }: {
12
+ handleCallback: () => Promise<string>;
13
+ }) {
14
+ const [error, setError] = useState<Error | null>(null);
15
+ const navigate = useNavigate();
16
+ // Deal with double mount in dev mode which will break
17
+ // the OAuth flow because you can only use the code once
18
+ const didInitialize = useRef(false);
19
+
20
+ useEffect(() => {
21
+ if (didInitialize.current) {
22
+ return;
23
+ }
24
+ didInitialize.current = true;
25
+ handleCallback()
26
+ .then((redirect) => {
27
+ navigate(redirect);
28
+ })
29
+ .catch((err) => {
30
+ logger.error(err);
31
+ setError(err);
32
+ });
33
+ }, [navigate, handleCallback]);
34
+
35
+ if (error) {
36
+ return (
37
+ <ErrorPage
38
+ category="Error"
39
+ title="Authentication Error"
40
+ message={
41
+ <>
42
+ <DeveloperHint className="mb-4">
43
+ Check the configuration of your authorization provider and ensure
44
+ all settings such as the callback URL are configured correctly.
45
+ </DeveloperHint>
46
+ An error occurred while authorizing the user.
47
+ <SyntaxHighlight code={error.toString()} language="plain" />
48
+ </>
49
+ }
50
+ />
51
+ );
52
+ }
53
+
54
+ return (
55
+ <div className="grid h-full place-items-center">
56
+ <Spinner />
57
+ </div>
58
+ );
59
+ }
@@ -4,6 +4,16 @@ import { useAuthState } from "../state.js";
4
4
  import { OpenIDAuthenticationProvider } from "./openid.js";
5
5
 
6
6
  class Auth0AuthenticationProvider extends OpenIDAuthenticationProvider {
7
+ constructor(config: Auth0AuthenticationConfig) {
8
+ super({
9
+ ...config,
10
+ type: "openid",
11
+ issuer: `https://${config.domain}`,
12
+ clientId: config.clientId,
13
+ audience: config.audience,
14
+ });
15
+ }
16
+
7
17
  onAuthorizationUrl = async (
8
18
  url: URL,
9
19
  { isSignUp }: { isSignUp: boolean },
@@ -12,13 +22,14 @@ class Auth0AuthenticationProvider extends OpenIDAuthenticationProvider {
12
22
  url.searchParams.set("screen_hint", "signup");
13
23
  }
14
24
  };
25
+
15
26
  signOut = async (): Promise<void> => {
16
27
  useAuthState.setState({
17
28
  isAuthenticated: false,
18
29
  isPending: false,
19
30
  profile: undefined,
20
31
  });
21
- localStorage.removeItem("auto-login");
32
+ sessionStorage.clear();
22
33
  const as = await this.getAuthServer();
23
34
 
24
35
  const redirectUrl = new URL(
@@ -53,11 +64,6 @@ class Auth0AuthenticationProvider extends OpenIDAuthenticationProvider {
53
64
 
54
65
  const auth0Auth: AuthenticationProviderInitializer<
55
66
  Auth0AuthenticationConfig
56
- > = ({ domain, ...options }) =>
57
- new Auth0AuthenticationProvider({
58
- ...options,
59
- type: "openid",
60
- issuer: `https://${domain}`,
61
- });
67
+ > = (options) => new Auth0AuthenticationProvider(options);
62
68
 
63
69
  export default auth0Auth;
@@ -1,13 +1,12 @@
1
1
  import logger from "loglevel";
2
2
  import * as oauth from "oauth4webapi";
3
- import { NavigateFunction } from "react-router-dom";
4
3
  import { OpenIDAuthenticationConfig } from "../../../config/config.js";
5
- import { CommonPlugin } from "../../core/plugins.js";
6
4
  import {
7
5
  AuthenticationProvider,
8
6
  AuthenticationProviderInitializer,
9
7
  } from "../authentication.js";
10
8
  import { AuthenticationPlugin } from "../AuthenticationPlugin.js";
9
+ import { CallbackHandler } from "../components/CallbackHandler.js";
11
10
  import { AuthorizationError, OAuthAuthorizationError } from "../errors.js";
12
11
  import { useAuthState, UserProfile } from "../state.js";
13
12
 
@@ -23,7 +22,7 @@ interface TokenState {
23
22
  class OpenIdAuthPlugin extends AuthenticationPlugin {
24
23
  constructor(
25
24
  private callbackUrlPath: string,
26
- public initialize?: CommonPlugin["initialize"],
25
+ private handleCallback: () => Promise<string>,
27
26
  ) {
28
27
  super();
29
28
  }
@@ -32,7 +31,7 @@ class OpenIdAuthPlugin extends AuthenticationPlugin {
32
31
  ...super.getRoutes(),
33
32
  {
34
33
  path: this.callbackUrlPath,
35
- element: <div />,
34
+ element: <CallbackHandler handleCallback={this.handleCallback} />,
36
35
  },
37
36
  ];
38
37
  }
@@ -41,11 +40,8 @@ class OpenIdAuthPlugin extends AuthenticationPlugin {
41
40
  export class OpenIDAuthenticationProvider implements AuthenticationProvider {
42
41
  protected client: oauth.Client;
43
42
  protected issuer: string;
44
- protected authorizationEndpoint: string | undefined;
45
- protected tokenEndpoint: string | undefined;
46
43
 
47
44
  protected authorizationServer: oauth.AuthorizationServer | undefined;
48
- protected tokens: TokenState | undefined;
49
45
 
50
46
  protected callbackUrlPath = "/oauth/callback";
51
47
  protected logoutRedirectUrlPath = "/";
@@ -61,8 +57,6 @@ export class OpenIDAuthenticationProvider implements AuthenticationProvider {
61
57
  constructor({
62
58
  issuer,
63
59
  audience,
64
- authorizationEndpoint,
65
- tokenEndpoint,
66
60
  clientId,
67
61
  redirectToAfterSignUp,
68
62
  redirectToAfterSignIn,
@@ -74,8 +68,6 @@ export class OpenIDAuthenticationProvider implements AuthenticationProvider {
74
68
  };
75
69
  this.audience = audience;
76
70
  this.issuer = issuer;
77
- this.authorizationEndpoint = authorizationEndpoint;
78
- this.tokenEndpoint = tokenEndpoint;
79
71
  this.redirectToAfterSignUp = redirectToAfterSignUp ?? "/";
80
72
  this.redirectToAfterSignIn = redirectToAfterSignIn ?? "/";
81
73
  this.redirectToAfterSignOut = redirectToAfterSignOut ?? "/";
@@ -83,21 +75,12 @@ export class OpenIDAuthenticationProvider implements AuthenticationProvider {
83
75
 
84
76
  protected async getAuthServer() {
85
77
  if (!this.authorizationServer) {
86
- if (this.tokenEndpoint && this.authorizationEndpoint) {
87
- this.authorizationServer = {
88
- issuer: new URL(this.authorizationEndpoint!).origin,
89
- authorization_endpoint: this.authorizationEndpoint,
90
- token_endpoint: this.tokenEndpoint,
91
- code_challenge_methods_supported: [],
92
- };
93
- } else {
94
- const issuerUrl = new URL(this.issuer);
95
- const response = await oauth.discoveryRequest(issuerUrl);
96
- this.authorizationServer = await oauth.processDiscoveryResponse(
97
- issuerUrl,
98
- response,
99
- );
100
- }
78
+ const issuerUrl = new URL(this.issuer);
79
+ const response = await oauth.discoveryRequest(issuerUrl);
80
+ this.authorizationServer = await oauth.processDiscoveryResponse(
81
+ issuerUrl,
82
+ response,
83
+ );
101
84
  }
102
85
  return this.authorizationServer;
103
86
  }
@@ -118,13 +101,13 @@ export class OpenIDAuthenticationProvider implements AuthenticationProvider {
118
101
  throw new AuthorizationError("No expires_in in response");
119
102
  }
120
103
 
121
- this.tokens = {
104
+ const tokens: TokenState = {
122
105
  accessToken: response.access_token,
123
106
  refreshToken: response.refresh_token,
124
107
  expiresOn: new Date(Date.now() + response.expires_in * 1000),
125
108
  tokenType: response.token_type,
126
109
  };
127
- sessionStorage.setItem("openid-token", JSON.stringify(this.tokens));
110
+ sessionStorage.setItem("token-state", JSON.stringify(tokens));
128
111
  }
129
112
 
130
113
  async signUp({ redirectTo }: { redirectTo?: string } = {}) {
@@ -178,7 +161,7 @@ export class OpenIDAuthenticationProvider implements AuthenticationProvider {
178
161
  authorizationUrl.searchParams.set("client_id", this.client.client_id);
179
162
  authorizationUrl.searchParams.set("redirect_uri", redirectUrl.toString());
180
163
  authorizationUrl.searchParams.set("response_type", "code");
181
- authorizationUrl.searchParams.set("scope", "openid+profile+email");
164
+ authorizationUrl.searchParams.set("scope", "openid profile email");
182
165
  authorizationUrl.searchParams.set("code_challenge", codeChallenge);
183
166
  authorizationUrl.searchParams.set(
184
167
  "code_challenge_method",
@@ -211,11 +194,14 @@ export class OpenIDAuthenticationProvider implements AuthenticationProvider {
211
194
 
212
195
  async getAccessToken(): Promise<string> {
213
196
  const as = await this.getAuthServer();
214
- if (!this.tokens) {
197
+ const tokenState = sessionStorage.getItem("token-state");
198
+ if (!tokenState) {
215
199
  throw new AuthorizationError("User is not authenticated");
216
200
  }
217
- if (this.tokens.expiresOn < new Date()) {
218
- if (!this.tokens.refreshToken) {
201
+
202
+ const state = JSON.parse(tokenState) as TokenState;
203
+ if (state.expiresOn < new Date()) {
204
+ if (!state.refreshToken) {
219
205
  await this.signIn();
220
206
  return "";
221
207
  }
@@ -223,7 +209,7 @@ export class OpenIDAuthenticationProvider implements AuthenticationProvider {
223
209
  const request = await oauth.refreshTokenGrantRequest(
224
210
  as,
225
211
  this.client,
226
- this.tokens.refreshToken,
212
+ state.refreshToken,
227
213
  );
228
214
  const response = await oauth.processRefreshTokenResponse(
229
215
  as,
@@ -231,10 +217,16 @@ export class OpenIDAuthenticationProvider implements AuthenticationProvider {
231
217
  request,
232
218
  );
233
219
 
220
+ if (!response.access_token) {
221
+ throw new AuthorizationError("No access token in response");
222
+ }
223
+
234
224
  this.setTokensFromResponse(response);
235
- }
236
225
 
237
- return this.tokens.accessToken;
226
+ return response.access_token.toString();
227
+ } else {
228
+ return state.accessToken;
229
+ }
238
230
  }
239
231
 
240
232
  signOut = async () => {
@@ -243,7 +235,7 @@ export class OpenIDAuthenticationProvider implements AuthenticationProvider {
243
235
  isPending: false,
244
236
  profile: undefined,
245
237
  });
246
- localStorage.removeItem("auto-login");
238
+ sessionStorage.clear();
247
239
 
248
240
  const as = await this.getAuthServer();
249
241
 
@@ -279,9 +271,8 @@ export class OpenIDAuthenticationProvider implements AuthenticationProvider {
279
271
  // Authorization Code Grant Request & Response
280
272
  const codeVerifier = sessionStorage.getItem(CODE_VERIFIER_KEY);
281
273
  sessionStorage.removeItem(CODE_VERIFIER_KEY);
282
-
283
274
  if (!codeVerifier) {
284
- return "/";
275
+ throw new AuthorizationError("No code verifier found in state.");
285
276
  }
286
277
 
287
278
  const authServer = await this.getAuthServer();
@@ -320,7 +311,7 @@ export class OpenIDAuthenticationProvider implements AuthenticationProvider {
320
311
  // }
321
312
  // throw new Error(); // Handle WWW-Authenticate Challenges as needed
322
313
  // }
323
- const oauthResult = await oauth.processAuthorizationCodeOAuth2Response(
314
+ const oauthResult = await oauth.processAuthorizationCodeOpenIDResponse(
324
315
  authServer,
325
316
  this.client,
326
317
  response,
@@ -351,29 +342,36 @@ export class OpenIDAuthenticationProvider implements AuthenticationProvider {
351
342
  profile,
352
343
  });
353
344
 
354
- localStorage.setItem("auto-login", "1");
345
+ sessionStorage.setItem(
346
+ "profile-state",
347
+ JSON.stringify(useAuthState.getState().profile),
348
+ );
355
349
 
356
- return sessionStorage.getItem("redirect-to") ?? "/";
350
+ const redirectTo = sessionStorage.getItem("redirect-to") ?? "/";
351
+ sessionStorage.removeItem("redirect-to");
352
+ return redirectTo;
357
353
  };
358
354
 
355
+ pageLoad(): void {
356
+ const profileState = sessionStorage.getItem("profile-state");
357
+ if (profileState) {
358
+ try {
359
+ const profile = JSON.parse(profileState);
360
+ useAuthState.setState({
361
+ isAuthenticated: true,
362
+ isPending: false,
363
+ profile,
364
+ });
365
+ } catch (err) {
366
+ logger.error("Error parsing auth state", err);
367
+ }
368
+ }
369
+ }
370
+
359
371
  getAuthenticationPlugin() {
360
- return new OpenIdAuthPlugin(
361
- this.callbackUrlPath,
362
- async (_, options: { navigate: NavigateFunction }) => {
363
- if (typeof window === "undefined") return;
364
-
365
- if (localStorage.getItem("auto-login")) {
366
- localStorage.removeItem("auto-login");
367
-
368
- await this.authorize({ redirectTo: window.location.pathname });
369
- } else if (window.location.pathname === "/oauth/callback") {
370
- const redirect = await this.handleCallback();
371
- if (redirect) {
372
- options.navigate(redirect);
373
- }
374
- }
375
- },
376
- );
372
+ // TODO: This API is a bit messy, we need to refactor auth plugins/providers
373
+ // to remove the extra layers of abstraction.
374
+ return new OpenIdAuthPlugin(this.callbackUrlPath, this.handleCallback);
377
375
  }
378
376
  }
379
377