@happyvertical/smrt-users 0.37.2 → 0.37.3
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/chunks/TerminalAuthService-BXAAuaXf.js +4531 -0
- package/dist/chunks/TerminalAuthService-BXAAuaXf.js.map +1 -0
- package/dist/index.js +1564 -2024
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +2 -2
- package/dist/playground.js +114 -136
- package/dist/playground.js.map +1 -1
- package/dist/smrt-knowledge.json +12 -12
- package/dist/sveltekit.js +685 -881
- package/dist/sveltekit.js.map +1 -1
- package/dist/ui.js +79 -73
- package/dist/ui.js.map +1 -1
- package/package.json +19 -19
- package/dist/chunks/TerminalAuthService-DcgimQYo.js +0 -5261
- package/dist/chunks/TerminalAuthService-DcgimQYo.js.map +0 -1
- package/dist/chunks/index-C3E55ikp.js +0 -169
- package/dist/chunks/index-C3E55ikp.js.map +0 -1
package/dist/sveltekit.js
CHANGED
|
@@ -1,1006 +1,810 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { createLogger } from "@happyvertical/logger";
|
|
1
|
+
import { _ as resolveOidcProviderConfig, a as TerminalAuthRateLimitError, f as OidcLoginError, g as getUsersOidcConfig, h as encodeOidcTransaction, i as TerminalAuthError, l as withSessionPermissionContext, m as decodeOidcTransaction, o as TerminalAuthService, p as OidcLoginService, u as SessionService } from "./chunks/TerminalAuthService-BXAAuaXf.js";
|
|
3
2
|
import { ObjectRegistry } from "@happyvertical/smrt-core";
|
|
3
|
+
import { createLogger } from "@happyvertical/logger";
|
|
4
4
|
import { classnameToTablename } from "@happyvertical/smrt-core/utils";
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
import { methodNameToKebab, resolveApiActionSet } from "@happyvertical/smrt-core/vite-plugin";
|
|
6
|
+
//#region src/sveltekit/resource-list-handler.ts
|
|
7
|
+
var STANDARD_API_ACTIONS = [
|
|
8
|
+
"list",
|
|
9
|
+
"get",
|
|
10
|
+
"create",
|
|
11
|
+
"update",
|
|
12
|
+
"delete"
|
|
12
13
|
];
|
|
13
14
|
function createResourceListHandler(options) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
},
|
|
120
|
-
500
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
commandNameSeen.add(result.command.commandName);
|
|
124
|
-
candidates.push(result.command);
|
|
125
|
-
}
|
|
126
|
-
const policyResults = await Promise.all(
|
|
127
|
-
candidates.map(
|
|
128
|
-
(candidate) => commandPolicy({
|
|
129
|
-
resource: resourceShell,
|
|
130
|
-
command: candidate,
|
|
131
|
-
session,
|
|
132
|
-
classMeta
|
|
133
|
-
})
|
|
134
|
-
)
|
|
135
|
-
);
|
|
136
|
-
const allowed = candidates.filter((_, i) => policyResults[i]);
|
|
137
|
-
if (allowed.length === 0) continue;
|
|
138
|
-
resources.push({ ...resourceShell, commands: allowed });
|
|
139
|
-
}
|
|
140
|
-
const warnResults = await Promise.all(
|
|
141
|
-
skipWarnings.map(
|
|
142
|
-
(w) => commandPolicy({
|
|
143
|
-
resource: w.resourceMeta,
|
|
144
|
-
command: w.candidate,
|
|
145
|
-
session,
|
|
146
|
-
classMeta: w.classMeta
|
|
147
|
-
})
|
|
148
|
-
)
|
|
149
|
-
);
|
|
150
|
-
const visibleWarnings = skipWarnings.filter((_, i) => warnResults[i]).map((w) => `${w.ref}: ${w.reason}`);
|
|
151
|
-
const body = {
|
|
152
|
-
user: session.user ? { authenticated: true, id: String(session.user.id ?? "") } : { authenticated: false },
|
|
153
|
-
warnings: visibleWarnings,
|
|
154
|
-
resources
|
|
155
|
-
};
|
|
156
|
-
return jsonResponse$1(body, 200, {
|
|
157
|
-
"cache-control": "private, no-store"
|
|
158
|
-
});
|
|
159
|
-
};
|
|
15
|
+
const { ensureRegistry, resolveSession = (event) => defaultResolveSession(event, options), commandPolicy = defaultCommandPolicy, resourceSlug = defaultResourceSlug, kebabRoutes = false } = options;
|
|
16
|
+
return async (event) => {
|
|
17
|
+
await ensureRegistry();
|
|
18
|
+
let session;
|
|
19
|
+
try {
|
|
20
|
+
session = await resolveSession(event);
|
|
21
|
+
} catch (error) {
|
|
22
|
+
if (error instanceof InvalidBearerError) return jsonResponse$1({ error: error.message }, 401);
|
|
23
|
+
throw error;
|
|
24
|
+
}
|
|
25
|
+
const resources = [];
|
|
26
|
+
const skipWarnings = [];
|
|
27
|
+
const slugSeen = /* @__PURE__ */ new Map();
|
|
28
|
+
for (const [registeredName, registered] of ObjectRegistry.getAllClasses()) {
|
|
29
|
+
const def = synthesizeDefinition(registeredName, registered);
|
|
30
|
+
const cliConfig = def.decoratorConfig.cli;
|
|
31
|
+
if (!cliConfig) continue;
|
|
32
|
+
if (!isHttpCliConfig(cliConfig)) continue;
|
|
33
|
+
if (isCollectionClass(def)) continue;
|
|
34
|
+
const includedMethods = resolveCliIncludedMethods(cliConfig, resolveApiActionSet(def));
|
|
35
|
+
if (includedMethods.length === 0) continue;
|
|
36
|
+
const slug = resourceSlug({
|
|
37
|
+
className: def.className,
|
|
38
|
+
collection: def.collection,
|
|
39
|
+
qualifiedName: def.qualifiedName,
|
|
40
|
+
packageName: def.packageName
|
|
41
|
+
});
|
|
42
|
+
const previous = slugSeen.get(slug);
|
|
43
|
+
if (previous && previous !== def.qualifiedName) return jsonResponse$1({
|
|
44
|
+
error: "resource-slug-collision",
|
|
45
|
+
slug,
|
|
46
|
+
classes: [previous, def.qualifiedName ?? def.className].filter(Boolean)
|
|
47
|
+
}, 500);
|
|
48
|
+
slugSeen.set(slug, def.qualifiedName ?? def.className);
|
|
49
|
+
const resourceShell = {
|
|
50
|
+
slug,
|
|
51
|
+
className: def.className,
|
|
52
|
+
qualifiedName: def.qualifiedName,
|
|
53
|
+
packageName: def.packageName,
|
|
54
|
+
label: humanLabel(def.className),
|
|
55
|
+
apiPath: resolveApiPath(def)
|
|
56
|
+
};
|
|
57
|
+
const classMeta = {
|
|
58
|
+
name: def.className,
|
|
59
|
+
qualifiedName: def.qualifiedName,
|
|
60
|
+
packageName: def.packageName,
|
|
61
|
+
decoratorConfig: def.decoratorConfig
|
|
62
|
+
};
|
|
63
|
+
const commandNameSeen = /* @__PURE__ */ new Set();
|
|
64
|
+
const candidates = [];
|
|
65
|
+
for (const methodName of includedMethods) {
|
|
66
|
+
const result = buildCommand(def, methodName, kebabRoutes);
|
|
67
|
+
if (!result.ok) {
|
|
68
|
+
skipWarnings.push({
|
|
69
|
+
ref: `${def.className}.${methodName}`,
|
|
70
|
+
reason: result.reason,
|
|
71
|
+
candidate: result.candidate,
|
|
72
|
+
resourceMeta: resourceShell,
|
|
73
|
+
classMeta
|
|
74
|
+
});
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (result.command.kind === "custom" && STANDARD_API_ACTIONS.includes(result.command.commandName)) return jsonResponse$1({
|
|
78
|
+
error: "command-name-shadows-crud",
|
|
79
|
+
className: def.className,
|
|
80
|
+
methodName,
|
|
81
|
+
commandName: result.command.commandName
|
|
82
|
+
}, 500);
|
|
83
|
+
if (commandNameSeen.has(result.command.commandName)) return jsonResponse$1({
|
|
84
|
+
error: "command-name-collision",
|
|
85
|
+
className: def.className,
|
|
86
|
+
commandName: result.command.commandName
|
|
87
|
+
}, 500);
|
|
88
|
+
commandNameSeen.add(result.command.commandName);
|
|
89
|
+
candidates.push(result.command);
|
|
90
|
+
}
|
|
91
|
+
const policyResults = await Promise.all(candidates.map((candidate) => commandPolicy({
|
|
92
|
+
resource: resourceShell,
|
|
93
|
+
command: candidate,
|
|
94
|
+
session,
|
|
95
|
+
classMeta
|
|
96
|
+
})));
|
|
97
|
+
const allowed = candidates.filter((_, i) => policyResults[i]);
|
|
98
|
+
if (allowed.length === 0) continue;
|
|
99
|
+
resources.push({
|
|
100
|
+
...resourceShell,
|
|
101
|
+
commands: allowed
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
const warnResults = await Promise.all(skipWarnings.map((w) => commandPolicy({
|
|
105
|
+
resource: w.resourceMeta,
|
|
106
|
+
command: w.candidate,
|
|
107
|
+
session,
|
|
108
|
+
classMeta: w.classMeta
|
|
109
|
+
})));
|
|
110
|
+
const visibleWarnings = skipWarnings.filter((_, i) => warnResults[i]).map((w) => `${w.ref}: ${w.reason}`);
|
|
111
|
+
return jsonResponse$1({
|
|
112
|
+
user: session.user ? {
|
|
113
|
+
authenticated: true,
|
|
114
|
+
id: String(session.user.id ?? "")
|
|
115
|
+
} : { authenticated: false },
|
|
116
|
+
warnings: visibleWarnings,
|
|
117
|
+
resources
|
|
118
|
+
}, 200, { "cache-control": "private, no-store" });
|
|
119
|
+
};
|
|
160
120
|
}
|
|
161
121
|
function synthesizeDefinition(_registeredName, registered) {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
constructor: registered.constructor
|
|
179
|
-
};
|
|
122
|
+
const methods = {};
|
|
123
|
+
for (const [name, value] of registered.methods.entries()) methods[name] = value;
|
|
124
|
+
const decoratorConfig = registered.config ?? {};
|
|
125
|
+
const collection = registered.collection ?? deriveCollectionFromConfig(decoratorConfig) ?? classnameToTablename(registered.name);
|
|
126
|
+
return {
|
|
127
|
+
className: registered.name,
|
|
128
|
+
qualifiedName: registered.qualifiedName,
|
|
129
|
+
packageName: registered.packageName,
|
|
130
|
+
collection,
|
|
131
|
+
decoratorConfig,
|
|
132
|
+
methods,
|
|
133
|
+
tools: registered.tools,
|
|
134
|
+
extends: registered.extends,
|
|
135
|
+
extendsTypeArg: registered.extendsTypeArg,
|
|
136
|
+
constructor: registered.constructor
|
|
137
|
+
};
|
|
180
138
|
}
|
|
181
139
|
function isCollectionClass(def) {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
140
|
+
if (def.extends === "SmrtCollection") return true;
|
|
141
|
+
if (def.extendsTypeArg) return true;
|
|
142
|
+
return ctorChainContains(def.constructor, "SmrtCollection");
|
|
185
143
|
}
|
|
186
144
|
function ctorChainContains(ctor, name, depthCap = 16) {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
145
|
+
let current = ctor;
|
|
146
|
+
for (let i = 0; i < depthCap && current; i += 1) {
|
|
147
|
+
if (current.name === name) return true;
|
|
148
|
+
const next = Object.getPrototypeOf(current);
|
|
149
|
+
if (!next || next === current) break;
|
|
150
|
+
current = next;
|
|
151
|
+
}
|
|
152
|
+
return false;
|
|
195
153
|
}
|
|
196
154
|
function deriveCollectionFromConfig(config) {
|
|
197
|
-
|
|
155
|
+
return config?.tableName ?? void 0;
|
|
198
156
|
}
|
|
199
157
|
function resolveCliIncludedMethods(cliConfig, apiActionSet) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
candidates = STANDARD_API_ACTIONS.filter((a) => apiActionSet.has(a));
|
|
221
|
-
}
|
|
222
|
-
if (exclude && exclude.length > 0) {
|
|
223
|
-
const excludeSet = new Set(exclude);
|
|
224
|
-
candidates = candidates.filter((m) => !excludeSet.has(m));
|
|
225
|
-
}
|
|
226
|
-
return candidates;
|
|
158
|
+
if (cliConfig === true) return STANDARD_API_ACTIONS.filter((a) => apiActionSet.has(a));
|
|
159
|
+
if (cliConfig === false) return [];
|
|
160
|
+
if (typeof cliConfig !== "object" || cliConfig === null) return [];
|
|
161
|
+
if (Array.isArray(cliConfig)) return [];
|
|
162
|
+
const obj = cliConfig;
|
|
163
|
+
if (obj.include !== void 0 && !Array.isArray(obj.include)) return [];
|
|
164
|
+
if (obj.exclude !== void 0 && !Array.isArray(obj.exclude)) return [];
|
|
165
|
+
if (obj.mirror !== void 0 && obj.mirror !== "api") return [];
|
|
166
|
+
const include = obj.include;
|
|
167
|
+
const exclude = obj.exclude;
|
|
168
|
+
let candidates;
|
|
169
|
+
if (obj.mirror === "api") candidates = [...apiActionSet];
|
|
170
|
+
else if (include?.includes("*")) candidates = [...apiActionSet];
|
|
171
|
+
else if (include && include.length > 0) candidates = include.filter((m) => apiActionSet.has(m));
|
|
172
|
+
else candidates = STANDARD_API_ACTIONS.filter((a) => apiActionSet.has(a));
|
|
173
|
+
if (exclude && exclude.length > 0) {
|
|
174
|
+
const excludeSet = new Set(exclude);
|
|
175
|
+
candidates = candidates.filter((m) => !excludeSet.has(m));
|
|
176
|
+
}
|
|
177
|
+
return candidates;
|
|
227
178
|
}
|
|
228
179
|
function isHttpCliConfig(cliConfig) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
180
|
+
if (typeof cliConfig !== "object" || cliConfig === null) return true;
|
|
181
|
+
if (Array.isArray(cliConfig)) return true;
|
|
182
|
+
return cliConfig.http !== false;
|
|
232
183
|
}
|
|
233
184
|
function buildCommand(def, methodName, kebabRoutes) {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
const methodHasParams = (methodDef.parameters?.length ?? 0) > 0;
|
|
266
|
-
if (methodHasParams || hasNonIdParameters(candidate.parameters)) {
|
|
267
|
-
return {
|
|
268
|
-
ok: false,
|
|
269
|
-
reason: "DELETE-with-body unsupported",
|
|
270
|
-
candidate
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
return { ok: true, command: candidate };
|
|
185
|
+
if (STANDARD_API_ACTIONS.includes(methodName)) return {
|
|
186
|
+
ok: true,
|
|
187
|
+
command: buildCrudCommand(methodName)
|
|
188
|
+
};
|
|
189
|
+
const methodDef = def.methods[methodName];
|
|
190
|
+
if (!methodDef) return {
|
|
191
|
+
ok: true,
|
|
192
|
+
command: buildCustomCommand(def, methodName, void 0, kebabRoutes)
|
|
193
|
+
};
|
|
194
|
+
if ((methodDef.parameters?.length ?? 0) > 1) return {
|
|
195
|
+
ok: false,
|
|
196
|
+
reason: "multi-arg unsupported (use single-options-object convention)",
|
|
197
|
+
candidate: buildCustomCommand(def, methodName, methodDef, kebabRoutes)
|
|
198
|
+
};
|
|
199
|
+
const candidate = buildCustomCommand(def, methodName, methodDef, kebabRoutes);
|
|
200
|
+
if (hasDynamicSegments(candidate.pathSegments)) return {
|
|
201
|
+
ok: false,
|
|
202
|
+
reason: "dynamic-path-params unsupported",
|
|
203
|
+
candidate
|
|
204
|
+
};
|
|
205
|
+
if (candidate.httpMethod === "DELETE" && candidate.kind === "custom") {
|
|
206
|
+
if ((methodDef.parameters?.length ?? 0) > 0 || hasNonIdParameters(candidate.parameters)) return {
|
|
207
|
+
ok: false,
|
|
208
|
+
reason: "DELETE-with-body unsupported",
|
|
209
|
+
candidate
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
ok: true,
|
|
214
|
+
command: candidate
|
|
215
|
+
};
|
|
275
216
|
}
|
|
276
217
|
function buildCrudCommand(name) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
description: defaultCrudDescription(name)
|
|
287
|
-
};
|
|
218
|
+
return {
|
|
219
|
+
methodName: name,
|
|
220
|
+
commandName: name,
|
|
221
|
+
kind: "crud",
|
|
222
|
+
scope: name === "get" || name === "update" || name === "delete" ? "item" : "collection",
|
|
223
|
+
httpMethod: name === "list" || name === "get" ? "GET" : name === "create" ? "POST" : name === "update" ? "PUT" : "DELETE",
|
|
224
|
+
pathSegments: [],
|
|
225
|
+
description: defaultCrudDescription(name)
|
|
226
|
+
};
|
|
288
227
|
}
|
|
289
228
|
function buildCustomCommand(def, methodName, methodDef, kebabRoutes) {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
description: methodDef?.description,
|
|
311
|
-
parameters
|
|
312
|
-
};
|
|
229
|
+
const routeConfig = getApiConfigObject(def.decoratorConfig.api)?.routes?.[methodName];
|
|
230
|
+
const defaultScope = methodDef?.isStatic ? "collection" : "item";
|
|
231
|
+
const scope = routeConfig?.scope ?? defaultScope;
|
|
232
|
+
const httpMethod = normalizeApiHttpMethod(routeConfig?.method);
|
|
233
|
+
let pathSegments;
|
|
234
|
+
if (routeConfig?.path) {
|
|
235
|
+
pathSegments = routeConfig.path.split("/").map((s) => s.trim()).filter(Boolean);
|
|
236
|
+
if (pathSegments.length === 0) pathSegments = [methodName];
|
|
237
|
+
} else pathSegments = [kebabRoutes ? methodNameToKebab(methodName) : methodName];
|
|
238
|
+
const parameters = resolveParametersSchema(def, methodName, methodDef);
|
|
239
|
+
return {
|
|
240
|
+
methodName,
|
|
241
|
+
commandName: methodNameToKebab(methodName),
|
|
242
|
+
kind: "custom",
|
|
243
|
+
scope,
|
|
244
|
+
httpMethod,
|
|
245
|
+
pathSegments,
|
|
246
|
+
description: methodDef?.description,
|
|
247
|
+
parameters
|
|
248
|
+
};
|
|
313
249
|
}
|
|
314
250
|
function resolveParametersSchema(def, methodName, _methodDef) {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
return void 0;
|
|
251
|
+
const tool = def.tools?.find((t) => t.function.name === methodName);
|
|
252
|
+
if (tool?.function.parameters) {
|
|
253
|
+
const params = tool.function.parameters;
|
|
254
|
+
if (hasUsableProperties(params)) return params;
|
|
255
|
+
}
|
|
321
256
|
}
|
|
322
257
|
function hasUsableProperties(schema) {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
258
|
+
if (!schema || typeof schema !== "object") return false;
|
|
259
|
+
const props = schema.properties;
|
|
260
|
+
if (!props || typeof props !== "object") return false;
|
|
261
|
+
return Object.keys(props).length > 0;
|
|
327
262
|
}
|
|
328
263
|
function normalizeApiHttpMethod(method) {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
return "POST";
|
|
338
|
-
}
|
|
264
|
+
switch (method?.toUpperCase()) {
|
|
265
|
+
case "GET":
|
|
266
|
+
case "POST":
|
|
267
|
+
case "PUT":
|
|
268
|
+
case "PATCH":
|
|
269
|
+
case "DELETE": return method.toUpperCase();
|
|
270
|
+
default: return "POST";
|
|
271
|
+
}
|
|
339
272
|
}
|
|
340
273
|
function getApiConfigObject(api) {
|
|
341
|
-
|
|
342
|
-
|
|
274
|
+
if (typeof api !== "object" || api === null) return void 0;
|
|
275
|
+
return api;
|
|
343
276
|
}
|
|
344
277
|
function hasDynamicSegments(segments) {
|
|
345
|
-
|
|
278
|
+
return segments.some((s) => /^\[.+\]$/.test(s) || s.startsWith(":"));
|
|
346
279
|
}
|
|
347
280
|
function hasNonIdParameters(parameters) {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
return keys.length > 0;
|
|
281
|
+
if (!parameters || typeof parameters !== "object") return false;
|
|
282
|
+
const props = parameters.properties;
|
|
283
|
+
if (!props) return false;
|
|
284
|
+
return Object.keys(props).filter((k) => k !== "id").length > 0;
|
|
353
285
|
}
|
|
354
286
|
function defaultCrudDescription(name) {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
case "update":
|
|
363
|
-
return "Update an existing record";
|
|
364
|
-
case "delete":
|
|
365
|
-
return "Delete a record";
|
|
366
|
-
}
|
|
287
|
+
switch (name) {
|
|
288
|
+
case "list": return "List records";
|
|
289
|
+
case "get": return "Get a record by id";
|
|
290
|
+
case "create": return "Create a new record";
|
|
291
|
+
case "update": return "Update an existing record";
|
|
292
|
+
case "delete": return "Delete a record";
|
|
293
|
+
}
|
|
367
294
|
}
|
|
368
295
|
function resolveApiPath(def) {
|
|
369
|
-
|
|
296
|
+
return def.collection;
|
|
370
297
|
}
|
|
371
298
|
function defaultResourceSlug(meta) {
|
|
372
|
-
|
|
299
|
+
return meta.collection;
|
|
373
300
|
}
|
|
374
301
|
function humanLabel(className) {
|
|
375
|
-
|
|
376
|
-
}
|
|
377
|
-
class InvalidBearerError extends Error {
|
|
378
|
-
constructor(message = "Invalid or expired bearer token.") {
|
|
379
|
-
super(message);
|
|
380
|
-
this.name = "InvalidBearerError";
|
|
381
|
-
}
|
|
302
|
+
return className.replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/([a-z0-9])([A-Z])/g, "$1 $2");
|
|
382
303
|
}
|
|
304
|
+
var InvalidBearerError = class extends Error {
|
|
305
|
+
constructor(message = "Invalid or expired bearer token.") {
|
|
306
|
+
super(message);
|
|
307
|
+
this.name = "InvalidBearerError";
|
|
308
|
+
}
|
|
309
|
+
};
|
|
383
310
|
async function defaultResolveSession(event, options) {
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
permissions: [],
|
|
412
|
-
tenantId: null,
|
|
413
|
-
sessionId: null
|
|
414
|
-
};
|
|
311
|
+
const locals = event.locals ?? {};
|
|
312
|
+
if (locals.user) return {
|
|
313
|
+
user: locals.user,
|
|
314
|
+
membership: locals.membership ?? null,
|
|
315
|
+
permissions: locals.permissions ?? [],
|
|
316
|
+
tenantId: locals.tenantId ?? null,
|
|
317
|
+
sessionId: locals.sessionId ?? null
|
|
318
|
+
};
|
|
319
|
+
const bearer = parseBearerToken(event.request.headers.get("authorization"));
|
|
320
|
+
if (bearer) {
|
|
321
|
+
const ctx = await loadBearerSessionContext(bearer, options);
|
|
322
|
+
if (!ctx) throw new InvalidBearerError();
|
|
323
|
+
return {
|
|
324
|
+
user: ctx.user,
|
|
325
|
+
membership: ctx.membership ?? null,
|
|
326
|
+
permissions: ctx.permissions,
|
|
327
|
+
tenantId: ctx.tenantId,
|
|
328
|
+
sessionId: ctx.sessionId
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
return {
|
|
332
|
+
user: null,
|
|
333
|
+
membership: null,
|
|
334
|
+
permissions: [],
|
|
335
|
+
tenantId: null,
|
|
336
|
+
sessionId: null
|
|
337
|
+
};
|
|
415
338
|
}
|
|
416
339
|
function defaultCommandPolicy(ctx) {
|
|
417
|
-
|
|
340
|
+
return ctx.session.user != null;
|
|
418
341
|
}
|
|
419
342
|
function jsonResponse$1(body, status = 200, extraHeaders = {}) {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
343
|
+
return new Response(JSON.stringify(body), {
|
|
344
|
+
status,
|
|
345
|
+
headers: {
|
|
346
|
+
"content-type": "application/json",
|
|
347
|
+
...extraHeaders
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
//#endregion
|
|
352
|
+
//#region src/sveltekit/types.ts
|
|
353
|
+
var defaultSessionLocals = {
|
|
354
|
+
user: null,
|
|
355
|
+
membership: null,
|
|
356
|
+
permissions: [],
|
|
357
|
+
tenantId: null,
|
|
358
|
+
sessionId: null
|
|
434
359
|
};
|
|
435
|
-
|
|
360
|
+
//#endregion
|
|
361
|
+
//#region src/sveltekit/index.ts
|
|
362
|
+
var logger = createLogger({ level: "info" });
|
|
436
363
|
function createSessionHandler(options) {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
);
|
|
485
|
-
} catch (error) {
|
|
486
|
-
logger.error("Session or request context initialization error", {
|
|
487
|
-
error
|
|
488
|
-
});
|
|
489
|
-
if (options.postgresRls) {
|
|
490
|
-
return new Response("Internal Server Error", { status: 500 });
|
|
491
|
-
}
|
|
492
|
-
return resolve(event);
|
|
493
|
-
}
|
|
494
|
-
};
|
|
495
|
-
}
|
|
496
|
-
const sessionServiceCache = /* @__PURE__ */ new Map();
|
|
364
|
+
const cookieName = options.cookieName ?? "sid";
|
|
365
|
+
const ttl = options.ttl ?? 604800;
|
|
366
|
+
const skipPaths = options.skipPaths ?? [];
|
|
367
|
+
let sessionService = null;
|
|
368
|
+
const getSessionService = async () => {
|
|
369
|
+
if (!sessionService) sessionService = await SessionService.create({
|
|
370
|
+
...options,
|
|
371
|
+
defaultTTL: ttl,
|
|
372
|
+
autoExtend: options.autoExtend ?? false
|
|
373
|
+
});
|
|
374
|
+
return sessionService;
|
|
375
|
+
};
|
|
376
|
+
return async ({ event, resolve }) => {
|
|
377
|
+
event.locals.user = null;
|
|
378
|
+
event.locals.membership = null;
|
|
379
|
+
event.locals.permissions = [];
|
|
380
|
+
event.locals.tenantId = null;
|
|
381
|
+
event.locals.sessionId = null;
|
|
382
|
+
if (skipPaths.some((path) => event.url.pathname.startsWith(path))) return resolve(event);
|
|
383
|
+
const sessionId = event.cookies.get(cookieName);
|
|
384
|
+
if (!sessionId && !options.postgresRls) return resolve(event);
|
|
385
|
+
try {
|
|
386
|
+
const service = await getSessionService();
|
|
387
|
+
return await withSessionPermissionContext({
|
|
388
|
+
...options,
|
|
389
|
+
enterTenantContext: options.enterTenantContext,
|
|
390
|
+
postgresRls: options.postgresRls,
|
|
391
|
+
sessionId,
|
|
392
|
+
sessionService: service
|
|
393
|
+
}, async (context) => {
|
|
394
|
+
if (context.session) {
|
|
395
|
+
event.locals.user = context.user;
|
|
396
|
+
event.locals.membership = context.membership ?? null;
|
|
397
|
+
event.locals.permissions = context.permissions;
|
|
398
|
+
event.locals.tenantId = context.tenantId;
|
|
399
|
+
event.locals.sessionId = context.sessionId;
|
|
400
|
+
}
|
|
401
|
+
return resolve(event);
|
|
402
|
+
});
|
|
403
|
+
} catch (error) {
|
|
404
|
+
logger.error("Session or request context initialization error", { error });
|
|
405
|
+
if (options.postgresRls) return new Response("Internal Server Error", { status: 500 });
|
|
406
|
+
return resolve(event);
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
var sessionServiceCache = /* @__PURE__ */ new Map();
|
|
497
411
|
async function getOrCreateSessionService(options, ttl) {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
412
|
+
const cacheKey = JSON.stringify(options.db);
|
|
413
|
+
let service = sessionServiceCache.get(cacheKey);
|
|
414
|
+
if (!service) {
|
|
415
|
+
service = await SessionService.create({
|
|
416
|
+
...options,
|
|
417
|
+
defaultTTL: ttl
|
|
418
|
+
});
|
|
419
|
+
sessionServiceCache.set(cacheKey, service);
|
|
420
|
+
}
|
|
421
|
+
return service;
|
|
508
422
|
}
|
|
509
423
|
async function createSessionCookie(event, userId, tenantId, options) {
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
});
|
|
531
|
-
return sessionId;
|
|
424
|
+
const cookieName = options.cookieName ?? "sid";
|
|
425
|
+
const ttl = options.ttl ?? 604800;
|
|
426
|
+
const cookiePath = options.cookiePath ?? "/";
|
|
427
|
+
const cookieSameSite = options.cookieSameSite ?? "lax";
|
|
428
|
+
const cookieSecure = options.cookieSecure ?? event.url.protocol === "https:";
|
|
429
|
+
const sessionId = await (await getOrCreateSessionService(options, ttl)).createSession(userId, tenantId, {
|
|
430
|
+
ttl,
|
|
431
|
+
userAgent: options.userAgent,
|
|
432
|
+
ipAddress: options.ipAddress,
|
|
433
|
+
data: options.data
|
|
434
|
+
});
|
|
435
|
+
event.cookies.set(cookieName, sessionId, {
|
|
436
|
+
path: cookiePath,
|
|
437
|
+
domain: options.cookieDomain,
|
|
438
|
+
httpOnly: true,
|
|
439
|
+
secure: cookieSecure,
|
|
440
|
+
sameSite: cookieSameSite,
|
|
441
|
+
maxAge: ttl
|
|
442
|
+
});
|
|
443
|
+
return sessionId;
|
|
532
444
|
}
|
|
533
445
|
async function destroySessionCookie(event, options) {
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
path: cookiePath,
|
|
548
|
-
domain: options.cookieDomain
|
|
549
|
-
});
|
|
446
|
+
const cookieName = options.cookieName ?? "sid";
|
|
447
|
+
const cookiePath = options.cookiePath ?? "/";
|
|
448
|
+
const ttl = options.ttl ?? 604800;
|
|
449
|
+
const sessionId = event.cookies.get(cookieName);
|
|
450
|
+
if (sessionId) try {
|
|
451
|
+
await (await getOrCreateSessionService(options, ttl)).destroySession(sessionId);
|
|
452
|
+
} catch (error) {
|
|
453
|
+
logger.error("Session destruction error", { error });
|
|
454
|
+
}
|
|
455
|
+
event.cookies.delete(cookieName, {
|
|
456
|
+
path: cookiePath,
|
|
457
|
+
domain: options.cookieDomain
|
|
458
|
+
});
|
|
550
459
|
}
|
|
551
460
|
async function switchSessionTenant(event, tenantId, options) {
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
httpOnly: true,
|
|
573
|
-
secure: cookieSecure,
|
|
574
|
-
sameSite: cookieSameSite,
|
|
575
|
-
maxAge
|
|
576
|
-
});
|
|
577
|
-
}
|
|
578
|
-
return result.switched;
|
|
461
|
+
const cookieName = options.cookieName ?? "sid";
|
|
462
|
+
const ttl = options.ttl ?? 604800;
|
|
463
|
+
const sessionId = event.cookies.get(cookieName);
|
|
464
|
+
if (!sessionId) return false;
|
|
465
|
+
const result = await (await getOrCreateSessionService(options, ttl)).switchTenant(sessionId, tenantId);
|
|
466
|
+
if (result.rotated && result.sessionId) {
|
|
467
|
+
const cookiePath = options.cookiePath ?? "/";
|
|
468
|
+
const cookieSameSite = options.cookieSameSite ?? "lax";
|
|
469
|
+
const cookieSecure = options.cookieSecure ?? event.url.protocol === "https:";
|
|
470
|
+
const maxAge = result.session ? Math.max(0, Math.round((new Date(result.session.expiresAt).getTime() - Date.now()) / 1e3)) : ttl;
|
|
471
|
+
event.cookies.set(cookieName, result.sessionId, {
|
|
472
|
+
path: cookiePath,
|
|
473
|
+
domain: options.cookieDomain,
|
|
474
|
+
httpOnly: true,
|
|
475
|
+
secure: cookieSecure,
|
|
476
|
+
sameSite: cookieSameSite,
|
|
477
|
+
maxAge
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
return result.switched;
|
|
579
481
|
}
|
|
580
482
|
function getOidcProviderName(event, options) {
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
}
|
|
584
|
-
return options.provider ?? event.params?.provider ?? options.defaultProvider;
|
|
483
|
+
if (typeof options.provider === "function") return options.provider(event);
|
|
484
|
+
return options.provider ?? event.params?.provider ?? options.defaultProvider;
|
|
585
485
|
}
|
|
586
486
|
function getOidcTransactionCookieName(providerName, options) {
|
|
587
|
-
|
|
588
|
-
const safeProvider = providerName.replace(/[^a-z0-9_-]/giu, "_");
|
|
589
|
-
return `${prefix}_${safeProvider}`;
|
|
487
|
+
return `${options.transactionCookiePrefix ?? "smrt_oidc"}_${providerName.replace(/[^a-z0-9_-]/giu, "_")}`;
|
|
590
488
|
}
|
|
591
489
|
function useSecureCookie(event, explicit) {
|
|
592
|
-
|
|
490
|
+
return explicit ?? event.url.protocol === "https:";
|
|
593
491
|
}
|
|
594
492
|
function resolveCallbackPath(providerName, options) {
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
}
|
|
598
|
-
return options.callbackPath ?? `/auth/${providerName}/callback`;
|
|
493
|
+
if (typeof options.callbackPath === "function") return options.callbackPath(providerName);
|
|
494
|
+
return options.callbackPath ?? `/auth/${providerName}/callback`;
|
|
599
495
|
}
|
|
600
496
|
function resolveProviderWithRedirectUri(event, providerName, provider, options) {
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
event.url.origin
|
|
606
|
-
).toString()
|
|
607
|
-
};
|
|
497
|
+
return {
|
|
498
|
+
...provider,
|
|
499
|
+
redirectUri: provider.redirectUri ?? new URL(resolveCallbackPath(providerName, options), event.url.origin).toString()
|
|
500
|
+
};
|
|
608
501
|
}
|
|
609
502
|
function createOidcService(event, options) {
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
);
|
|
618
|
-
return new OidcLoginService({
|
|
619
|
-
...options,
|
|
620
|
-
provider,
|
|
621
|
-
providerName: resolved.providerName
|
|
622
|
-
});
|
|
503
|
+
const resolved = resolveOidcProviderConfig(getOidcProviderName(event, options), options);
|
|
504
|
+
const provider = resolveProviderWithRedirectUri(event, resolved.providerName, resolved.provider, options);
|
|
505
|
+
return new OidcLoginService({
|
|
506
|
+
...options,
|
|
507
|
+
provider,
|
|
508
|
+
providerName: resolved.providerName
|
|
509
|
+
});
|
|
623
510
|
}
|
|
624
511
|
function getReturnTo(event, options) {
|
|
625
|
-
|
|
626
|
-
|
|
512
|
+
const param = options.returnToParam ?? "returnTo";
|
|
513
|
+
return getLocalReturnTo(event.url.searchParams.get(param));
|
|
627
514
|
}
|
|
628
515
|
function getLocalReturnTo(returnTo) {
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
return returnTo;
|
|
632
|
-
}
|
|
633
|
-
return void 0;
|
|
516
|
+
if (!returnTo) return void 0;
|
|
517
|
+
if (returnTo.startsWith("/") && !returnTo.startsWith("//")) return returnTo;
|
|
634
518
|
}
|
|
635
519
|
function getTransactionCookieSameSite(event, options) {
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
}
|
|
639
|
-
return useSecureCookie(event, options.transactionCookieSecure) ? "none" : "lax";
|
|
520
|
+
if (options.transactionCookieSameSite) return options.transactionCookieSameSite;
|
|
521
|
+
return useSecureCookie(event, options.transactionCookieSecure) ? "none" : "lax";
|
|
640
522
|
}
|
|
641
523
|
function getTransactionCookieSecret(provider, options) {
|
|
642
|
-
|
|
643
|
-
|
|
524
|
+
const secret = options.transactionCookieSecret ?? provider.clientSecret;
|
|
525
|
+
return secret && secret.length > 0 ? secret : void 0;
|
|
644
526
|
}
|
|
645
527
|
function bytesToBase64Url(bytes) {
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
}
|
|
650
|
-
return btoa(binary).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/u, "");
|
|
528
|
+
let binary = "";
|
|
529
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
530
|
+
return btoa(binary).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/u, "");
|
|
651
531
|
}
|
|
652
532
|
async function signTransactionPayload(payload, secret) {
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
);
|
|
660
|
-
const signature = await crypto.subtle.sign(
|
|
661
|
-
"HMAC",
|
|
662
|
-
key,
|
|
663
|
-
new TextEncoder().encode(payload)
|
|
664
|
-
);
|
|
665
|
-
return bytesToBase64Url(new Uint8Array(signature));
|
|
533
|
+
const key = await crypto.subtle.importKey("raw", new TextEncoder().encode(secret), {
|
|
534
|
+
hash: "SHA-256",
|
|
535
|
+
name: "HMAC"
|
|
536
|
+
}, false, ["sign"]);
|
|
537
|
+
const signature = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(payload));
|
|
538
|
+
return bytesToBase64Url(new Uint8Array(signature));
|
|
666
539
|
}
|
|
667
540
|
function timingSafeEqual(left, right) {
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
}
|
|
675
|
-
return diff === 0;
|
|
541
|
+
const leftBytes = new TextEncoder().encode(left);
|
|
542
|
+
const rightBytes = new TextEncoder().encode(right);
|
|
543
|
+
let diff = leftBytes.length ^ rightBytes.length;
|
|
544
|
+
const length = Math.max(leftBytes.length, rightBytes.length);
|
|
545
|
+
for (let index = 0; index < length; index += 1) diff |= (leftBytes[index] ?? 0) ^ (rightBytes[index] ?? 0);
|
|
546
|
+
return diff === 0;
|
|
676
547
|
}
|
|
677
548
|
async function encodeOidcTransactionCookie(transaction, secret) {
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
return `${payload}.${signature}`;
|
|
549
|
+
const payload = encodeOidcTransaction(transaction);
|
|
550
|
+
if (!secret) return payload;
|
|
551
|
+
return `${payload}.${await signTransactionPayload(payload, secret)}`;
|
|
682
552
|
}
|
|
683
553
|
async function decodeOidcTransactionCookie(value, secret) {
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
const signature = value.slice(separatorIndex + 1);
|
|
691
|
-
const expectedSignature = await signTransactionPayload(payload, secret);
|
|
692
|
-
if (!timingSafeEqual(signature, expectedSignature)) {
|
|
693
|
-
throw new OidcLoginError("Invalid OIDC login transaction signature.");
|
|
694
|
-
}
|
|
695
|
-
return decodeOidcTransaction(payload);
|
|
554
|
+
if (!secret) return decodeOidcTransaction(value);
|
|
555
|
+
const separatorIndex = value.lastIndexOf(".");
|
|
556
|
+
if (separatorIndex < 0) throw new OidcLoginError("Invalid OIDC login transaction signature.");
|
|
557
|
+
const payload = value.slice(0, separatorIndex);
|
|
558
|
+
if (!timingSafeEqual(value.slice(separatorIndex + 1), await signTransactionPayload(payload, secret))) throw new OidcLoginError("Invalid OIDC login transaction signature.");
|
|
559
|
+
return decodeOidcTransaction(payload);
|
|
696
560
|
}
|
|
697
561
|
function getTransactionTtl(options) {
|
|
698
|
-
|
|
562
|
+
return options.transactionTtl ?? getUsersOidcConfig().transactionTtl ?? 600;
|
|
699
563
|
}
|
|
700
564
|
async function resolveTenantId(result, event, options) {
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
}
|
|
704
|
-
return options.tenantId;
|
|
565
|
+
if (typeof options.tenantId === "function") return options.tenantId(result, event);
|
|
566
|
+
return options.tenantId;
|
|
705
567
|
}
|
|
706
568
|
function redirectResponse(location) {
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
569
|
+
return new Response(null, {
|
|
570
|
+
headers: { location: location.toString() },
|
|
571
|
+
status: 303
|
|
572
|
+
});
|
|
711
573
|
}
|
|
712
574
|
function failureResponse(error) {
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
}
|
|
719
|
-
});
|
|
575
|
+
const message = error instanceof Error ? error.message : "OIDC login failed.";
|
|
576
|
+
return new Response(message, {
|
|
577
|
+
status: 401,
|
|
578
|
+
headers: { "content-type": "text/plain; charset=utf-8" }
|
|
579
|
+
});
|
|
720
580
|
}
|
|
721
581
|
function resolveSuccessRedirect(result, event, options) {
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
}
|
|
725
|
-
return options.successRedirect ?? result.returnTo ?? "/";
|
|
582
|
+
if (typeof options.successRedirect === "function") return options.successRedirect(result, event);
|
|
583
|
+
return options.successRedirect ?? result.returnTo ?? "/";
|
|
726
584
|
}
|
|
727
585
|
function resolveFailureRedirect(error, event, options) {
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
}
|
|
732
|
-
return options.failureRedirect;
|
|
586
|
+
if (!options.failureRedirect) return void 0;
|
|
587
|
+
if (typeof options.failureRedirect === "function") return options.failureRedirect(error, event);
|
|
588
|
+
return options.failureRedirect;
|
|
733
589
|
}
|
|
734
590
|
async function beginOidcLogin(event, options) {
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
}
|
|
751
|
-
);
|
|
752
|
-
return {
|
|
753
|
-
providerName: service.providerName,
|
|
754
|
-
transaction,
|
|
755
|
-
url: result.url
|
|
756
|
-
};
|
|
591
|
+
const service = createOidcService(event, options);
|
|
592
|
+
const transaction = service.createTransaction(getReturnTo(event, options));
|
|
593
|
+
const result = await service.createAuthorizationUrl({ transaction });
|
|
594
|
+
event.cookies.set(getOidcTransactionCookieName(service.providerName, options), await encodeOidcTransactionCookie(transaction, getTransactionCookieSecret(service.provider, options)), {
|
|
595
|
+
httpOnly: true,
|
|
596
|
+
maxAge: getTransactionTtl(options),
|
|
597
|
+
path: options.transactionCookiePath ?? "/",
|
|
598
|
+
sameSite: getTransactionCookieSameSite(event, options),
|
|
599
|
+
secure: useSecureCookie(event, options.transactionCookieSecure)
|
|
600
|
+
});
|
|
601
|
+
return {
|
|
602
|
+
providerName: service.providerName,
|
|
603
|
+
transaction,
|
|
604
|
+
url: result.url
|
|
605
|
+
};
|
|
757
606
|
}
|
|
758
607
|
async function completeOidcLogin(event, options) {
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
},
|
|
798
|
-
ipAddress: event.getClientAddress?.(),
|
|
799
|
-
ttl: options.sessionTtl,
|
|
800
|
-
userAgent: event.request.headers.get("user-agent") ?? void 0
|
|
801
|
-
}
|
|
802
|
-
);
|
|
803
|
-
return {
|
|
804
|
-
...result,
|
|
805
|
-
providerName: service.providerName,
|
|
806
|
-
returnTo: transaction.returnTo,
|
|
807
|
-
sessionId
|
|
808
|
-
};
|
|
809
|
-
} finally {
|
|
810
|
-
event.cookies.delete(cookieName, { path: cookiePath });
|
|
811
|
-
}
|
|
608
|
+
const service = createOidcService(event, options);
|
|
609
|
+
const cookieName = getOidcTransactionCookieName(service.providerName, options);
|
|
610
|
+
const cookiePath = options.transactionCookiePath ?? "/";
|
|
611
|
+
try {
|
|
612
|
+
const rawTransaction = event.cookies.get(cookieName);
|
|
613
|
+
if (!rawTransaction) throw new OidcLoginError("Missing OIDC login transaction cookie.");
|
|
614
|
+
const decodedTransaction = await decodeOidcTransactionCookie(rawTransaction, getTransactionCookieSecret(service.provider, options));
|
|
615
|
+
const transaction = {
|
|
616
|
+
...decodedTransaction,
|
|
617
|
+
returnTo: getLocalReturnTo(decodedTransaction.returnTo)
|
|
618
|
+
};
|
|
619
|
+
const ttl = getTransactionTtl(options);
|
|
620
|
+
if (Date.now() - transaction.createdAt > ttl * 1e3) throw new OidcLoginError("OIDC login transaction has expired.");
|
|
621
|
+
const result = await service.completeLogin(event.url, transaction);
|
|
622
|
+
const tenantId = await resolveTenantId(result, event, options);
|
|
623
|
+
const sessionId = await createSessionCookie(event, result.user.id, tenantId ?? void 0, {
|
|
624
|
+
...options,
|
|
625
|
+
cookieName: options.sessionCookieName,
|
|
626
|
+
cookiePath: options.sessionCookiePath,
|
|
627
|
+
cookieSameSite: options.sessionCookieSameSite,
|
|
628
|
+
cookieSecure: useSecureCookie(event, options.sessionCookieSecure),
|
|
629
|
+
data: {
|
|
630
|
+
oidcIssuer: result.claims.iss,
|
|
631
|
+
oidcProvider: service.providerName
|
|
632
|
+
},
|
|
633
|
+
ipAddress: event.getClientAddress?.(),
|
|
634
|
+
ttl: options.sessionTtl,
|
|
635
|
+
userAgent: event.request.headers.get("user-agent") ?? void 0
|
|
636
|
+
});
|
|
637
|
+
return {
|
|
638
|
+
...result,
|
|
639
|
+
providerName: service.providerName,
|
|
640
|
+
returnTo: transaction.returnTo,
|
|
641
|
+
sessionId
|
|
642
|
+
};
|
|
643
|
+
} finally {
|
|
644
|
+
event.cookies.delete(cookieName, { path: cookiePath });
|
|
645
|
+
}
|
|
812
646
|
}
|
|
813
647
|
function createOidcLoginHandler(options) {
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
648
|
+
return async (event) => {
|
|
649
|
+
const { url } = await beginOidcLogin(event, options);
|
|
650
|
+
return redirectResponse(url);
|
|
651
|
+
};
|
|
818
652
|
}
|
|
819
653
|
function createOidcCallbackHandler(options) {
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
}
|
|
832
|
-
const terminalAuthServiceCache = /* @__PURE__ */ new Map();
|
|
654
|
+
return async (event) => {
|
|
655
|
+
try {
|
|
656
|
+
return redirectResponse(await resolveSuccessRedirect(await completeOidcLogin(event, options), event, options));
|
|
657
|
+
} catch (error) {
|
|
658
|
+
const failureRedirect = resolveFailureRedirect(error, event, options);
|
|
659
|
+
if (failureRedirect) return redirectResponse(failureRedirect);
|
|
660
|
+
return failureResponse(error);
|
|
661
|
+
}
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
var terminalAuthServiceCache = /* @__PURE__ */ new Map();
|
|
833
665
|
function terminalAuthCacheKey(options) {
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
666
|
+
return JSON.stringify({
|
|
667
|
+
db: options.db,
|
|
668
|
+
cookie: options.sessionCookieName,
|
|
669
|
+
prefix: options.userCodePrefix,
|
|
670
|
+
reqTtl: options.requestTtlSeconds,
|
|
671
|
+
sessTtl: options.sessionTtlSeconds,
|
|
672
|
+
poll: options.pollIntervalSeconds,
|
|
673
|
+
path: options.verificationPath,
|
|
674
|
+
autoExtend: options.sessionAutoExtend,
|
|
675
|
+
maxAttempts: options.maxApproveAttempts,
|
|
676
|
+
attemptWindow: options.approveAttemptWindowSeconds
|
|
677
|
+
});
|
|
846
678
|
}
|
|
847
679
|
async function getOrCreateTerminalAuthService(options) {
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
680
|
+
const key = terminalAuthCacheKey(options);
|
|
681
|
+
let service = terminalAuthServiceCache.get(key);
|
|
682
|
+
if (!service) {
|
|
683
|
+
service = await TerminalAuthService.create(options);
|
|
684
|
+
terminalAuthServiceCache.set(key, service);
|
|
685
|
+
}
|
|
686
|
+
return service;
|
|
855
687
|
}
|
|
856
688
|
function parseBearerToken(authorization) {
|
|
857
|
-
|
|
858
|
-
return match?.[1]?.trim() || null;
|
|
689
|
+
return (authorization?.match(/^Bearer\s+(.+)$/iu))?.[1]?.trim() || null;
|
|
859
690
|
}
|
|
860
691
|
function createTerminalAuthStartHandler(options) {
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
};
|
|
692
|
+
return async (event) => {
|
|
693
|
+
const service = await getOrCreateTerminalAuthService(options);
|
|
694
|
+
const origin = typeof options.verificationOrigin === "function" ? options.verificationOrigin(event) : options.verificationOrigin ?? event.url.origin;
|
|
695
|
+
return jsonResponse(await service.createRequest(origin), 201, NO_STORE_HEADERS);
|
|
696
|
+
};
|
|
867
697
|
}
|
|
868
698
|
function createTerminalAuthTokenHandler(options) {
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
const service = await getOrCreateTerminalAuthService(options);
|
|
876
|
-
const result = await service.exchangeDeviceCode(deviceCode);
|
|
877
|
-
return jsonResponse(result, 200, NO_STORE_HEADERS);
|
|
878
|
-
};
|
|
699
|
+
return async (event) => {
|
|
700
|
+
const body = await event.request.json().catch(() => null);
|
|
701
|
+
const deviceCode = typeof body?.deviceCode === "string" ? body.deviceCode.trim() : "";
|
|
702
|
+
if (!deviceCode) return jsonResponse({ error: "deviceCode is required." }, 400);
|
|
703
|
+
return jsonResponse(await (await getOrCreateTerminalAuthService(options)).exchangeDeviceCode(deviceCode), 200, NO_STORE_HEADERS);
|
|
704
|
+
};
|
|
879
705
|
}
|
|
880
706
|
function createBearerSessionDeleteHandler(options) {
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
}
|
|
891
|
-
return jsonResponse({ authenticated: false });
|
|
892
|
-
};
|
|
707
|
+
return async (event) => {
|
|
708
|
+
const token = parseBearerToken(event.request.headers.get("authorization"));
|
|
709
|
+
if (token) try {
|
|
710
|
+
await (await getOrCreateTerminalAuthService(options)).destroyBearerSession(token);
|
|
711
|
+
} catch (error) {
|
|
712
|
+
logger.error("Terminal bearer session revocation error", { error });
|
|
713
|
+
}
|
|
714
|
+
return jsonResponse({ authenticated: false });
|
|
715
|
+
};
|
|
893
716
|
}
|
|
894
717
|
async function loadBearerSessionContext(token, options) {
|
|
895
|
-
|
|
896
|
-
return service.loadBearerSession(token);
|
|
718
|
+
return (await getOrCreateTerminalAuthService(options)).loadBearerSession(token);
|
|
897
719
|
}
|
|
898
720
|
function mountTerminalLoginPage(options) {
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
}
|
|
972
|
-
};
|
|
721
|
+
const codeParam = options.codeQueryParam ?? "code";
|
|
722
|
+
return {
|
|
723
|
+
load: async (event) => {
|
|
724
|
+
const userCode = event.url.searchParams.get(codeParam)?.trim().toUpperCase() ?? "";
|
|
725
|
+
let requestStatus = null;
|
|
726
|
+
if (userCode) requestStatus = (await (await getOrCreateTerminalAuthService(options)).getRequestForUserCode(userCode))?.status ?? null;
|
|
727
|
+
return {
|
|
728
|
+
requestStatus,
|
|
729
|
+
userCode
|
|
730
|
+
};
|
|
731
|
+
},
|
|
732
|
+
approve: async (event) => {
|
|
733
|
+
const userCode = (await event.request.formData()).get("userCode")?.toString().trim().toUpperCase() ?? "";
|
|
734
|
+
if (!userCode) return {
|
|
735
|
+
type: "failure",
|
|
736
|
+
status: 400,
|
|
737
|
+
data: {
|
|
738
|
+
status: 400,
|
|
739
|
+
error: "Enter a terminal login code.",
|
|
740
|
+
userCode
|
|
741
|
+
}
|
|
742
|
+
};
|
|
743
|
+
const user = options.resolveUser(event);
|
|
744
|
+
const tenantId = options.resolveTenantId(event);
|
|
745
|
+
if (!user?.id) return {
|
|
746
|
+
type: "failure",
|
|
747
|
+
status: 401,
|
|
748
|
+
data: {
|
|
749
|
+
status: 401,
|
|
750
|
+
error: "Sign in before approving terminal access.",
|
|
751
|
+
userCode
|
|
752
|
+
}
|
|
753
|
+
};
|
|
754
|
+
try {
|
|
755
|
+
const service = await getOrCreateTerminalAuthService(options);
|
|
756
|
+
const approveInput = {
|
|
757
|
+
ipAddress: event.getClientAddress?.(),
|
|
758
|
+
tenantId: tenantId ?? null,
|
|
759
|
+
user: {
|
|
760
|
+
email: user.email ?? "",
|
|
761
|
+
id: user.id
|
|
762
|
+
},
|
|
763
|
+
userAgent: event.request.headers.get("user-agent") ?? void 0,
|
|
764
|
+
userCode
|
|
765
|
+
};
|
|
766
|
+
return {
|
|
767
|
+
approved: true,
|
|
768
|
+
requestStatus: (await service.approveRequest(approveInput)).status,
|
|
769
|
+
userCode
|
|
770
|
+
};
|
|
771
|
+
} catch (error) {
|
|
772
|
+
if (error instanceof TerminalAuthRateLimitError) return {
|
|
773
|
+
type: "failure",
|
|
774
|
+
status: 429,
|
|
775
|
+
data: {
|
|
776
|
+
status: 429,
|
|
777
|
+
error: error.message,
|
|
778
|
+
userCode
|
|
779
|
+
}
|
|
780
|
+
};
|
|
781
|
+
return {
|
|
782
|
+
type: "failure",
|
|
783
|
+
status: 400,
|
|
784
|
+
data: {
|
|
785
|
+
status: 400,
|
|
786
|
+
error: error instanceof TerminalAuthError ? error.message : error instanceof Error ? error.message : "Unable to approve terminal login.",
|
|
787
|
+
userCode
|
|
788
|
+
}
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
};
|
|
973
793
|
}
|
|
974
794
|
function jsonResponse(body, status = 200, extraHeaders) {
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
TerminalAuthError,
|
|
987
|
-
TerminalAuthRateLimitError,
|
|
988
|
-
TerminalAuthService,
|
|
989
|
-
beginOidcLogin,
|
|
990
|
-
completeOidcLogin,
|
|
991
|
-
createBearerSessionDeleteHandler,
|
|
992
|
-
createOidcCallbackHandler,
|
|
993
|
-
createOidcLoginHandler,
|
|
994
|
-
createResourceListHandler,
|
|
995
|
-
createSessionCookie,
|
|
996
|
-
createSessionHandler,
|
|
997
|
-
createTerminalAuthStartHandler,
|
|
998
|
-
createTerminalAuthTokenHandler,
|
|
999
|
-
defaultSessionLocals,
|
|
1000
|
-
destroySessionCookie,
|
|
1001
|
-
loadBearerSessionContext,
|
|
1002
|
-
mountTerminalLoginPage,
|
|
1003
|
-
parseBearerToken,
|
|
1004
|
-
switchSessionTenant
|
|
795
|
+
return new Response(JSON.stringify(body), {
|
|
796
|
+
status,
|
|
797
|
+
headers: {
|
|
798
|
+
"content-type": "application/json",
|
|
799
|
+
...extraHeaders
|
|
800
|
+
}
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
var NO_STORE_HEADERS = {
|
|
804
|
+
"cache-control": "private, no-store",
|
|
805
|
+
pragma: "no-cache"
|
|
1005
806
|
};
|
|
1006
|
-
//#
|
|
807
|
+
//#endregion
|
|
808
|
+
export { InvalidBearerError, TerminalAuthError, TerminalAuthRateLimitError, TerminalAuthService, beginOidcLogin, completeOidcLogin, createBearerSessionDeleteHandler, createOidcCallbackHandler, createOidcLoginHandler, createResourceListHandler, createSessionCookie, createSessionHandler, createTerminalAuthStartHandler, createTerminalAuthTokenHandler, defaultSessionLocals, destroySessionCookie, loadBearerSessionContext, mountTerminalLoginPage, parseBearerToken, switchSessionTenant };
|
|
809
|
+
|
|
810
|
+
//# sourceMappingURL=sveltekit.js.map
|