zudoku 0.3.0-dev.81 → 0.3.0-dev.83
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/lib/plugins/api-keys/SettingsApiKeys.js +16 -2
- package/dist/lib/plugins/api-keys/SettingsApiKeys.js.map +1 -1
- package/dist/lib/plugins/api-keys/index.js +6 -0
- package/dist/lib/plugins/api-keys/index.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/Playground.js +1 -1
- package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
- package/lib/{OperationList-Bl6rGF6_.js → OperationList-CHK_erYP.js} +2 -2
- package/lib/{OperationList-Bl6rGF6_.js.map → OperationList-CHK_erYP.js.map} +1 -1
- package/lib/{Route-BEvxtkD4.js → Route-D70pGn9n.js} +2 -2
- package/lib/{Route-BEvxtkD4.js.map → Route-D70pGn9n.js.map} +1 -1
- package/lib/{index-BlnQp2oR.js → index-Bl6YeerK.js} +4 -4
- package/lib/index-Bl6YeerK.js.map +1 -0
- package/lib/zudoku.plugin-api-keys.js +127 -105
- package/lib/zudoku.plugin-api-keys.js.map +1 -1
- package/lib/zudoku.plugin-openapi.js +1 -1
- package/package.json +1 -1
- package/src/lib/plugins/api-keys/SettingsApiKeys.tsx +31 -10
- package/src/lib/plugins/api-keys/index.tsx +10 -0
- package/src/lib/plugins/openapi/playground/Playground.tsx +1 -1
- package/lib/index-BlnQp2oR.js.map +0 -1
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { a as f, j as e, O as
|
|
2
|
-
import { a as
|
|
3
|
-
import { u as v, a as
|
|
4
|
-
import { L as
|
|
5
|
-
import { u as
|
|
6
|
-
import { B as
|
|
1
|
+
import { a as f, j as e, O as g } from "./jsx-runtime-CJBdjYYx.js";
|
|
2
|
+
import { a as p, R as j } from "./SlotletProvider-B71hNEUL.js";
|
|
3
|
+
import { u as v, a as u, I as k, S as w, b, c as K, d as N, e as E, f as y } from "./Input-3IEt27jb.js";
|
|
4
|
+
import { L as x } from "./index-Dt-pU7Vu.js";
|
|
5
|
+
import { u as h, x as A, y as S } from "./DevPortalProvider-BWeAysxF.js";
|
|
6
|
+
import { B as l, p as I } from "./Combination-C442XfGG.js";
|
|
7
7
|
import { D as P } from "./DeveloperHint-DQVwIery.js";
|
|
8
|
-
import { useState as
|
|
9
|
-
import { c as
|
|
8
|
+
import { useState as D } from "react";
|
|
9
|
+
import { c as d, a as C } from "./Markdown-QsZ-PHET.js";
|
|
10
10
|
/**
|
|
11
11
|
* @license lucide-react v0.378.0 - ISC
|
|
12
12
|
*
|
|
13
13
|
* This source code is licensed under the ISC license.
|
|
14
14
|
* See the LICENSE file in the root directory of this source tree.
|
|
15
15
|
*/
|
|
16
|
-
const
|
|
16
|
+
const R = d("EyeOff", [
|
|
17
17
|
["path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24", key: "1jxqfv" }],
|
|
18
18
|
[
|
|
19
19
|
"path",
|
|
@@ -34,7 +34,7 @@ const O = l("EyeOff", [
|
|
|
34
34
|
* This source code is licensed under the ISC license.
|
|
35
35
|
* See the LICENSE file in the root directory of this source tree.
|
|
36
36
|
*/
|
|
37
|
-
const
|
|
37
|
+
const q = d("Eye", [
|
|
38
38
|
["path", { d: "M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z", key: "rwhkz3" }],
|
|
39
39
|
["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }]
|
|
40
40
|
]);
|
|
@@ -44,7 +44,7 @@ const R = l("Eye", [
|
|
|
44
44
|
* This source code is licensed under the ISC license.
|
|
45
45
|
* See the LICENSE file in the root directory of this source tree.
|
|
46
46
|
*/
|
|
47
|
-
const
|
|
47
|
+
const O = d("RotateCw", [
|
|
48
48
|
["path", { d: "M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8", key: "1p45f6" }],
|
|
49
49
|
["path", { d: "M21 3v5h-5", key: "1q7to0" }]
|
|
50
50
|
]);
|
|
@@ -54,35 +54,35 @@ const q = l("RotateCw", [
|
|
|
54
54
|
* This source code is licensed under the ISC license.
|
|
55
55
|
* See the LICENSE file in the root directory of this source tree.
|
|
56
56
|
*/
|
|
57
|
-
const
|
|
57
|
+
const M = d("Trash", [
|
|
58
58
|
["path", { d: "M3 6h18", key: "d0wm0j" }],
|
|
59
59
|
["path", { d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6", key: "4alrt4" }],
|
|
60
60
|
["path", { d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2", key: "v07s0e" }]
|
|
61
61
|
]);
|
|
62
|
-
function
|
|
62
|
+
function c(t, s) {
|
|
63
63
|
if (t)
|
|
64
64
|
return;
|
|
65
|
-
const r = typeof
|
|
66
|
-
throw new
|
|
65
|
+
const r = typeof s == "function" ? s() : s;
|
|
66
|
+
throw new z(r ?? "Invariant failed");
|
|
67
67
|
}
|
|
68
|
-
class
|
|
69
|
-
constructor(
|
|
70
|
-
super(
|
|
68
|
+
class z extends Error {
|
|
69
|
+
constructor(s) {
|
|
70
|
+
super(s), this.name = "ZudokuError";
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
-
const
|
|
74
|
-
const
|
|
73
|
+
const F = ({ service: t }) => {
|
|
74
|
+
const s = h(), r = f(), n = v({
|
|
75
75
|
defaultValues: {
|
|
76
76
|
expiresOn: "30"
|
|
77
77
|
}
|
|
78
|
-
}),
|
|
79
|
-
mutationFn: ({ description:
|
|
78
|
+
}), o = u({
|
|
79
|
+
mutationFn: ({ description: i, expiresOn: a }) => {
|
|
80
80
|
if (!t.createKey)
|
|
81
81
|
throw new Error("deleteKey not implemented");
|
|
82
|
-
const
|
|
82
|
+
const m = a !== "never" ? L(Number(a)) : void 0;
|
|
83
83
|
return t.createKey(
|
|
84
|
-
{ description:
|
|
85
|
-
|
|
84
|
+
{ description: i, expiresOn: m },
|
|
85
|
+
s
|
|
86
86
|
);
|
|
87
87
|
},
|
|
88
88
|
onSuccess: () => r("/settings/api-keys/")
|
|
@@ -92,175 +92,197 @@ const L = ({ service: t }) => {
|
|
|
92
92
|
/* @__PURE__ */ e.jsx(
|
|
93
93
|
"form",
|
|
94
94
|
{
|
|
95
|
-
onSubmit:
|
|
95
|
+
onSubmit: n.handleSubmit((i) => o.mutate(i)),
|
|
96
96
|
children: /* @__PURE__ */ e.jsxs("div", { className: "flex gap-2 flex-col", children: [
|
|
97
97
|
"Note",
|
|
98
|
-
/* @__PURE__ */ e.jsx(
|
|
98
|
+
/* @__PURE__ */ e.jsx(k, { ...n.register("description") }),
|
|
99
99
|
"Expiration",
|
|
100
100
|
/* @__PURE__ */ e.jsxs(
|
|
101
|
-
|
|
101
|
+
w,
|
|
102
102
|
{
|
|
103
|
-
onValueChange: (
|
|
104
|
-
defaultValue:
|
|
103
|
+
onValueChange: (i) => n.setValue("expiresOn", i),
|
|
104
|
+
defaultValue: n.getValues("expiresOn"),
|
|
105
105
|
children: [
|
|
106
106
|
/* @__PURE__ */ e.jsx(b, { children: /* @__PURE__ */ e.jsx(K, {}) }),
|
|
107
|
-
/* @__PURE__ */ e.jsx(N, { children: /* @__PURE__ */ e.jsxs(
|
|
108
|
-
[7, 30, 60, 90].map((
|
|
109
|
-
|
|
107
|
+
/* @__PURE__ */ e.jsx(N, { children: /* @__PURE__ */ e.jsxs(E, { children: [
|
|
108
|
+
[7, 30, 60, 90].map((i) => /* @__PURE__ */ e.jsxs(y, { value: String(i), children: [
|
|
109
|
+
i,
|
|
110
110
|
" days"
|
|
111
|
-
] },
|
|
112
|
-
/* @__PURE__ */ e.jsx(
|
|
111
|
+
] }, i)),
|
|
112
|
+
/* @__PURE__ */ e.jsx(y, { value: "never", children: "Never" })
|
|
113
113
|
] }) })
|
|
114
114
|
]
|
|
115
115
|
}
|
|
116
116
|
),
|
|
117
117
|
/* @__PURE__ */ e.jsxs("div", { className: "flex gap-2", children: [
|
|
118
|
-
/* @__PURE__ */ e.jsx(
|
|
119
|
-
/* @__PURE__ */ e.jsx(
|
|
118
|
+
/* @__PURE__ */ e.jsx(l, { children: "Generate Key" }),
|
|
119
|
+
/* @__PURE__ */ e.jsx(l, { variant: "outline", asChild: !0, children: /* @__PURE__ */ e.jsx(x, { to: "/settings/api-keys/", children: "Cancel" }) })
|
|
120
120
|
] })
|
|
121
121
|
] })
|
|
122
122
|
}
|
|
123
123
|
)
|
|
124
124
|
] }) : null;
|
|
125
|
-
},
|
|
126
|
-
const
|
|
127
|
-
return
|
|
128
|
-
},
|
|
125
|
+
}, L = (t) => {
|
|
126
|
+
const s = /* @__PURE__ */ new Date();
|
|
127
|
+
return s.setDate(s.getDate() + t), s.toISOString();
|
|
128
|
+
}, T = () => {
|
|
129
129
|
const t = I();
|
|
130
|
-
return t.isAuthEnabled && t.isPending ? null : t.isAuthenticated ? /* @__PURE__ */ e.jsx(
|
|
130
|
+
return t.isAuthEnabled && t.isPending ? null : t.isAuthenticated ? /* @__PURE__ */ e.jsx(g, {}) : t.isAuthEnabled ? /* @__PURE__ */ e.jsxs("div", { className: "flex flex-col justify-center gap-2 items-center h-1/2", children: [
|
|
131
131
|
"Please login first to view this page",
|
|
132
|
-
/* @__PURE__ */ e.jsx(
|
|
132
|
+
/* @__PURE__ */ e.jsx(l, { onClick: () => t.login(), children: "Login" })
|
|
133
133
|
] }) : /* @__PURE__ */ e.jsx("div", { className: "flex flex-col justify-center gap-2 items-center h-1/2", children: /* @__PURE__ */ e.jsxs(P, { className: "max-w-[600px]", children: [
|
|
134
134
|
"Authentication needs to be enabled for API keys to work. Enable it in your Zudoku configuration under ",
|
|
135
135
|
/* @__PURE__ */ e.jsx("code", { children: "authentication" }),
|
|
136
136
|
"."
|
|
137
137
|
] }) });
|
|
138
138
|
}, V = ({ service: t }) => {
|
|
139
|
-
const
|
|
140
|
-
queryFn: () => t.getKeys(
|
|
139
|
+
const s = h(), r = A(), { data: n } = S({
|
|
140
|
+
queryFn: () => t.getKeys(s),
|
|
141
141
|
queryKey: ["api-keys"],
|
|
142
142
|
retry: !1
|
|
143
|
-
}),
|
|
144
|
-
mutationFn: (
|
|
143
|
+
}), o = u({
|
|
144
|
+
mutationFn: (a) => {
|
|
145
145
|
if (!t.deleteKey)
|
|
146
146
|
throw new Error("deleteKey not implemented");
|
|
147
|
-
return t.deleteKey(
|
|
147
|
+
return t.deleteKey(a, s);
|
|
148
148
|
},
|
|
149
149
|
onSuccess: () => {
|
|
150
150
|
r.invalidateQueries({ queryKey: ["api-keys"] });
|
|
151
151
|
}
|
|
152
|
+
}), i = u({
|
|
153
|
+
mutationFn: (a) => {
|
|
154
|
+
if (!t.rollKey)
|
|
155
|
+
throw new Error("rollKey not implemented");
|
|
156
|
+
return t.rollKey(a, s);
|
|
157
|
+
},
|
|
158
|
+
onSuccess: () => r.invalidateQueries({ queryKey: ["api-keys"] })
|
|
152
159
|
});
|
|
153
160
|
return /* @__PURE__ */ e.jsxs("div", { className: "max-w-screen-lg h-full pt-[--padding-content-top] pb-[--padding-content-bottom]", children: [
|
|
154
|
-
/* @__PURE__ */ e.jsx(
|
|
161
|
+
/* @__PURE__ */ e.jsx(p, { name: "api-keys-list-page" }),
|
|
155
162
|
/* @__PURE__ */ e.jsxs("div", { className: "flex justify-between mb-4 border-b pb-3", children: [
|
|
156
163
|
/* @__PURE__ */ e.jsx("h1", { className: "font-medium text-2xl", children: "API Keys" }),
|
|
157
|
-
t.createKey && /* @__PURE__ */ e.jsx(
|
|
164
|
+
t.createKey && /* @__PURE__ */ e.jsx(l, { asChild: !0, children: /* @__PURE__ */ e.jsx(x, { to: "/settings/api-keys/new", children: "Create API Key" }) })
|
|
158
165
|
] }),
|
|
159
|
-
/* @__PURE__ */ e.jsx(
|
|
160
|
-
|
|
161
|
-
/* @__PURE__ */ e.jsxs("
|
|
166
|
+
/* @__PURE__ */ e.jsx(p, { name: "api-keys-list-page-before-keys" }),
|
|
167
|
+
n.length === 0 ? /* @__PURE__ */ e.jsxs("div", { className: "flex flex-col justify-center gap-4 items-center p-8 border rounded bg-muted/30 text-muted-foreground", children: [
|
|
168
|
+
/* @__PURE__ */ e.jsxs("p", { className: "text-center", children: [
|
|
162
169
|
"No API keys created yet.",
|
|
163
170
|
/* @__PURE__ */ e.jsx("br", {}),
|
|
164
|
-
"Get started and create
|
|
171
|
+
"Get started and create your first key."
|
|
165
172
|
] }),
|
|
166
|
-
t.createKey && /* @__PURE__ */ e.jsx(
|
|
173
|
+
t.createKey && /* @__PURE__ */ e.jsx(l, { asChild: !0, variant: "outline", children: /* @__PURE__ */ e.jsx(x, { to: "/settings/api-keys/new", children: "Create API Key" }) })
|
|
167
174
|
] }) : /* @__PURE__ */ e.jsx(
|
|
168
175
|
"ul",
|
|
169
176
|
{
|
|
170
|
-
className:
|
|
177
|
+
className: C(
|
|
171
178
|
"grid grid-cols-1 rounded border",
|
|
172
179
|
"lg:grid-cols-[minmax(250px,min-content)_1fr_min-content]"
|
|
173
180
|
),
|
|
174
|
-
children:
|
|
181
|
+
children: n.map((a) => /* @__PURE__ */ e.jsxs(
|
|
175
182
|
"li",
|
|
176
183
|
{
|
|
177
184
|
className: "border-b p-5 grid grid-cols-subgrid col-span-full gap-2 items-center",
|
|
178
185
|
children: [
|
|
179
186
|
/* @__PURE__ */ e.jsxs("div", { className: "flex flex-col gap-1 text-sm", children: [
|
|
180
|
-
|
|
187
|
+
a.description ?? a.id,
|
|
181
188
|
/* @__PURE__ */ e.jsxs("div", { className: "text-muted-foreground text-xs", children: [
|
|
182
|
-
|
|
189
|
+
a.createdOn && /* @__PURE__ */ e.jsxs("div", { children: [
|
|
183
190
|
"Created on ",
|
|
184
|
-
new Date(
|
|
191
|
+
new Date(a.createdOn).toLocaleDateString()
|
|
185
192
|
] }),
|
|
186
|
-
|
|
193
|
+
a.expiresOn && /* @__PURE__ */ e.jsxs("div", { children: [
|
|
187
194
|
"Expires on ",
|
|
188
|
-
new Date(
|
|
195
|
+
new Date(a.expiresOn).toLocaleDateString()
|
|
189
196
|
] })
|
|
190
197
|
] })
|
|
191
198
|
] }),
|
|
192
|
-
/* @__PURE__ */ e.jsx("div", { className: "items-center flex lg:justify-center", children: /* @__PURE__ */ e.jsx(_, { apiKey:
|
|
199
|
+
/* @__PURE__ */ e.jsx("div", { className: "items-center flex lg:justify-center", children: /* @__PURE__ */ e.jsx(_, { apiKey: a.key }) }),
|
|
193
200
|
/* @__PURE__ */ e.jsxs("div", { className: "flex gap-2", children: [
|
|
194
|
-
t.rollKey && /* @__PURE__ */ e.jsx(
|
|
201
|
+
t.rollKey && /* @__PURE__ */ e.jsx(
|
|
202
|
+
l,
|
|
203
|
+
{
|
|
204
|
+
size: "icon",
|
|
205
|
+
title: "Roll this key",
|
|
206
|
+
variant: "ghost",
|
|
207
|
+
onClick: () => {
|
|
208
|
+
confirm("Do you want to roll this key?") && i.mutate(a.id);
|
|
209
|
+
},
|
|
210
|
+
children: /* @__PURE__ */ e.jsx(O, { size: 16 })
|
|
211
|
+
}
|
|
212
|
+
),
|
|
195
213
|
t.deleteKey && /* @__PURE__ */ e.jsx(
|
|
196
|
-
|
|
214
|
+
l,
|
|
197
215
|
{
|
|
198
216
|
variant: "ghost",
|
|
199
217
|
size: "icon",
|
|
200
218
|
onClick: () => {
|
|
201
|
-
confirm("Do you want to delete this key?") &&
|
|
219
|
+
confirm("Do you want to delete this key?") && o.mutate(a.id);
|
|
202
220
|
},
|
|
203
|
-
disabled:
|
|
204
|
-
children: /* @__PURE__ */ e.jsx(
|
|
221
|
+
disabled: o.isPending,
|
|
222
|
+
children: /* @__PURE__ */ e.jsx(M, { size: 16 })
|
|
205
223
|
}
|
|
206
224
|
)
|
|
207
225
|
] })
|
|
208
226
|
]
|
|
209
227
|
},
|
|
210
|
-
|
|
228
|
+
a.id
|
|
211
229
|
))
|
|
212
230
|
}
|
|
213
231
|
)
|
|
214
232
|
] });
|
|
215
233
|
}, _ = ({ apiKey: t }) => {
|
|
216
|
-
const [
|
|
234
|
+
const [s, r] = D(!1);
|
|
217
235
|
return /* @__PURE__ */ e.jsxs("div", { className: "flex gap-2 items-center text-sm w-full", children: [
|
|
236
|
+
/* @__PURE__ */ e.jsx("div", { className: "border rounded bg-gray-100 dark:bg-gray-950 p-1 font-mono w-fit overflow-x-scroll h-9 items-center flex px-2", children: s ? t : "•".repeat(t.length) }),
|
|
218
237
|
/* @__PURE__ */ e.jsx(
|
|
219
|
-
|
|
220
|
-
{
|
|
221
|
-
className: "border rounded bg-gray-100 dark:bg-gray-950 p-1 font-mono max-w-min",
|
|
222
|
-
value: n ? t : "•".repeat(t.length)
|
|
223
|
-
}
|
|
224
|
-
),
|
|
225
|
-
/* @__PURE__ */ e.jsx(
|
|
226
|
-
o,
|
|
238
|
+
l,
|
|
227
239
|
{
|
|
228
240
|
variant: "outline",
|
|
229
|
-
onClick: () => r((
|
|
241
|
+
onClick: () => r((n) => !n),
|
|
230
242
|
size: "icon",
|
|
231
|
-
children:
|
|
243
|
+
children: s ? /* @__PURE__ */ e.jsx(R, { size: 16 }) : /* @__PURE__ */ e.jsx(q, { size: 16 })
|
|
232
244
|
}
|
|
233
245
|
)
|
|
234
246
|
] });
|
|
235
|
-
},
|
|
236
|
-
deleteKey: async (
|
|
237
|
-
const
|
|
247
|
+
}, Q = "https://zudoku-rewiringamerica-main-ef9c9c0.d2.zuplo.dev", Z = (t) => ({
|
|
248
|
+
deleteKey: async (s, r) => {
|
|
249
|
+
const n = new Request(t + `/v1/developer/api-keys/${s}`, {
|
|
238
250
|
method: "DELETE"
|
|
239
251
|
});
|
|
240
|
-
await r.signRequest(
|
|
241
|
-
const
|
|
242
|
-
|
|
252
|
+
await r.signRequest(n);
|
|
253
|
+
const o = await fetch(n);
|
|
254
|
+
c(o.ok, "Failed to delete API key");
|
|
255
|
+
},
|
|
256
|
+
rollKey: async (s, r) => {
|
|
257
|
+
const n = await fetch(
|
|
258
|
+
await r.signRequest(
|
|
259
|
+
new Request(t + `/v1/developer/api-keys/${s}/key`, {
|
|
260
|
+
method: "DELETE"
|
|
261
|
+
})
|
|
262
|
+
)
|
|
263
|
+
);
|
|
264
|
+
c(n.ok, "Failed to delete API key");
|
|
243
265
|
},
|
|
244
|
-
createKey: async (
|
|
245
|
-
const
|
|
266
|
+
createKey: async (s, r) => {
|
|
267
|
+
const n = new Request(t + "/v1/developer/api-keys", {
|
|
246
268
|
method: "POST",
|
|
247
269
|
headers: {
|
|
248
270
|
"Content-Type": "application/json"
|
|
249
271
|
},
|
|
250
|
-
body: JSON.stringify(
|
|
272
|
+
body: JSON.stringify(s)
|
|
251
273
|
});
|
|
252
|
-
await r.signRequest(
|
|
253
|
-
const
|
|
254
|
-
|
|
274
|
+
await r.signRequest(n);
|
|
275
|
+
const o = await fetch(n);
|
|
276
|
+
c(o.ok, "Failed to create API key");
|
|
255
277
|
},
|
|
256
|
-
getKeys: async (
|
|
278
|
+
getKeys: async (s) => {
|
|
257
279
|
const r = new Request(t + "/v1/developer/api-keys");
|
|
258
|
-
await
|
|
259
|
-
const
|
|
260
|
-
return
|
|
280
|
+
await s.signRequest(r);
|
|
281
|
+
const n = await fetch(r);
|
|
282
|
+
return c(n.ok, "Failed to fetch API keys"), await n.json();
|
|
261
283
|
}
|
|
262
284
|
}), ee = (t) => {
|
|
263
|
-
const
|
|
285
|
+
const s = "endpoint" in t ? t.endpoint : Q, r = "getKeys" in t ? t : Z(s);
|
|
264
286
|
return {
|
|
265
287
|
getProfileMenuItems: () => [
|
|
266
288
|
{
|
|
@@ -268,12 +290,12 @@ const L = ({ service: t }) => {
|
|
|
268
290
|
path: "/settings/api-keys"
|
|
269
291
|
}
|
|
270
292
|
],
|
|
271
|
-
getIdentities: async (
|
|
293
|
+
getIdentities: async (n) => {
|
|
272
294
|
try {
|
|
273
|
-
return (await r.getKeys(
|
|
274
|
-
authorizeRequest: (
|
|
275
|
-
id:
|
|
276
|
-
label:
|
|
295
|
+
return (await r.getKeys(n)).map((i) => ({
|
|
296
|
+
authorizeRequest: (a) => (a.headers.set("Authorization", `Bearer ${i.key}`), a),
|
|
297
|
+
id: i.id,
|
|
298
|
+
label: i.description ?? i.id
|
|
277
299
|
}));
|
|
278
300
|
} catch {
|
|
279
301
|
return [];
|
|
@@ -281,8 +303,8 @@ const L = ({ service: t }) => {
|
|
|
281
303
|
},
|
|
282
304
|
getRoutes: () => [
|
|
283
305
|
{
|
|
284
|
-
element: /* @__PURE__ */ e.jsx(
|
|
285
|
-
errorElement: /* @__PURE__ */ e.jsx(
|
|
306
|
+
element: /* @__PURE__ */ e.jsx(T, {}),
|
|
307
|
+
errorElement: /* @__PURE__ */ e.jsx(j, {}),
|
|
286
308
|
children: [
|
|
287
309
|
{
|
|
288
310
|
path: "/settings/api-keys",
|
|
@@ -290,7 +312,7 @@ const L = ({ service: t }) => {
|
|
|
290
312
|
},
|
|
291
313
|
{
|
|
292
314
|
path: "/settings/api-keys/new",
|
|
293
|
-
element: /* @__PURE__ */ e.jsx(
|
|
315
|
+
element: /* @__PURE__ */ e.jsx(F, { service: r })
|
|
294
316
|
}
|
|
295
317
|
]
|
|
296
318
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zudoku.plugin-api-keys.js","sources":["../../../node_modules/.pnpm/lucide-react@0.378.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/eye-off.js","../../../node_modules/.pnpm/lucide-react@0.378.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/eye.js","../../../node_modules/.pnpm/lucide-react@0.378.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/rotate-cw.js","../../../node_modules/.pnpm/lucide-react@0.378.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/trash.js","../src/lib/util/invariant.ts","../src/lib/plugins/api-keys/CreateApiKey.tsx","../src/lib/plugins/api-keys/ProtectedRoute.tsx","../src/lib/plugins/api-keys/SettingsApiKeys.tsx","../src/lib/plugins/api-keys/index.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.378.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst EyeOff = createLucideIcon(\"EyeOff\", [\n [\"path\", { d: \"M9.88 9.88a3 3 0 1 0 4.24 4.24\", key: \"1jxqfv\" }],\n [\n \"path\",\n {\n d: \"M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68\",\n key: \"9wicm4\"\n }\n ],\n [\n \"path\",\n { d: \"M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61\", key: \"1jreej\" }\n ],\n [\"line\", { x1: \"2\", x2: \"22\", y1: \"2\", y2: \"22\", key: \"a6p6uj\" }]\n]);\n\nexport { EyeOff as default };\n//# sourceMappingURL=eye-off.js.map\n","/**\n * @license lucide-react v0.378.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Eye = createLucideIcon(\"Eye\", [\n [\"path\", { d: \"M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z\", key: \"rwhkz3\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }]\n]);\n\nexport { Eye as default };\n//# sourceMappingURL=eye.js.map\n","/**\n * @license lucide-react v0.378.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst RotateCw = createLucideIcon(\"RotateCw\", [\n [\"path\", { d: \"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8\", key: \"1p45f6\" }],\n [\"path\", { d: \"M21 3v5h-5\", key: \"1q7to0\" }]\n]);\n\nexport { RotateCw as default };\n//# sourceMappingURL=rotate-cw.js.map\n","/**\n * @license lucide-react v0.378.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Trash = createLucideIcon(\"Trash\", [\n [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n [\"path\", { d: \"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\", key: \"4alrt4\" }],\n [\"path\", { d: \"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\", key: \"v07s0e\" }]\n]);\n\nexport { Trash as default };\n//# sourceMappingURL=trash.js.map\n","export default function invariant(\n condition: any,\n // Not providing an inline default argument for message as the result is smaller\n /**\n * Can provide a string, or a function that returns a string for cases where\n * the message takes a fair amount of effort to compute\n */\n message?: string | (() => string),\n): asserts condition {\n if (condition) {\n return;\n }\n // Condition not passed\n\n const provided: string | undefined =\n typeof message === \"function\" ? message() : message;\n\n throw new ZudokuError(provided ?? \"Invariant failed\");\n}\n\nclass ZudokuError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ZudokuError\";\n }\n}\n","import { useMutation } from \"@tanstack/react-query\";\nimport { useForm } from \"react-hook-form\";\nimport { Link, useNavigate } from \"react-router-dom\";\nimport { useDevPortal } from \"../../components/context/DevPortalProvider.js\";\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../components/Select.js\";\nimport { Button } from \"../../ui/Button.js\";\nimport { Input } from \"../../ui/Input.js\";\nimport { ApiKeyService } from \"./index.js\";\n\ntype CreateApiKey = { description: string; expiresOn?: string };\n\nexport const CreateApiKey = ({ service }: { service: ApiKeyService }) => {\n const context = useDevPortal();\n const navigate = useNavigate();\n const form = useForm<CreateApiKey>({\n defaultValues: {\n expiresOn: \"30\",\n },\n });\n const createKeyMutation = useMutation({\n mutationFn: ({ description, expiresOn }: CreateApiKey) => {\n if (!service.createKey) {\n throw new Error(\"deleteKey not implemented\");\n }\n\n const expiresOnDate =\n expiresOn !== \"never\" ? addDaysToDate(Number(expiresOn)) : undefined;\n\n return service.createKey(\n { description: description, expiresOn: expiresOnDate },\n context,\n );\n },\n onSuccess: () => navigate(\"/settings/api-keys/\"),\n });\n\n if (!service.createKey) {\n return null;\n }\n\n return (\n <div className=\"max-w-screen-lg pt-[--padding-content-top] pb-[--padding-content-bottom]\">\n <div className=\"flex justify-between mb-4 border-b pb-1\">\n <h1 className=\"font-medium text-2xl\">New API Key</h1>\n </div>\n <form\n onSubmit={form.handleSubmit((data) => createKeyMutation.mutate(data))}\n >\n <div className=\"flex gap-2 flex-col\">\n Note\n <Input {...form.register(\"description\")} />\n Expiration\n <Select\n onValueChange={(value) => form.setValue(\"expiresOn\", value)}\n defaultValue={form.getValues(\"expiresOn\")}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectGroup>\n {[7, 30, 60, 90].map((option) => (\n <SelectItem value={String(option)} key={option}>\n {option} days\n </SelectItem>\n ))}\n <SelectItem value=\"never\">Never</SelectItem>\n </SelectGroup>\n </SelectContent>\n </Select>\n <div className=\"flex gap-2\">\n <Button>Generate Key</Button>\n <Button variant=\"outline\" asChild>\n <Link to=\"/settings/api-keys/\">Cancel</Link>\n </Button>\n </div>\n </div>\n </form>\n </div>\n );\n};\n\nconst addDaysToDate = (days: number): string => {\n const date = new Date();\n date.setDate(date.getDate() + days);\n return date.toISOString();\n};\n","import { Outlet } from \"react-router-dom\";\nimport { useAuth } from \"../../authentication/hook.js\";\nimport { DeveloperHint } from \"../../components/DeveloperHint.js\";\nimport { Button } from \"../../ui/Button.js\";\n\nexport const ProtectedRoute = () => {\n const auth = useAuth();\n\n // TODO: should we suspend here somehow?\n if (auth.isAuthEnabled && auth.isPending) {\n return null;\n }\n\n return auth.isAuthenticated ? (\n <Outlet />\n ) : !auth.isAuthEnabled ? (\n <div className=\"flex flex-col justify-center gap-2 items-center h-1/2\">\n <DeveloperHint className=\"max-w-[600px]\">\n Authentication needs to be enabled for API keys to work. Enable it in\n your Zudoku configuration under <code>authentication</code>.\n </DeveloperHint>\n </div>\n ) : (\n <div className=\"flex flex-col justify-center gap-2 items-center h-1/2\">\n Please login first to view this page\n <Button onClick={() => auth.login()}>Login</Button>\n </div>\n );\n};\n","import {\n useMutation,\n useQueryClient,\n useSuspenseQuery,\n} from \"@tanstack/react-query\";\nimport { EyeIcon, EyeOffIcon, RotateCwIcon, TrashIcon } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport { useDevPortal } from \"../../components/context/DevPortalProvider.js\";\nimport { Slotlet } from \"../../components/SlotletProvider.js\";\nimport { Button } from \"../../ui/Button.js\";\nimport { cn } from \"../../util/cn.js\";\nimport { ApiKeyService } from \"./index.js\";\n\nexport const SettingsApiKeys = ({ service }: { service: ApiKeyService }) => {\n const context = useDevPortal();\n const queryClient = useQueryClient();\n const { data } = useSuspenseQuery({\n queryFn: () => service.getKeys(context),\n queryKey: [\"api-keys\"],\n retry: false,\n });\n\n const deleteKeyMutation = useMutation({\n mutationFn: (id: string) => {\n if (!service.deleteKey) {\n throw new Error(\"deleteKey not implemented\");\n }\n\n return service.deleteKey(id, context);\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [\"api-keys\"] });\n },\n });\n\n return (\n <div className=\"max-w-screen-lg h-full pt-[--padding-content-top] pb-[--padding-content-bottom]\">\n <Slotlet name=\"api-keys-list-page\" />\n\n <div className=\"flex justify-between mb-4 border-b pb-3\">\n <h1 className=\"font-medium text-2xl\">API Keys</h1>\n {service.createKey && (\n <Button asChild>\n <Link to=\"/settings/api-keys/new\">Create API Key</Link>\n </Button>\n )}\n </div>\n\n <Slotlet name=\"api-keys-list-page-before-keys\" />\n\n {data.length === 0 ? (\n <div className=\"flex flex-col justify-center gap-4 items-center h-1/2 my-8\">\n <div className=\"text-center\">\n No API keys created yet.\n <br />\n Get started and create the first one now\n </div>\n {service.createKey && (\n <Button asChild>\n <Link to=\"/settings/api-keys/new\">Create API Key</Link>\n </Button>\n )}\n </div>\n ) : (\n <ul\n className={cn(\n \"grid grid-cols-1 rounded border\",\n \"lg:grid-cols-[minmax(250px,min-content)_1fr_min-content]\",\n )}\n >\n {data.map((key) => (\n <li\n className=\"border-b p-5 grid grid-cols-subgrid col-span-full gap-2 items-center\"\n key={key.id}\n >\n <div className=\"flex flex-col gap-1 text-sm\">\n {key.description ?? key.id}\n <div className=\"text-muted-foreground text-xs\">\n {key.createdOn && (\n <div>\n Created on {new Date(key.createdOn).toLocaleDateString()}\n </div>\n )}\n {key.expiresOn && (\n <div>\n Expires on {new Date(key.expiresOn).toLocaleDateString()}\n </div>\n )}\n </div>\n </div>\n <div className=\"items-center flex lg:justify-center\">\n <RevealApiKey apiKey={key.key} />\n </div>\n <div className=\"flex gap-2\">\n {service.rollKey && (\n <Button size=\"icon\">\n <RotateCwIcon size={16} />\n </Button>\n )}\n {service.deleteKey && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => {\n if (!confirm(\"Do you want to delete this key?\")) {\n return;\n }\n\n deleteKeyMutation.mutate(key.id);\n }}\n disabled={deleteKeyMutation.isPending}\n >\n <TrashIcon size={16} />\n </Button>\n )}\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n};\n\nconst RevealApiKey = ({ apiKey }: { apiKey: string }) => {\n const [revealed, setRevealed] = useState(false);\n\n return (\n <div className=\"flex gap-2 items-center text-sm w-full\">\n <input\n className=\"border rounded bg-gray-100 dark:bg-gray-950 p-1 font-mono max-w-min\"\n value={revealed ? apiKey : \"•\".repeat(apiKey.length)}\n />\n <Button\n variant=\"outline\"\n onClick={() => setRevealed((prev) => !prev)}\n size=\"icon\"\n >\n {revealed ? <EyeOffIcon size={16} /> : <EyeIcon size={16} />}\n </Button>\n </div>\n );\n};\n","import { type RouteObject } from \"react-router-dom\";\nimport { DevPortalContext } from \"../../core/DevPortalContext.js\";\nimport {\n type ApiIdentityPlugin,\n type DevPortalPlugin,\n ProfileMenuPlugin,\n} from \"../../core/plugins.js\";\nimport { RouterError } from \"../../errors/RouterError.js\";\nimport invariant from \"../../util/invariant.js\";\nimport { CreateApiKey } from \"./CreateApiKey.js\";\nimport { ProtectedRoute } from \"./ProtectedRoute.js\";\nimport { SettingsApiKeys } from \"./SettingsApiKeys.js\";\n\nconst DEFAULT_API_KEY_ENDPOINT =\n \"https://zudoku-rewiringamerica-main-ef9c9c0.d2.zuplo.dev\";\n\nexport type ApiKeyService = {\n getKeys: (context: DevPortalContext) => Promise<ApiKey[]>;\n rollKey?: (id: string, context: DevPortalContext) => Promise<void>;\n deleteKey?: (id: string, context: DevPortalContext) => Promise<void>;\n updateKeyDescription?: (\n apiKey: { id: string; description: string },\n context: DevPortalContext,\n ) => Promise<void>;\n getUsage?: (apiKeys: string[], context: DevPortalContext) => Promise<void>;\n createKey?: (\n apiKey: { description: string; expiresOn?: string },\n context: DevPortalContext,\n ) => Promise<void>;\n};\n\nexport type GetApiKeysOptions = ApiKeyService | { endpoint: string } | object;\n\nexport type ApiKeyPluginOptions = object & GetApiKeysOptions;\n\nexport interface ApiKey {\n id: string;\n description?: string;\n createdOn?: string;\n updatedOn?: string;\n expiresOn?: string;\n key: string;\n}\n\nconst createDefaultHandler = (endpoint: string): ApiKeyService => {\n return {\n deleteKey: async (id, context) => {\n const request = new Request(endpoint + `/v1/developer/api-keys/${id}`, {\n method: \"DELETE\",\n });\n\n await context.signRequest(request);\n\n const response = await fetch(request);\n invariant(response.ok, \"Failed to delete API key\");\n },\n createKey: async (apiKey, context) => {\n const request = new Request(endpoint + `/v1/developer/api-keys`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(apiKey),\n });\n\n await context.signRequest(request);\n\n const response = await fetch(request);\n invariant(response.ok, \"Failed to create API key\");\n },\n getKeys: async (context) => {\n const request = new Request(endpoint + `/v1/developer/api-keys`);\n\n await context.signRequest(request);\n\n const keys = await fetch(request);\n invariant(keys.ok, \"Failed to fetch API keys\");\n\n return await keys.json();\n },\n };\n};\n\nexport const apiKeyPlugin = (\n options: ApiKeyPluginOptions,\n): DevPortalPlugin & ApiIdentityPlugin & ProfileMenuPlugin => {\n const endpoint =\n \"endpoint\" in options ? options.endpoint : DEFAULT_API_KEY_ENDPOINT;\n\n const service =\n \"getKeys\" in options ? options : createDefaultHandler(endpoint);\n\n return {\n getProfileMenuItems: () => [\n {\n label: \"API Keys\",\n path: \"/settings/api-keys\",\n },\n ],\n getIdentities: async (context) => {\n try {\n const keys = await service.getKeys(context);\n\n return keys.map((key) => ({\n authorizeRequest: (request) => {\n request.headers.set(\"Authorization\", `Bearer ${key.key}`);\n return request;\n },\n id: key.id,\n label: key.description ?? key.id,\n }));\n } catch {\n return [];\n }\n },\n getRoutes: (): RouteObject[] => {\n // TODO: Make lazy\n return [\n {\n element: <ProtectedRoute />,\n errorElement: <RouterError />,\n children: [\n {\n path: \"/settings/api-keys\",\n element: <SettingsApiKeys service={service} />,\n },\n {\n path: \"/settings/api-keys/new\",\n element: <CreateApiKey service={service} />,\n },\n ],\n },\n ];\n },\n };\n};\n"],"names":["EyeOff","createLucideIcon","Eye","RotateCw","Trash","invariant","condition","message","provided","ZudokuError","CreateApiKey","service","context","useDevPortal","navigate","useNavigate","form","useForm","createKeyMutation","useMutation","description","expiresOn","expiresOnDate","addDaysToDate","jsxs","jsx","data","Input","Select","value","SelectTrigger","SelectValue","SelectContent","SelectGroup","option","SelectItem","Button","Link","days","date","ProtectedRoute","auth","useAuth","Outlet","DeveloperHint","SettingsApiKeys","queryClient","useQueryClient","useSuspenseQuery","deleteKeyMutation","id","Slotlet","cn","key","RevealApiKey","RotateCwIcon","TrashIcon","apiKey","revealed","setRevealed","useState","prev","EyeOffIcon","EyeIcon","DEFAULT_API_KEY_ENDPOINT","createDefaultHandler","endpoint","request","response","keys","apiKeyPlugin","options","RouterError"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}
|
|
1
|
+
{"version":3,"file":"zudoku.plugin-api-keys.js","sources":["../../../node_modules/.pnpm/lucide-react@0.378.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/eye-off.js","../../../node_modules/.pnpm/lucide-react@0.378.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/eye.js","../../../node_modules/.pnpm/lucide-react@0.378.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/rotate-cw.js","../../../node_modules/.pnpm/lucide-react@0.378.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/trash.js","../src/lib/util/invariant.ts","../src/lib/plugins/api-keys/CreateApiKey.tsx","../src/lib/plugins/api-keys/ProtectedRoute.tsx","../src/lib/plugins/api-keys/SettingsApiKeys.tsx","../src/lib/plugins/api-keys/index.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.378.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst EyeOff = createLucideIcon(\"EyeOff\", [\n [\"path\", { d: \"M9.88 9.88a3 3 0 1 0 4.24 4.24\", key: \"1jxqfv\" }],\n [\n \"path\",\n {\n d: \"M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68\",\n key: \"9wicm4\"\n }\n ],\n [\n \"path\",\n { d: \"M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61\", key: \"1jreej\" }\n ],\n [\"line\", { x1: \"2\", x2: \"22\", y1: \"2\", y2: \"22\", key: \"a6p6uj\" }]\n]);\n\nexport { EyeOff as default };\n//# sourceMappingURL=eye-off.js.map\n","/**\n * @license lucide-react v0.378.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Eye = createLucideIcon(\"Eye\", [\n [\"path\", { d: \"M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z\", key: \"rwhkz3\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }]\n]);\n\nexport { Eye as default };\n//# sourceMappingURL=eye.js.map\n","/**\n * @license lucide-react v0.378.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst RotateCw = createLucideIcon(\"RotateCw\", [\n [\"path\", { d: \"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8\", key: \"1p45f6\" }],\n [\"path\", { d: \"M21 3v5h-5\", key: \"1q7to0\" }]\n]);\n\nexport { RotateCw as default };\n//# sourceMappingURL=rotate-cw.js.map\n","/**\n * @license lucide-react v0.378.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Trash = createLucideIcon(\"Trash\", [\n [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n [\"path\", { d: \"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\", key: \"4alrt4\" }],\n [\"path\", { d: \"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\", key: \"v07s0e\" }]\n]);\n\nexport { Trash as default };\n//# sourceMappingURL=trash.js.map\n","export default function invariant(\n condition: any,\n // Not providing an inline default argument for message as the result is smaller\n /**\n * Can provide a string, or a function that returns a string for cases where\n * the message takes a fair amount of effort to compute\n */\n message?: string | (() => string),\n): asserts condition {\n if (condition) {\n return;\n }\n // Condition not passed\n\n const provided: string | undefined =\n typeof message === \"function\" ? message() : message;\n\n throw new ZudokuError(provided ?? \"Invariant failed\");\n}\n\nclass ZudokuError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ZudokuError\";\n }\n}\n","import { useMutation } from \"@tanstack/react-query\";\nimport { useForm } from \"react-hook-form\";\nimport { Link, useNavigate } from \"react-router-dom\";\nimport { useDevPortal } from \"../../components/context/DevPortalProvider.js\";\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../components/Select.js\";\nimport { Button } from \"../../ui/Button.js\";\nimport { Input } from \"../../ui/Input.js\";\nimport { ApiKeyService } from \"./index.js\";\n\ntype CreateApiKey = { description: string; expiresOn?: string };\n\nexport const CreateApiKey = ({ service }: { service: ApiKeyService }) => {\n const context = useDevPortal();\n const navigate = useNavigate();\n const form = useForm<CreateApiKey>({\n defaultValues: {\n expiresOn: \"30\",\n },\n });\n const createKeyMutation = useMutation({\n mutationFn: ({ description, expiresOn }: CreateApiKey) => {\n if (!service.createKey) {\n throw new Error(\"deleteKey not implemented\");\n }\n\n const expiresOnDate =\n expiresOn !== \"never\" ? addDaysToDate(Number(expiresOn)) : undefined;\n\n return service.createKey(\n { description: description, expiresOn: expiresOnDate },\n context,\n );\n },\n onSuccess: () => navigate(\"/settings/api-keys/\"),\n });\n\n if (!service.createKey) {\n return null;\n }\n\n return (\n <div className=\"max-w-screen-lg pt-[--padding-content-top] pb-[--padding-content-bottom]\">\n <div className=\"flex justify-between mb-4 border-b pb-1\">\n <h1 className=\"font-medium text-2xl\">New API Key</h1>\n </div>\n <form\n onSubmit={form.handleSubmit((data) => createKeyMutation.mutate(data))}\n >\n <div className=\"flex gap-2 flex-col\">\n Note\n <Input {...form.register(\"description\")} />\n Expiration\n <Select\n onValueChange={(value) => form.setValue(\"expiresOn\", value)}\n defaultValue={form.getValues(\"expiresOn\")}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectGroup>\n {[7, 30, 60, 90].map((option) => (\n <SelectItem value={String(option)} key={option}>\n {option} days\n </SelectItem>\n ))}\n <SelectItem value=\"never\">Never</SelectItem>\n </SelectGroup>\n </SelectContent>\n </Select>\n <div className=\"flex gap-2\">\n <Button>Generate Key</Button>\n <Button variant=\"outline\" asChild>\n <Link to=\"/settings/api-keys/\">Cancel</Link>\n </Button>\n </div>\n </div>\n </form>\n </div>\n );\n};\n\nconst addDaysToDate = (days: number): string => {\n const date = new Date();\n date.setDate(date.getDate() + days);\n return date.toISOString();\n};\n","import { Outlet } from \"react-router-dom\";\nimport { useAuth } from \"../../authentication/hook.js\";\nimport { DeveloperHint } from \"../../components/DeveloperHint.js\";\nimport { Button } from \"../../ui/Button.js\";\n\nexport const ProtectedRoute = () => {\n const auth = useAuth();\n\n // TODO: should we suspend here somehow?\n if (auth.isAuthEnabled && auth.isPending) {\n return null;\n }\n\n return auth.isAuthenticated ? (\n <Outlet />\n ) : !auth.isAuthEnabled ? (\n <div className=\"flex flex-col justify-center gap-2 items-center h-1/2\">\n <DeveloperHint className=\"max-w-[600px]\">\n Authentication needs to be enabled for API keys to work. Enable it in\n your Zudoku configuration under <code>authentication</code>.\n </DeveloperHint>\n </div>\n ) : (\n <div className=\"flex flex-col justify-center gap-2 items-center h-1/2\">\n Please login first to view this page\n <Button onClick={() => auth.login()}>Login</Button>\n </div>\n );\n};\n","import {\n useMutation,\n useQueryClient,\n useSuspenseQuery,\n} from \"@tanstack/react-query\";\nimport { EyeIcon, EyeOffIcon, RotateCwIcon, TrashIcon } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport { useDevPortal } from \"../../components/context/DevPortalProvider.js\";\nimport { Slotlet } from \"../../components/SlotletProvider.js\";\nimport { Button } from \"../../ui/Button.js\";\nimport { cn } from \"../../util/cn.js\";\nimport { ApiKeyService } from \"./index.js\";\n\nexport const SettingsApiKeys = ({ service }: { service: ApiKeyService }) => {\n const context = useDevPortal();\n const queryClient = useQueryClient();\n const { data } = useSuspenseQuery({\n queryFn: () => service.getKeys(context),\n queryKey: [\"api-keys\"],\n retry: false,\n });\n\n const deleteKeyMutation = useMutation({\n mutationFn: (id: string) => {\n if (!service.deleteKey) {\n throw new Error(\"deleteKey not implemented\");\n }\n\n return service.deleteKey(id, context);\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [\"api-keys\"] });\n },\n });\n\n const rollKeyMutation = useMutation({\n mutationFn: (id: string) => {\n if (!service.rollKey) {\n throw new Error(\"rollKey not implemented\");\n }\n\n return service.rollKey(id, context);\n },\n onSuccess: () => queryClient.invalidateQueries({ queryKey: [\"api-keys\"] }),\n });\n\n return (\n <div className=\"max-w-screen-lg h-full pt-[--padding-content-top] pb-[--padding-content-bottom]\">\n <Slotlet name=\"api-keys-list-page\" />\n\n <div className=\"flex justify-between mb-4 border-b pb-3\">\n <h1 className=\"font-medium text-2xl\">API Keys</h1>\n {service.createKey && (\n <Button asChild>\n <Link to=\"/settings/api-keys/new\">Create API Key</Link>\n </Button>\n )}\n </div>\n\n <Slotlet name=\"api-keys-list-page-before-keys\" />\n\n {data.length === 0 ? (\n <div className=\"flex flex-col justify-center gap-4 items-center p-8 border rounded bg-muted/30 text-muted-foreground\">\n <p className=\"text-center\">\n No API keys created yet.\n <br />\n Get started and create your first key.\n </p>\n {service.createKey && (\n <Button asChild variant=\"outline\">\n <Link to=\"/settings/api-keys/new\">Create API Key</Link>\n </Button>\n )}\n </div>\n ) : (\n <ul\n className={cn(\n \"grid grid-cols-1 rounded border\",\n \"lg:grid-cols-[minmax(250px,min-content)_1fr_min-content]\",\n )}\n >\n {data.map((key) => (\n <li\n className=\"border-b p-5 grid grid-cols-subgrid col-span-full gap-2 items-center\"\n key={key.id}\n >\n <div className=\"flex flex-col gap-1 text-sm\">\n {key.description ?? key.id}\n <div className=\"text-muted-foreground text-xs\">\n {key.createdOn && (\n <div>\n Created on {new Date(key.createdOn).toLocaleDateString()}\n </div>\n )}\n {key.expiresOn && (\n <div>\n Expires on {new Date(key.expiresOn).toLocaleDateString()}\n </div>\n )}\n </div>\n </div>\n <div className=\"items-center flex lg:justify-center\">\n <RevealApiKey apiKey={key.key} />\n </div>\n <div className=\"flex gap-2\">\n {service.rollKey && (\n <Button\n size=\"icon\"\n title=\"Roll this key\"\n variant=\"ghost\"\n onClick={() => {\n if (!confirm(\"Do you want to roll this key?\")) {\n return;\n }\n\n rollKeyMutation.mutate(key.id);\n }}\n >\n <RotateCwIcon size={16} />\n </Button>\n )}\n {service.deleteKey && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => {\n if (!confirm(\"Do you want to delete this key?\")) {\n return;\n }\n\n deleteKeyMutation.mutate(key.id);\n }}\n disabled={deleteKeyMutation.isPending}\n >\n <TrashIcon size={16} />\n </Button>\n )}\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n};\n\nconst RevealApiKey = ({ apiKey }: { apiKey: string }) => {\n const [revealed, setRevealed] = useState(false);\n\n return (\n <div className=\"flex gap-2 items-center text-sm w-full\">\n <div className=\"border rounded bg-gray-100 dark:bg-gray-950 p-1 font-mono w-fit overflow-x-scroll h-9 items-center flex px-2\">\n {revealed ? apiKey : \"•\".repeat(apiKey.length)}\n </div>\n <Button\n variant=\"outline\"\n onClick={() => setRevealed((prev) => !prev)}\n size=\"icon\"\n >\n {revealed ? <EyeOffIcon size={16} /> : <EyeIcon size={16} />}\n </Button>\n </div>\n );\n};\n","import { type RouteObject } from \"react-router-dom\";\nimport { DevPortalContext } from \"../../core/DevPortalContext.js\";\nimport {\n type ApiIdentityPlugin,\n type DevPortalPlugin,\n ProfileMenuPlugin,\n} from \"../../core/plugins.js\";\nimport { RouterError } from \"../../errors/RouterError.js\";\nimport invariant from \"../../util/invariant.js\";\nimport { CreateApiKey } from \"./CreateApiKey.js\";\nimport { ProtectedRoute } from \"./ProtectedRoute.js\";\nimport { SettingsApiKeys } from \"./SettingsApiKeys.js\";\n\nconst DEFAULT_API_KEY_ENDPOINT =\n \"https://zudoku-rewiringamerica-main-ef9c9c0.d2.zuplo.dev\";\n\nexport type ApiKeyService = {\n getKeys: (context: DevPortalContext) => Promise<ApiKey[]>;\n rollKey?: (id: string, context: DevPortalContext) => Promise<void>;\n deleteKey?: (id: string, context: DevPortalContext) => Promise<void>;\n updateKeyDescription?: (\n apiKey: { id: string; description: string },\n context: DevPortalContext,\n ) => Promise<void>;\n getUsage?: (apiKeys: string[], context: DevPortalContext) => Promise<void>;\n createKey?: (\n apiKey: { description: string; expiresOn?: string },\n context: DevPortalContext,\n ) => Promise<void>;\n};\n\nexport type GetApiKeysOptions = ApiKeyService | { endpoint: string } | object;\n\nexport type ApiKeyPluginOptions = object & GetApiKeysOptions;\n\nexport interface ApiKey {\n id: string;\n description?: string;\n createdOn?: string;\n updatedOn?: string;\n expiresOn?: string;\n key: string;\n}\n\nconst createDefaultHandler = (endpoint: string): ApiKeyService => {\n return {\n deleteKey: async (id, context) => {\n const request = new Request(endpoint + `/v1/developer/api-keys/${id}`, {\n method: \"DELETE\",\n });\n\n await context.signRequest(request);\n\n const response = await fetch(request);\n invariant(response.ok, \"Failed to delete API key\");\n },\n rollKey: async (id, context) => {\n const response = await fetch(\n await context.signRequest(\n new Request(endpoint + `/v1/developer/api-keys/${id}/key`, {\n method: \"DELETE\",\n }),\n ),\n );\n invariant(response.ok, \"Failed to delete API key\");\n },\n createKey: async (apiKey, context) => {\n const request = new Request(endpoint + `/v1/developer/api-keys`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(apiKey),\n });\n\n await context.signRequest(request);\n\n const response = await fetch(request);\n invariant(response.ok, \"Failed to create API key\");\n },\n getKeys: async (context) => {\n const request = new Request(endpoint + `/v1/developer/api-keys`);\n\n await context.signRequest(request);\n\n const keys = await fetch(request);\n invariant(keys.ok, \"Failed to fetch API keys\");\n\n return await keys.json();\n },\n };\n};\n\nexport const apiKeyPlugin = (\n options: ApiKeyPluginOptions,\n): DevPortalPlugin & ApiIdentityPlugin & ProfileMenuPlugin => {\n const endpoint =\n \"endpoint\" in options ? options.endpoint : DEFAULT_API_KEY_ENDPOINT;\n\n const service =\n \"getKeys\" in options ? options : createDefaultHandler(endpoint);\n\n return {\n getProfileMenuItems: () => [\n {\n label: \"API Keys\",\n path: \"/settings/api-keys\",\n },\n ],\n getIdentities: async (context) => {\n try {\n const keys = await service.getKeys(context);\n\n return keys.map((key) => ({\n authorizeRequest: (request) => {\n request.headers.set(\"Authorization\", `Bearer ${key.key}`);\n return request;\n },\n id: key.id,\n label: key.description ?? key.id,\n }));\n } catch {\n return [];\n }\n },\n getRoutes: (): RouteObject[] => {\n // TODO: Make lazy\n return [\n {\n element: <ProtectedRoute />,\n errorElement: <RouterError />,\n children: [\n {\n path: \"/settings/api-keys\",\n element: <SettingsApiKeys service={service} />,\n },\n {\n path: \"/settings/api-keys/new\",\n element: <CreateApiKey service={service} />,\n },\n ],\n },\n ];\n },\n };\n};\n"],"names":["EyeOff","createLucideIcon","Eye","RotateCw","Trash","invariant","condition","message","provided","ZudokuError","CreateApiKey","service","context","useDevPortal","navigate","useNavigate","form","useForm","createKeyMutation","useMutation","description","expiresOn","expiresOnDate","addDaysToDate","jsxs","jsx","data","Input","Select","value","SelectTrigger","SelectValue","SelectContent","SelectGroup","option","SelectItem","Button","Link","days","date","ProtectedRoute","auth","useAuth","Outlet","DeveloperHint","SettingsApiKeys","queryClient","useQueryClient","useSuspenseQuery","deleteKeyMutation","id","rollKeyMutation","Slotlet","cn","key","RevealApiKey","RotateCwIcon","TrashIcon","apiKey","revealed","setRevealed","useState","prev","EyeOffIcon","EyeIcon","DEFAULT_API_KEY_ENDPOINT","createDefaultHandler","endpoint","request","response","keys","apiKeyPlugin","options","RouterError"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}
|