@ghostly-solutions/auth 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -84
- package/dist/{auth-client-CAHMjodm.d.ts → auth-client-Cdkp07ii.d.ts} +14 -6
- package/dist/{auth-sdk-error-DKM7PyKC.d.ts → auth-sdk-error-D3gsfK9d.d.ts} +0 -3
- package/dist/extension.d.ts +16 -0
- package/dist/extension.js +502 -0
- package/dist/extension.js.map +1 -0
- package/dist/index.d.ts +12 -19
- package/dist/index.js +105 -119
- package/dist/index.js.map +1 -1
- package/dist/next.d.ts +4 -27
- package/dist/next.js +125 -383
- package/dist/next.js.map +1 -1
- package/dist/react.d.ts +4 -20
- package/dist/react.js +129 -176
- package/dist/react.js.map +1 -1
- package/docs/api-reference.md +65 -89
- package/docs/architecture.md +28 -46
- package/docs/development-and-ci.md +15 -19
- package/docs/index.md +1 -15
- package/docs/integration-guide.md +46 -81
- package/docs/overview.md +24 -30
- package/package.json +8 -2
package/dist/index.js
CHANGED
|
@@ -1,33 +1,26 @@
|
|
|
1
1
|
// src/constants/auth-endpoints.ts
|
|
2
|
-
var authApiPrefix = "/
|
|
2
|
+
var authApiPrefix = "/oauth";
|
|
3
3
|
var authEndpoints = {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
session: `${authApiPrefix}/
|
|
4
|
+
authorize: `${authApiPrefix}/authorize`,
|
|
5
|
+
providerCallback: `${authApiPrefix}/callback/provider`,
|
|
6
|
+
session: `${authApiPrefix}/session`,
|
|
7
|
+
refresh: `${authApiPrefix}/refresh`,
|
|
7
8
|
logout: `${authApiPrefix}/logout`
|
|
8
9
|
};
|
|
9
10
|
|
|
10
11
|
// src/constants/auth-keys.ts
|
|
11
|
-
var authQueryKeys = {
|
|
12
|
-
token: "token"
|
|
13
|
-
};
|
|
14
|
-
var authStorageKeys = {
|
|
15
|
-
returnTo: "ghostly-auth:return-to"
|
|
16
|
-
};
|
|
17
12
|
var authBroadcast = {
|
|
18
13
|
channelName: "ghostly-auth-channel",
|
|
19
14
|
sessionUpdatedEvent: "session-updated"
|
|
20
15
|
};
|
|
21
16
|
var authRoutes = {
|
|
22
|
-
root: "/"
|
|
23
|
-
callback: "/auth/callback"
|
|
17
|
+
root: "/"
|
|
24
18
|
};
|
|
25
19
|
|
|
26
20
|
// src/constants/http-status.ts
|
|
27
21
|
var httpStatus = {
|
|
28
22
|
ok: 200,
|
|
29
23
|
noContent: 204,
|
|
30
|
-
badRequest: 400,
|
|
31
24
|
unauthorized: 401
|
|
32
25
|
};
|
|
33
26
|
|
|
@@ -47,9 +40,6 @@ var AuthSdkError = class extends Error {
|
|
|
47
40
|
|
|
48
41
|
// src/types/auth-error-code.ts
|
|
49
42
|
var authErrorCode = {
|
|
50
|
-
callbackMissingToken: "callback_missing_token",
|
|
51
|
-
callbackInvalidToken: "callback_invalid_token",
|
|
52
|
-
callbackValidationFailed: "callback_validation_failed",
|
|
53
43
|
unauthorized: "unauthorized",
|
|
54
44
|
networkError: "network_error",
|
|
55
45
|
apiError: "api_error",
|
|
@@ -57,6 +47,46 @@ var authErrorCode = {
|
|
|
57
47
|
serverOriginResolutionFailed: "server_origin_resolution_failed"
|
|
58
48
|
};
|
|
59
49
|
|
|
50
|
+
// src/core/api-origin.ts
|
|
51
|
+
var slash = "/";
|
|
52
|
+
function normalizeApiOrigin(apiOrigin) {
|
|
53
|
+
const trimmed = apiOrigin.trim();
|
|
54
|
+
if (!trimmed) {
|
|
55
|
+
throw new AuthSdkError({
|
|
56
|
+
code: authErrorCode.apiError,
|
|
57
|
+
details: null,
|
|
58
|
+
message: "Auth API origin must be a non-empty absolute URL.",
|
|
59
|
+
status: null
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
let parsed;
|
|
63
|
+
try {
|
|
64
|
+
parsed = new URL(trimmed);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
throw new AuthSdkError({
|
|
67
|
+
code: authErrorCode.apiError,
|
|
68
|
+
details: error,
|
|
69
|
+
message: "Auth API origin must be a valid absolute URL.",
|
|
70
|
+
status: null
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
if (parsed.pathname !== slash || parsed.search || parsed.hash) {
|
|
74
|
+
throw new AuthSdkError({
|
|
75
|
+
code: authErrorCode.apiError,
|
|
76
|
+
details: null,
|
|
77
|
+
message: "Auth API origin must not include path, query, or hash.",
|
|
78
|
+
status: null
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return parsed.origin;
|
|
82
|
+
}
|
|
83
|
+
function resolveApiEndpoint(path, apiOrigin) {
|
|
84
|
+
if (!apiOrigin) {
|
|
85
|
+
return path;
|
|
86
|
+
}
|
|
87
|
+
return `${normalizeApiOrigin(apiOrigin)}${path}`;
|
|
88
|
+
}
|
|
89
|
+
|
|
60
90
|
// src/core/object-guards.ts
|
|
61
91
|
function isObjectRecord(value) {
|
|
62
92
|
return typeof value === "object" && value !== null;
|
|
@@ -125,19 +155,6 @@ function createBroadcastSync(options) {
|
|
|
125
155
|
};
|
|
126
156
|
}
|
|
127
157
|
|
|
128
|
-
// src/core/callback-url.ts
|
|
129
|
-
function readCallbackToken(url) {
|
|
130
|
-
return url.searchParams.get(authQueryKeys.token);
|
|
131
|
-
}
|
|
132
|
-
function removeCallbackToken(url) {
|
|
133
|
-
const nextUrl = new URL(url.toString());
|
|
134
|
-
nextUrl.searchParams.delete(authQueryKeys.token);
|
|
135
|
-
return nextUrl;
|
|
136
|
-
}
|
|
137
|
-
function replaceBrowserHistory(url) {
|
|
138
|
-
window.history.replaceState(null, "", url.toString());
|
|
139
|
-
}
|
|
140
|
-
|
|
141
158
|
// src/core/http-client.ts
|
|
142
159
|
var jsonContentType = "application/json";
|
|
143
160
|
var jsonHeaderName = "content-type";
|
|
@@ -233,9 +250,8 @@ function getJson(path) {
|
|
|
233
250
|
path
|
|
234
251
|
});
|
|
235
252
|
}
|
|
236
|
-
function
|
|
253
|
+
function postJsonWithoutBody(path) {
|
|
237
254
|
return request({
|
|
238
|
-
body,
|
|
239
255
|
method: "POST",
|
|
240
256
|
path
|
|
241
257
|
});
|
|
@@ -282,18 +298,10 @@ function sanitizeReturnTo(value) {
|
|
|
282
298
|
function getCurrentBrowserPath() {
|
|
283
299
|
return `${window.location.pathname}${window.location.search}${window.location.hash}`;
|
|
284
300
|
}
|
|
285
|
-
function
|
|
301
|
+
function resolveReturnToPath(returnTo) {
|
|
286
302
|
assertBrowserRuntime();
|
|
287
303
|
const fallbackPath = getCurrentBrowserPath();
|
|
288
|
-
|
|
289
|
-
window.sessionStorage.setItem(authStorageKeys.returnTo, sanitized);
|
|
290
|
-
return sanitized;
|
|
291
|
-
}
|
|
292
|
-
function consumeReturnToPath() {
|
|
293
|
-
assertBrowserRuntime();
|
|
294
|
-
const value = window.sessionStorage.getItem(authStorageKeys.returnTo);
|
|
295
|
-
window.sessionStorage.removeItem(authStorageKeys.returnTo);
|
|
296
|
-
return sanitizeReturnTo(value);
|
|
304
|
+
return sanitizeReturnTo(returnTo ?? fallbackPath);
|
|
297
305
|
}
|
|
298
306
|
|
|
299
307
|
// src/core/session-store.ts
|
|
@@ -326,10 +334,6 @@ var SessionStore = class {
|
|
|
326
334
|
};
|
|
327
335
|
|
|
328
336
|
// src/core/auth-client.ts
|
|
329
|
-
function createPendingRedirectPromise() {
|
|
330
|
-
return new Promise(() => {
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
337
|
function createInvalidSessionPayloadError(path) {
|
|
334
338
|
return new AuthSdkError({
|
|
335
339
|
code: authErrorCode.apiError,
|
|
@@ -344,29 +348,11 @@ function toValidatedSession(payload, path) {
|
|
|
344
348
|
}
|
|
345
349
|
return payload;
|
|
346
350
|
}
|
|
347
|
-
function
|
|
348
|
-
if (
|
|
349
|
-
|
|
350
|
-
return new AuthSdkError({
|
|
351
|
-
code: authErrorCode.callbackInvalidToken,
|
|
352
|
-
details: error.details,
|
|
353
|
-
message: "Callback JWT is invalid or expired.",
|
|
354
|
-
status: error.status
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
return new AuthSdkError({
|
|
358
|
-
code: authErrorCode.callbackValidationFailed,
|
|
359
|
-
details: error.details,
|
|
360
|
-
message: "Keycloak callback validation failed.",
|
|
361
|
-
status: error.status
|
|
362
|
-
});
|
|
351
|
+
function toSessionPayload(payload, path) {
|
|
352
|
+
if (payload === null) {
|
|
353
|
+
return null;
|
|
363
354
|
}
|
|
364
|
-
return
|
|
365
|
-
code: authErrorCode.callbackValidationFailed,
|
|
366
|
-
details: error,
|
|
367
|
-
message: "Keycloak callback validation failed.",
|
|
368
|
-
status: null
|
|
369
|
-
});
|
|
355
|
+
return toValidatedSession(payload, path);
|
|
370
356
|
}
|
|
371
357
|
function createNoopBroadcastSync() {
|
|
372
358
|
return {
|
|
@@ -388,25 +374,53 @@ function createSafeBroadcastSync(onSessionUpdated) {
|
|
|
388
374
|
throw error;
|
|
389
375
|
}
|
|
390
376
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
}
|
|
396
|
-
return toValidatedSession(payload, authEndpoints.session);
|
|
377
|
+
function toInitResult(session) {
|
|
378
|
+
return {
|
|
379
|
+
session,
|
|
380
|
+
status: session ? "authenticated" : "unauthenticated"
|
|
381
|
+
};
|
|
397
382
|
}
|
|
398
|
-
function createAuthClient() {
|
|
399
|
-
|
|
383
|
+
function createAuthClient(options = {}) {
|
|
384
|
+
let initPromise = null;
|
|
385
|
+
const defaultApplication = options.application?.trim() || "";
|
|
400
386
|
const sessionStore = new SessionStore();
|
|
401
387
|
const broadcastSync = createSafeBroadcastSync((session) => {
|
|
402
388
|
sessionStore.setSession(session);
|
|
403
389
|
});
|
|
404
|
-
const
|
|
405
|
-
|
|
390
|
+
const resolveEndpoint = (path) => resolveApiEndpoint(path, options.apiOrigin);
|
|
391
|
+
const loadSession = async () => {
|
|
392
|
+
const payload = await getJson(resolveEndpoint(authEndpoints.session));
|
|
393
|
+
return toSessionPayload(payload, authEndpoints.session);
|
|
394
|
+
};
|
|
395
|
+
const init = async (initOptions) => {
|
|
396
|
+
const forceRefresh = initOptions?.forceRefresh ?? false;
|
|
406
397
|
if (sessionStore.hasResolvedSession() && !forceRefresh) {
|
|
407
|
-
return sessionStore.getSessionIfResolved();
|
|
398
|
+
return toInitResult(sessionStore.getSessionIfResolved());
|
|
408
399
|
}
|
|
409
|
-
|
|
400
|
+
if (initPromise) {
|
|
401
|
+
return initPromise;
|
|
402
|
+
}
|
|
403
|
+
initPromise = (async () => {
|
|
404
|
+
const session = await loadSession();
|
|
405
|
+
sessionStore.setSession(session);
|
|
406
|
+
broadcastSync.publishSession(session);
|
|
407
|
+
return toInitResult(session);
|
|
408
|
+
})();
|
|
409
|
+
try {
|
|
410
|
+
return await initPromise;
|
|
411
|
+
} finally {
|
|
412
|
+
initPromise = null;
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
const getSession = async (requestOptions) => {
|
|
416
|
+
const result = await init({
|
|
417
|
+
forceRefresh: requestOptions?.forceRefresh ?? false
|
|
418
|
+
});
|
|
419
|
+
return result.session;
|
|
420
|
+
};
|
|
421
|
+
const refresh = async () => {
|
|
422
|
+
const payload = await postJsonWithoutBody(resolveEndpoint(authEndpoints.refresh));
|
|
423
|
+
const session = toSessionPayload(payload, authEndpoints.refresh);
|
|
410
424
|
sessionStore.setSession(session);
|
|
411
425
|
broadcastSync.publishSession(session);
|
|
412
426
|
return session;
|
|
@@ -423,61 +437,33 @@ function createAuthClient() {
|
|
|
423
437
|
status: httpStatus.unauthorized
|
|
424
438
|
});
|
|
425
439
|
};
|
|
426
|
-
const login = (
|
|
427
|
-
|
|
428
|
-
window.location.
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
if (!token) {
|
|
434
|
-
throw new AuthSdkError({
|
|
435
|
-
code: authErrorCode.callbackMissingToken,
|
|
436
|
-
details: null,
|
|
437
|
-
message: "Missing callback token query parameter.",
|
|
438
|
-
status: httpStatus.badRequest
|
|
439
|
-
});
|
|
440
|
+
const login = (loginOptions) => {
|
|
441
|
+
const returnTo = resolveReturnToPath(loginOptions?.returnTo);
|
|
442
|
+
const authorizeUrl = new URL(resolveEndpoint(authEndpoints.authorize), window.location.origin);
|
|
443
|
+
authorizeUrl.searchParams.set("return_to", returnTo);
|
|
444
|
+
const application = loginOptions?.application?.trim() || defaultApplication;
|
|
445
|
+
if (application) {
|
|
446
|
+
authorizeUrl.searchParams.set("app", application);
|
|
440
447
|
}
|
|
441
|
-
|
|
442
|
-
replaceBrowserHistory(cleanedUrl);
|
|
443
|
-
try {
|
|
444
|
-
const payload = await postJson(
|
|
445
|
-
authEndpoints.validateKeycloakToken,
|
|
446
|
-
{ token }
|
|
447
|
-
);
|
|
448
|
-
const session = toValidatedSession(payload.session, authEndpoints.validateKeycloakToken);
|
|
449
|
-
sessionStore.setSession(session);
|
|
450
|
-
broadcastSync.publishSession(session);
|
|
451
|
-
return {
|
|
452
|
-
redirectTo: consumeReturnToPath(),
|
|
453
|
-
session
|
|
454
|
-
};
|
|
455
|
-
} catch (error) {
|
|
456
|
-
throw toCallbackFailure(error);
|
|
457
|
-
}
|
|
458
|
-
};
|
|
459
|
-
const completeCallbackRedirect = async () => {
|
|
460
|
-
const result = await processCallback();
|
|
461
|
-
window.location.replace(result.redirectTo);
|
|
462
|
-
return createPendingRedirectPromise();
|
|
448
|
+
window.location.assign(authorizeUrl.toString());
|
|
463
449
|
};
|
|
464
450
|
const logout = async () => {
|
|
465
|
-
await postEmpty(authEndpoints.logout);
|
|
451
|
+
await postEmpty(resolveEndpoint(authEndpoints.logout));
|
|
466
452
|
sessionStore.setSession(null);
|
|
467
453
|
broadcastSync.publishSession(null);
|
|
468
454
|
};
|
|
469
455
|
const subscribe = sessionStore.subscribe.bind(sessionStore);
|
|
470
456
|
return {
|
|
471
|
-
|
|
457
|
+
init,
|
|
472
458
|
getSession,
|
|
473
459
|
login,
|
|
474
460
|
logout,
|
|
475
|
-
|
|
461
|
+
refresh,
|
|
476
462
|
requireSession,
|
|
477
463
|
subscribe
|
|
478
464
|
};
|
|
479
465
|
}
|
|
480
466
|
|
|
481
|
-
export { AuthSdkError, authEndpoints, authErrorCode,
|
|
467
|
+
export { AuthSdkError, authEndpoints, authErrorCode, authRoutes, createAuthClient };
|
|
482
468
|
//# sourceMappingURL=index.js.map
|
|
483
469
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants/auth-endpoints.ts","../src/constants/auth-keys.ts","../src/constants/http-status.ts","../src/errors/auth-sdk-error.ts","../src/types/auth-error-code.ts","../src/core/object-guards.ts","../src/core/session-parser.ts","../src/core/broadcast-sync.ts","../src/core/callback-url.ts","../src/core/http-client.ts","../src/core/runtime.ts","../src/core/return-to-storage.ts","../src/core/session-store.ts","../src/core/auth-client.ts"],"names":[],"mappings":";AAAA,IAAM,aAAA,GAAgB,UAAA;AAEf,IAAM,aAAA,GAAgB;AAAA,EAC3B,UAAA,EAAY,GAAG,aAAa,CAAA,eAAA,CAAA;AAAA,EAC5B,qBAAA,EAAuB,GAAG,aAAa,CAAA,kBAAA,CAAA;AAAA,EACvC,OAAA,EAAS,GAAG,aAAa,CAAA,GAAA,CAAA;AAAA,EACzB,MAAA,EAAQ,GAAG,aAAa,CAAA,OAAA;AAC1B;;;ACPO,IAAM,aAAA,GAAgB;AAAA,EAC3B,KAAA,EAAO;AACT;AAEO,IAAM,eAAA,GAAkB;AAAA,EAC7B,QAAA,EAAU;AACZ,CAAA;AAEO,IAAM,aAAA,GAAgB;AAAA,EAC3B,WAAA,EAAa,sBAAA;AAAA,EACb,mBAAA,EAAqB;AACvB,CAAA;AAEO,IAAM,UAAA,GAAa;AAAA,EACxB,IAAA,EAAM,GAAA;AAAA,EACN,QAAA,EAAU;AACZ;;;AChBO,IAAM,UAAA,GAAa;AAAA,EACxB,EAAA,EAAI,GAAA;AAAA,EAEJ,SAAA,EAAW,GAAA;AAAA,EACX,UAAA,EAAY,GAAA;AAAA,EACZ,YAAA,EAAc;AAChB,CAAA;;;ACGO,IAAM,YAAA,GAAN,cAA2B,KAAA,CAAM;AAAA,EAC7B,IAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EAET,YAAY,OAAA,EAA8B;AACxC,IAAA,KAAA,CAAM,QAAQ,OAAO,CAAA;AACrB,IAAA,IAAA,CAAK,IAAA,GAAO,cAAA;AACZ,IAAA,IAAA,CAAK,OAAO,OAAA,CAAQ,IAAA;AACpB,IAAA,IAAA,CAAK,UAAU,OAAA,CAAQ,OAAA;AACvB,IAAA,IAAA,CAAK,SAAS,OAAA,CAAQ,MAAA;AAAA,EACxB;AACF;;;ACrBO,IAAM,aAAA,GAAgB;AAAA,EAC3B,oBAAA,EAAsB,wBAAA;AAAA,EACtB,oBAAA,EAAsB,wBAAA;AAAA,EACtB,wBAAA,EAA0B,4BAAA;AAAA,EAC1B,YAAA,EAAc,cAAA;AAAA,EACd,YAAA,EAAc,eAAA;AAAA,EACd,QAAA,EAAU,WAAA;AAAA,EACV,2BAAA,EAA6B,+BAAA;AAAA,EAC7B,4BAAA,EAA8B;AAChC;;;ACTO,SAAS,eAAe,KAAA,EAAkD;AAC/E,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA;AAChD;AAEO,SAAS,cAAc,KAAA,EAAiC;AAC7D,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA;AAC1B;;;ACHO,SAAS,cAAc,KAAA,EAAmC;AAC/D,EAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,IAAK,KAAA,CAAM,MAAM,CAAC,KAAA,KAAU,aAAA,CAAc,KAAK,CAAC,CAAA;AAC5E;AAEO,SAAS,iBAAiB,KAAA,EAAyC;AACxE,EAAA,IAAI,CAAC,cAAA,CAAe,KAAK,CAAA,EAAG;AAC1B,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,OACE,aAAA,CAAc,KAAA,CAAM,EAAE,CAAA,IACtB,cAAc,KAAA,CAAM,QAAQ,CAAA,KAC3B,KAAA,CAAM,SAAA,KAAc,IAAA,IAAQ,aAAA,CAAc,KAAA,CAAM,SAAS,CAAA,CAAA,KACzD,KAAA,CAAM,QAAA,KAAa,IAAA,IAAQ,aAAA,CAAc,KAAA,CAAM,QAAQ,CAAA,CAAA,IACxD,cAAc,KAAA,CAAM,KAAK,CAAA,IACzB,aAAA,CAAc,KAAA,CAAM,IAAI,CAAA,IACxB,aAAA,CAAc,MAAM,WAAW,CAAA;AAEnC;;;ACAA,SAAS,wBAAwB,KAAA,EAAgD;AAC/E,EAAA,IAAI,CAAC,cAAA,CAAe,KAAK,CAAA,EAAG;AAC1B,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,IAAI,CAAC,aAAA,CAAc,KAAA,CAAM,IAAI,CAAA,EAAG;AAC9B,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,IAAI,KAAA,CAAM,IAAA,KAAS,aAAA,CAAc,mBAAA,EAAqB;AACpD,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,OAAO,KAAA,CAAM,OAAA,KAAY,IAAA,IAAQ,gBAAA,CAAiB,MAAM,OAAO,CAAA;AACjE;AAEA,SAAS,sCAAA,GAAuD;AAC9D,EAAA,OAAO,IAAI,YAAA,CAAa;AAAA,IACtB,MAAM,aAAA,CAAc,2BAAA;AAAA,IACpB,OAAA,EAAS,IAAA;AAAA,IACT,OAAA,EAAS,kDAAA;AAAA,IACT,MAAA,EAAQ;AAAA,GACT,CAAA;AACH;AAEO,SAAS,oBAAoB,OAAA,EAAoD;AACtF,EAAA,IAAI,OAAO,qBAAqB,WAAA,EAAa;AAC3C,IAAA,MAAM,sCAAA,EAAuC;AAAA,EAC/C;AAEA,EAAA,MAAM,OAAA,GAAU,IAAI,gBAAA,CAAiB,aAAA,CAAc,WAAW,CAAA;AAE9D,EAAA,MAAM,SAAA,GAA2B,CAAC,KAAA,KAAU;AAC1C,IAAA,MAAM,YAAA,GAAe,KAAA;AAErB,IAAA,IAAI,CAAC,uBAAA,CAAwB,YAAA,CAAa,IAAI,CAAA,EAAG;AAC/C,MAAA;AAAA,IACF;AAEA,IAAA,OAAA,CAAQ,gBAAA,CAAiB,YAAA,CAAa,IAAA,CAAK,OAAO,CAAA;AAAA,EACpD,CAAA;AAEA,EAAA,OAAA,CAAQ,gBAAA,CAAiB,WAAW,SAAS,CAAA;AAE7C,EAAA,OAAO;AAAA,IACL,KAAA,GAAQ;AACN,MAAA,OAAA,CAAQ,mBAAA,CAAoB,WAAW,SAAS,CAAA;AAChD,MAAA,OAAA,CAAQ,KAAA,EAAM;AAAA,IAChB,CAAA;AAAA,IACA,eAAe,OAAA,EAAS;AACtB,MAAA,MAAM,OAAA,GAAiC;AAAA,QACrC,OAAA;AAAA,QACA,MAAM,aAAA,CAAc;AAAA,OACtB;AAEA,MAAA,OAAA,CAAQ,YAAY,OAAO,CAAA;AAAA,IAC7B;AAAA,GACF;AACF;;;AC7EO,SAAS,kBAAkB,GAAA,EAAyB;AACzD,EAAA,OAAO,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,aAAA,CAAc,KAAK,CAAA;AACjD;AAEO,SAAS,oBAAoB,GAAA,EAAe;AACjD,EAAA,MAAM,OAAA,GAAU,IAAI,GAAA,CAAI,GAAA,CAAI,UAAU,CAAA;AACtC,EAAA,OAAA,CAAQ,YAAA,CAAa,MAAA,CAAO,aAAA,CAAc,KAAK,CAAA;AAC/C,EAAA,OAAO,OAAA;AACT;AAEO,SAAS,sBAAsB,GAAA,EAAgB;AACpD,EAAA,MAAA,CAAO,QAAQ,YAAA,CAAa,IAAA,EAAM,EAAA,EAAI,GAAA,CAAI,UAAU,CAAA;AACtD;;;ACTA,IAAM,eAAA,GAAkB,kBAAA;AACxB,IAAM,cAAA,GAAiB,cAAA;AACvB,IAAM,kBAAA,GAAyC,SAAA;AAC/C,IAAM,YAAA,GAA6B,UAAA;AAenC,SAAS,aAAqB,KAAA,EAAwB;AACpD,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,6BAA6B,MAAA,EAAgB;AACpD,EAAA,IAAI,MAAA,KAAW,WAAW,YAAA,EAAc;AACtC,IAAA,OAAO,aAAA,CAAc,YAAA;AAAA,EACvB;AAEA,EAAA,OAAO,aAAA,CAAc,QAAA;AACvB;AAEA,eAAe,iBAAiB,QAAA,EAAsC;AACpE,EAAA,IAAI;AACF,IAAA,OAAO,MAAM,SAAS,IAAA,EAAK;AAAA,EAC7B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEA,eAAe,kBAAkB,QAAA,EAAiD;AAChF,EAAA,MAAM,OAAA,GAAU,MAAM,gBAAA,CAAiB,QAAQ,CAAA;AAE/C,EAAA,IAAI,CAAC,cAAA,CAAe,OAAO,CAAA,EAAG;AAC5B,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,IAAA;AAAA,MACN,OAAA,EAAS,IAAA;AAAA,MACT,OAAA,EAAS;AAAA,KACX;AAAA,EACF;AAEA,EAAA,MAAM,YAAY,OAAA,CAAQ,IAAA;AAC1B,EAAA,MAAM,eAAe,OAAA,CAAQ,OAAA;AAE7B,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,aAAA,CAAc,SAAS,CAAA,GAAI,SAAA,GAAY,IAAA;AAAA,IAC7C,OAAA,EAAS,SAAA,IAAa,OAAA,GAAU,OAAA,CAAQ,OAAA,GAAU,IAAA;AAAA,IAClD,OAAA,EAAS,aAAA,CAAc,YAAY,CAAA,GAAI,YAAA,GAAe;AAAA,GACxD;AACF;AAEA,SAAS,oBAAA,CAAqB,QAA2C,IAAA,EAAsB;AAC7F,EAAA,OAAO,CAAA,yBAAA,EAA4B,MAAM,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA;AACnD;AAEA,SAAS,wBAAA,CAAyB,QAA2C,IAAA,EAAsB;AACjG,EAAA,OAAO,CAAA,0BAAA,EAA6B,MAAM,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA;AACpD;AAEA,eAAe,QACb,OAAA,EACoB;AACpB,EAAA,MAAM,cAAA,GAAiB,OAAA,CAAQ,cAAA,IAAkB,UAAA,CAAW,EAAA;AAC5D,EAAA,MAAM,OAAA,GAAU,IAAI,OAAA,EAAQ;AAC5B,EAAA,MAAM,OAAA,GAAU,OAAO,OAAA,CAAQ,IAAA,KAAS,WAAA;AAExC,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,OAAA,CAAQ,GAAA,CAAI,gBAAgB,eAAe,CAAA;AAAA,EAC7C;AAEA,EAAA,MAAM,WAAA,GAA2B;AAAA,IAC/B,KAAA,EAAO,YAAA;AAAA,IACP,WAAA,EAAa,kBAAA;AAAA,IACb,OAAA;AAAA,IACA,QAAQ,OAAA,CAAQ;AAAA,GAClB;AAEA,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,WAAA,CAAY,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,IAAI,CAAA;AAAA,EAChD;AAEA,EAAA,IAAI,QAAA;AAEJ,EAAA,IAAI;AACF,IAAA,QAAA,GAAW,MAAM,KAAA,CAAM,OAAA,CAAQ,IAAA,EAAM,WAAW,CAAA;AAAA,EAClD,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,IAAI,YAAA,CAAa;AAAA,MACrB,MAAM,aAAA,CAAc,YAAA;AAAA,MACpB,OAAA,EAAS,KAAA;AAAA,MACT,OAAA,EAAS,wBAAA,CAAyB,OAAA,CAAQ,MAAA,EAAQ,QAAQ,IAAI,CAAA;AAAA,MAC9D,MAAA,EAAQ;AAAA,KACT,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,QAAA,CAAS,WAAW,cAAA,EAAgB;AACtC,IAAA,MAAM,MAAA,GAAS,MAAM,iBAAA,CAAkB,QAAQ,CAAA;AAE/C,IAAA,MAAM,IAAI,YAAA,CAAa;AAAA,MACrB,IAAA,EAAM,4BAAA,CAA6B,QAAA,CAAS,MAAM,CAAA;AAAA,MAClD,OAAA,EAAS;AAAA,QACP,SAAS,MAAA,CAAO,IAAA;AAAA,QAChB,YAAY,MAAA,CAAO;AAAA,OACrB;AAAA,MACA,SAAS,MAAA,CAAO,OAAA,IAAW,qBAAqB,OAAA,CAAQ,MAAA,EAAQ,QAAQ,IAAI,CAAA;AAAA,MAC5E,QAAQ,QAAA,CAAS;AAAA,KAClB,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,QAAA,CAAS,MAAA,KAAW,UAAA,CAAW,SAAA,EAAW;AAC5C,IAAA,OAAO,aAAwB,IAAI,CAAA;AAAA,EACrC;AAEA,EAAA,MAAM,OAAA,GAAU,MAAM,gBAAA,CAAiB,QAAQ,CAAA;AAC/C,EAAA,OAAO,aAAwB,OAAO,CAAA;AACxC;AAEO,SAAS,QAAmB,IAAA,EAAkC;AACnE,EAAA,OAAO,OAAA,CAAmB;AAAA,IACxB,MAAA,EAAQ,KAAA;AAAA,IACR;AAAA,GACD,CAAA;AACH;AAEO,SAAS,QAAA,CAA2B,MAAc,IAAA,EAAiC;AACxF,EAAA,OAAO,OAAA,CAA0B;AAAA,IAC/B,IAAA;AAAA,IACA,MAAA,EAAQ,MAAA;AAAA,IACR;AAAA,GACD,CAAA;AACH;AAEO,SAAS,UAAU,IAAA,EAA6B;AACrD,EAAA,OAAO,OAAA,CAAc;AAAA,IACnB,gBAAgB,UAAA,CAAW,SAAA;AAAA,IAC3B,MAAA,EAAQ,MAAA;AAAA,IACR;AAAA,GACD,CAAA;AACH;;;ACnJA,IAAM,0BAAA,GAA6B,sDAAA;AAE5B,SAAS,gBAAA,GAA4B;AAC1C,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAC3B;AAEO,SAAS,oBAAA,GAA6B;AAC3C,EAAA,IAAI,kBAAiB,EAAG;AACtB,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,IAAI,YAAA,CAAa;AAAA,IACrB,MAAM,aAAA,CAAc,QAAA;AAAA,IACpB,OAAA,EAAS,IAAA;AAAA,IACT,OAAA,EAAS,0BAAA;AAAA,IACT,MAAA,EAAQ;AAAA,GACT,CAAA;AACH;;;ACjBA,SAAS,iBAAiB,KAAA,EAA0C;AAClE,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,OAAO,UAAA,CAAW,IAAA;AAAA,EACpB;AAEA,EAAA,IAAI,CAAC,KAAA,CAAM,UAAA,CAAW,UAAA,CAAW,IAAI,CAAA,EAAG;AACtC,IAAA,OAAO,UAAA,CAAW,IAAA;AAAA,EACpB;AAEA,EAAA,MAAM,sBAAA,GAAyB,IAAA;AAE/B,EAAA,IAAI,KAAA,CAAM,UAAA,CAAW,sBAAsB,CAAA,EAAG;AAC5C,IAAA,OAAO,UAAA,CAAW,IAAA;AAAA,EACpB;AAEA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,qBAAA,GAAgC;AACvC,EAAA,OAAO,CAAA,EAAG,MAAA,CAAO,QAAA,CAAS,QAAQ,CAAA,EAAG,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,EAAG,MAAA,CAAO,QAAA,CAAS,IAAI,CAAA,CAAA;AACpF;AAEO,SAAS,iBAAiB,QAAA,EAAsC;AACrE,EAAA,oBAAA,EAAqB;AAErB,EAAA,MAAM,eAAe,qBAAA,EAAsB;AAC3C,EAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,QAAA,IAAY,YAAY,CAAA;AAC3D,EAAA,MAAA,CAAO,cAAA,CAAe,OAAA,CAAQ,eAAA,CAAgB,QAAA,EAAU,SAAS,CAAA;AACjE,EAAA,OAAO,SAAA;AACT;AAEO,SAAS,mBAAA,GAA8B;AAC5C,EAAA,oBAAA,EAAqB;AAErB,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,cAAA,CAAe,OAAA,CAAQ,gBAAgB,QAAQ,CAAA;AACpE,EAAA,MAAA,CAAO,cAAA,CAAe,UAAA,CAAW,eAAA,CAAgB,QAAQ,CAAA;AACzD,EAAA,OAAO,iBAAiB,KAAK,CAAA;AAC/B;;;ACnCO,IAAM,eAAN,MAAmB;AAAA,EAChB,SAAA,uBAAgB,GAAA,EAAqB;AAAA,EACrC,eAAA,GAAyC,IAAA;AAAA,EACzC,YAAA,GAAoC,SAAA;AAAA,EAE5C,oBAAA,GAA8C;AAC5C,IAAA,IAAI,IAAA,CAAK,iBAAiB,SAAA,EAAW;AACnC,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,OAAO,IAAA,CAAK,eAAA;AAAA,EACd;AAAA,EAEA,kBAAA,GAA8B;AAC5B,IAAA,OAAO,KAAK,YAAA,KAAiB,UAAA;AAAA,EAC/B;AAAA,EAEA,WAAW,OAAA,EAAsC;AAC/C,IAAA,IAAA,CAAK,YAAA,GAAe,UAAA;AACpB,IAAA,IAAA,CAAK,eAAA,GAAkB,OAAA;AAEvB,IAAA,KAAA,MAAW,QAAA,IAAY,KAAK,SAAA,EAAW;AACrC,MAAA,QAAA,CAAS,OAAO,CAAA;AAAA,IAClB;AAAA,EACF;AAAA,EAEA,UAAU,QAAA,EAAuC;AAC/C,IAAA,IAAA,CAAK,SAAA,CAAU,IAAI,QAAQ,CAAA;AAE3B,IAAA,OAAO,MAAM;AACX,MAAA,IAAA,CAAK,SAAA,CAAU,OAAO,QAAQ,CAAA;AAAA,IAChC,CAAA;AAAA,EACF;AACF,CAAA;;;ACVA,SAAS,4BAAA,GAAwD;AAC/D,EAAA,OAAO,IAAI,QAAQ,MAAM;AAAA,EAEzB,CAAC,CAAA;AACH;AAEA,SAAS,iCAAiC,IAAA,EAA4B;AACpE,EAAA,OAAO,IAAI,YAAA,CAAa;AAAA,IACtB,MAAM,aAAA,CAAc,QAAA;AAAA,IACpB,OAAA,EAAS,IAAA;AAAA,IACT,OAAA,EAAS,gDAAgD,IAAI,CAAA,CAAA;AAAA,IAC7D,MAAA,EAAQ;AAAA,GACT,CAAA;AACH;AAEA,SAAS,kBAAA,CAAmB,SAAkB,IAAA,EAA8B;AAC1E,EAAA,IAAI,CAAC,gBAAA,CAAiB,OAAO,CAAA,EAAG;AAC9B,IAAA,MAAM,iCAAiC,IAAI,CAAA;AAAA,EAC7C;AAEA,EAAA,OAAO,OAAA;AACT;AAEA,SAAS,kBAAkB,KAAA,EAA8B;AACvD,EAAA,IAAI,iBAAiB,YAAA,EAAc;AACjC,IAAA,IAAI,KAAA,CAAM,MAAA,KAAW,UAAA,CAAW,YAAA,EAAc;AAC5C,MAAA,OAAO,IAAI,YAAA,CAAa;AAAA,QACtB,MAAM,aAAA,CAAc,oBAAA;AAAA,QACpB,SAAS,KAAA,CAAM,OAAA;AAAA,QACf,OAAA,EAAS,qCAAA;AAAA,QACT,QAAQ,KAAA,CAAM;AAAA,OACf,CAAA;AAAA,IACH;AAEA,IAAA,OAAO,IAAI,YAAA,CAAa;AAAA,MACtB,MAAM,aAAA,CAAc,wBAAA;AAAA,MACpB,SAAS,KAAA,CAAM,OAAA;AAAA,MACf,OAAA,EAAS,sCAAA;AAAA,MACT,QAAQ,KAAA,CAAM;AAAA,KACf,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,IAAI,YAAA,CAAa;AAAA,IACtB,MAAM,aAAA,CAAc,wBAAA;AAAA,IACpB,OAAA,EAAS,KAAA;AAAA,IACT,OAAA,EAAS,sCAAA;AAAA,IACT,MAAA,EAAQ;AAAA,GACT,CAAA;AACH;AAEA,SAAS,uBAAA,GAAyC;AAChD,EAAA,OAAO;AAAA,IACL,KAAA,GAAQ;AAAA,IAAC,CAAA;AAAA,IACT,cAAA,GAAiB;AAAA,IAAC;AAAA,GACpB;AACF;AAEA,SAAS,wBACP,gBAAA,EACe;AACf,EAAA,IAAI;AACF,IAAA,OAAO,mBAAA,CAAoB;AAAA,MACzB;AAAA,KACD,CAAA;AAAA,EACH,SAAS,KAAA,EAAO;AACd,IAAA,IAAI,KAAA,YAAiB,YAAA,IAAgB,KAAA,CAAM,IAAA,KAAS,cAAc,2BAAA,EAA6B;AAC7F,MAAA,OAAO,uBAAA,EAAwB;AAAA,IACjC;AAEA,IAAA,MAAM,KAAA;AAAA,EACR;AACF;AAEA,eAAe,0BAAA,GAA6D;AAC1E,EAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAiB,aAAA,CAAc,OAAO,CAAA;AAE5D,EAAA,IAAI,YAAY,IAAA,EAAM;AACpB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO,kBAAA,CAAmB,OAAA,EAAS,aAAA,CAAc,OAAO,CAAA;AAC1D;AAEO,SAAS,gBAAA,GAA+B;AAC7C,EAAA,oBAAA,EAAqB;AAErB,EAAA,MAAM,YAAA,GAAe,IAAI,YAAA,EAAa;AACtC,EAAA,MAAM,aAAA,GAAgB,uBAAA,CAAwB,CAAC,OAAA,KAAY;AACzD,IAAA,YAAA,CAAa,WAAW,OAAO,CAAA;AAAA,EACjC,CAAC,CAAA;AAED,EAAA,MAAM,UAAA,GAAa,OAAO,OAAA,KAAoE;AAC5F,IAAA,MAAM,YAAA,GAAe,SAAS,YAAA,IAAgB,KAAA;AAE9C,IAAA,IAAI,YAAA,CAAa,kBAAA,EAAmB,IAAK,CAAC,YAAA,EAAc;AACtD,MAAA,OAAO,aAAa,oBAAA,EAAqB;AAAA,IAC3C;AAEA,IAAA,MAAM,OAAA,GAAU,MAAM,0BAAA,EAA2B;AACjD,IAAA,YAAA,CAAa,WAAW,OAAO,CAAA;AAC/B,IAAA,aAAA,CAAc,eAAe,OAAO,CAAA;AAEpC,IAAA,OAAO,OAAA;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,iBAAiB,YAAqC;AAC1D,IAAA,MAAM,OAAA,GAAU,MAAM,UAAA,EAAW;AAEjC,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,OAAO,OAAA;AAAA,IACT;AAEA,IAAA,MAAM,IAAI,YAAA,CAAa;AAAA,MACrB,MAAM,aAAA,CAAc,YAAA;AAAA,MACpB,OAAA,EAAS,IAAA;AAAA,MACT,OAAA,EAAS,oCAAA;AAAA,MACT,QAAQ,UAAA,CAAW;AAAA,KACpB,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,MAAM,KAAA,GAAQ,CAAC,OAAA,KAAiC;AAC9C,IAAA,gBAAA,CAAiB,SAAS,QAAQ,CAAA;AAClC,IAAA,MAAA,CAAO,QAAA,CAAS,MAAA,CAAO,aAAA,CAAc,UAAU,CAAA;AAAA,EACjD,CAAA;AAEA,EAAA,MAAM,kBAAkB,YAA4C;AAClE,IAAA,MAAM,UAAA,GAAa,IAAI,GAAA,CAAI,MAAA,CAAO,SAAS,IAAI,CAAA;AAC/C,IAAA,MAAM,KAAA,GAAQ,kBAAkB,UAAU,CAAA;AAE1C,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,MAAM,IAAI,YAAA,CAAa;AAAA,QACrB,MAAM,aAAA,CAAc,oBAAA;AAAA,QACpB,OAAA,EAAS,IAAA;AAAA,QACT,OAAA,EAAS,yCAAA;AAAA,QACT,QAAQ,UAAA,CAAW;AAAA,OACpB,CAAA;AAAA,IACH;AAEA,IAAA,MAAM,UAAA,GAAa,oBAAoB,UAAU,CAAA;AACjD,IAAA,qBAAA,CAAsB,UAAU,CAAA;AAEhC,IAAA,IAAI;AACF,MAAA,MAAM,UAAU,MAAM,QAAA;AAAA,QACpB,aAAA,CAAc,qBAAA;AAAA,QACd,EAAE,KAAA;AAAM,OACV;AAEA,MAAA,MAAM,OAAA,GAAU,kBAAA,CAAmB,OAAA,CAAQ,OAAA,EAAS,cAAc,qBAAqB,CAAA;AACvF,MAAA,YAAA,CAAa,WAAW,OAAO,CAAA;AAC/B,MAAA,aAAA,CAAc,eAAe,OAAO,CAAA;AAEpC,MAAA,OAAO;AAAA,QACL,YAAY,mBAAA,EAAoB;AAAA,QAChC;AAAA,OACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,kBAAkB,KAAK,CAAA;AAAA,IAC/B;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,2BAA2B,YAA4B;AAC3D,IAAA,MAAM,MAAA,GAAS,MAAM,eAAA,EAAgB;AACrC,IAAA,MAAA,CAAO,QAAA,CAAS,OAAA,CAAQ,MAAA,CAAO,UAAU,CAAA;AACzC,IAAA,OAAO,4BAAA,EAAoC;AAAA,EAC7C,CAAA;AAEA,EAAA,MAAM,SAAS,YAA2B;AACxC,IAAA,MAAM,SAAA,CAAU,cAAc,MAAM,CAAA;AACpC,IAAA,YAAA,CAAa,WAAW,IAAI,CAAA;AAC5B,IAAA,aAAA,CAAc,eAAe,IAAI,CAAA;AAAA,EACnC,CAAA;AAEA,EAAA,MAAM,SAAA,GAAY,YAAA,CAAa,SAAA,CAAU,IAAA,CAAK,YAAY,CAAA;AAE1D,EAAA,OAAO;AAAA,IACL,wBAAA;AAAA,IACA,UAAA;AAAA,IACA,KAAA;AAAA,IACA,MAAA;AAAA,IACA,eAAA;AAAA,IACA,cAAA;AAAA,IACA;AAAA,GACF;AACF","file":"index.js","sourcesContent":["const authApiPrefix = \"/v1/auth\";\n\nexport const authEndpoints = {\n loginStart: `${authApiPrefix}/keycloak/login`,\n validateKeycloakToken: `${authApiPrefix}/keycloak/validate`,\n session: `${authApiPrefix}/me`,\n logout: `${authApiPrefix}/logout`,\n} as const;\n","export const authQueryKeys = {\n token: \"token\",\n} as const;\n\nexport const authStorageKeys = {\n returnTo: \"ghostly-auth:return-to\",\n} as const;\n\nexport const authBroadcast = {\n channelName: \"ghostly-auth-channel\",\n sessionUpdatedEvent: \"session-updated\",\n} as const;\n\nexport const authRoutes = {\n root: \"/\",\n callback: \"/auth/callback\",\n} as const;\n","export const httpStatus = {\n ok: 200,\n found: 302,\n noContent: 204,\n badRequest: 400,\n unauthorized: 401,\n} as const;\n","import type { AuthErrorCode } from \"../types/auth-error-code\";\n\nexport interface AuthSdkErrorPayload {\n code: AuthErrorCode;\n details: unknown;\n message: string;\n status: number | null;\n}\n\nexport class AuthSdkError extends Error {\n readonly code: AuthErrorCode;\n readonly details: unknown;\n readonly status: number | null;\n\n constructor(payload: AuthSdkErrorPayload) {\n super(payload.message);\n this.name = \"AuthSdkError\";\n this.code = payload.code;\n this.details = payload.details;\n this.status = payload.status;\n }\n}\n","export const authErrorCode = {\n callbackMissingToken: \"callback_missing_token\",\n callbackInvalidToken: \"callback_invalid_token\",\n callbackValidationFailed: \"callback_validation_failed\",\n unauthorized: \"unauthorized\",\n networkError: \"network_error\",\n apiError: \"api_error\",\n broadcastChannelUnsupported: \"broadcast_channel_unsupported\",\n serverOriginResolutionFailed: \"server_origin_resolution_failed\",\n} as const;\n\nexport type AuthErrorCode = (typeof authErrorCode)[keyof typeof authErrorCode];\n","export function isObjectRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nexport function isStringValue(value: unknown): value is string {\n return typeof value === \"string\";\n}\n","import type { GhostlySession } from \"../types/ghostly-session\";\nimport { isObjectRecord, isStringValue } from \"./object-guards\";\n\nexport function isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((entry) => isStringValue(entry));\n}\n\nexport function isGhostlySession(value: unknown): value is GhostlySession {\n if (!isObjectRecord(value)) {\n return false;\n }\n\n return (\n isStringValue(value.id) &&\n isStringValue(value.username) &&\n (value.firstName === null || isStringValue(value.firstName)) &&\n (value.lastName === null || isStringValue(value.lastName)) &&\n isStringValue(value.email) &&\n isStringValue(value.role) &&\n isStringArray(value.permissions)\n );\n}\n","import { authBroadcast } from \"../constants/auth-keys\";\nimport { AuthSdkError } from \"../errors/auth-sdk-error\";\nimport { authErrorCode } from \"../types/auth-error-code\";\nimport type { GhostlySession } from \"../types/ghostly-session\";\nimport { isObjectRecord, isStringValue } from \"./object-guards\";\nimport { isGhostlySession } from \"./session-parser\";\n\ninterface SessionUpdatedMessage {\n session: GhostlySession | null;\n type: typeof authBroadcast.sessionUpdatedEvent;\n}\n\nexport interface BroadcastSync {\n close(): void;\n publishSession(session: GhostlySession | null): void;\n}\n\ninterface CreateBroadcastSyncOptions {\n onSessionUpdated: (session: GhostlySession | null) => void;\n}\n\nfunction isSessionUpdatedMessage(value: unknown): value is SessionUpdatedMessage {\n if (!isObjectRecord(value)) {\n return false;\n }\n\n if (!isStringValue(value.type)) {\n return false;\n }\n\n if (value.type !== authBroadcast.sessionUpdatedEvent) {\n return false;\n }\n\n return value.session === null || isGhostlySession(value.session);\n}\n\nfunction createUnsupportedBroadcastChannelError(): AuthSdkError {\n return new AuthSdkError({\n code: authErrorCode.broadcastChannelUnsupported,\n details: null,\n message: \"BroadcastChannel is unavailable in this runtime.\",\n status: null,\n });\n}\n\nexport function createBroadcastSync(options: CreateBroadcastSyncOptions): BroadcastSync {\n if (typeof BroadcastChannel === \"undefined\") {\n throw createUnsupportedBroadcastChannelError();\n }\n\n const channel = new BroadcastChannel(authBroadcast.channelName);\n\n const onMessage: EventListener = (event) => {\n const messageEvent = event as MessageEvent<unknown>;\n\n if (!isSessionUpdatedMessage(messageEvent.data)) {\n return;\n }\n\n options.onSessionUpdated(messageEvent.data.session);\n };\n\n channel.addEventListener(\"message\", onMessage);\n\n return {\n close() {\n channel.removeEventListener(\"message\", onMessage);\n channel.close();\n },\n publishSession(session) {\n const payload: SessionUpdatedMessage = {\n session,\n type: authBroadcast.sessionUpdatedEvent,\n };\n\n channel.postMessage(payload);\n },\n };\n}\n","import { authQueryKeys } from \"../constants/auth-keys\";\n\nexport function readCallbackToken(url: URL): string | null {\n return url.searchParams.get(authQueryKeys.token);\n}\n\nexport function removeCallbackToken(url: URL): URL {\n const nextUrl = new URL(url.toString());\n nextUrl.searchParams.delete(authQueryKeys.token);\n return nextUrl;\n}\n\nexport function replaceBrowserHistory(url: URL): void {\n window.history.replaceState(null, \"\", url.toString());\n}\n","import { httpStatus } from \"../constants/http-status\";\nimport { AuthSdkError } from \"../errors/auth-sdk-error\";\nimport { authErrorCode } from \"../types/auth-error-code\";\nimport { isObjectRecord, isStringValue } from \"./object-guards\";\n\nconst jsonContentType = \"application/json\";\nconst jsonHeaderName = \"content-type\";\nconst includeCredentials: RequestCredentials = \"include\";\nconst noStoreCache: RequestCache = \"no-store\";\n\ninterface RequestOptions<TBody> {\n body?: TBody;\n expectedStatus?: number;\n method: \"GET\" | \"POST\";\n path: string;\n}\n\ninterface ParsedErrorPayload {\n code: string | null;\n details: unknown;\n message: string | null;\n}\n\nfunction toTypedValue<TValue>(value: unknown): TValue {\n return value as TValue;\n}\n\nfunction mapHttpStatusToAuthErrorCode(status: number) {\n if (status === httpStatus.unauthorized) {\n return authErrorCode.unauthorized;\n }\n\n return authErrorCode.apiError;\n}\n\nasync function parseJsonPayload(response: Response): Promise<unknown> {\n try {\n return await response.json();\n } catch {\n return null;\n }\n}\n\nasync function parseErrorPayload(response: Response): Promise<ParsedErrorPayload> {\n const payload = await parseJsonPayload(response);\n\n if (!isObjectRecord(payload)) {\n return {\n code: null,\n details: null,\n message: null,\n };\n }\n\n const maybeCode = payload.code;\n const maybeMessage = payload.message;\n\n return {\n code: isStringValue(maybeCode) ? maybeCode : null,\n details: \"details\" in payload ? payload.details : null,\n message: isStringValue(maybeMessage) ? maybeMessage : null,\n };\n}\n\nfunction buildApiErrorMessage(method: RequestOptions<unknown>[\"method\"], path: string): string {\n return `Auth API request failed: ${method} ${path}`;\n}\n\nfunction buildNetworkErrorMessage(method: RequestOptions<unknown>[\"method\"], path: string): string {\n return `Auth API network failure: ${method} ${path}`;\n}\n\nasync function request<TResponse, TBody = undefined>(\n options: RequestOptions<TBody>,\n): Promise<TResponse> {\n const expectedStatus = options.expectedStatus ?? httpStatus.ok;\n const headers = new Headers();\n const hasBody = typeof options.body !== \"undefined\";\n\n if (hasBody) {\n headers.set(jsonHeaderName, jsonContentType);\n }\n\n const requestInit: RequestInit = {\n cache: noStoreCache,\n credentials: includeCredentials,\n headers,\n method: options.method,\n };\n\n if (hasBody) {\n requestInit.body = JSON.stringify(options.body);\n }\n\n let response: Response;\n\n try {\n response = await fetch(options.path, requestInit);\n } catch (error) {\n throw new AuthSdkError({\n code: authErrorCode.networkError,\n details: error,\n message: buildNetworkErrorMessage(options.method, options.path),\n status: null,\n });\n }\n\n if (response.status !== expectedStatus) {\n const parsed = await parseErrorPayload(response);\n\n throw new AuthSdkError({\n code: mapHttpStatusToAuthErrorCode(response.status),\n details: {\n apiCode: parsed.code,\n apiDetails: parsed.details,\n },\n message: parsed.message ?? buildApiErrorMessage(options.method, options.path),\n status: response.status,\n });\n }\n\n if (response.status === httpStatus.noContent) {\n return toTypedValue<TResponse>(null);\n }\n\n const payload = await parseJsonPayload(response);\n return toTypedValue<TResponse>(payload);\n}\n\nexport function getJson<TResponse>(path: string): Promise<TResponse> {\n return request<TResponse>({\n method: \"GET\",\n path,\n });\n}\n\nexport function postJson<TResponse, TBody>(path: string, body: TBody): Promise<TResponse> {\n return request<TResponse, TBody>({\n body,\n method: \"POST\",\n path,\n });\n}\n\nexport function postEmpty(path: string): Promise<null> {\n return request<null>({\n expectedStatus: httpStatus.noContent,\n method: \"POST\",\n path,\n });\n}\n","import { AuthSdkError } from \"../errors/auth-sdk-error\";\nimport { authErrorCode } from \"../types/auth-error-code\";\n\nconst browserRuntimeErrorMessage = \"Browser runtime is required for this auth operation.\";\n\nexport function isBrowserRuntime(): boolean {\n return typeof window !== \"undefined\";\n}\n\nexport function assertBrowserRuntime(): void {\n if (isBrowserRuntime()) {\n return;\n }\n\n throw new AuthSdkError({\n code: authErrorCode.apiError,\n details: null,\n message: browserRuntimeErrorMessage,\n status: null,\n });\n}\n","import { authRoutes, authStorageKeys } from \"../constants/auth-keys\";\nimport { assertBrowserRuntime } from \"./runtime\";\n\nfunction sanitizeReturnTo(value: string | null | undefined): string {\n if (!value) {\n return authRoutes.root;\n }\n\n if (!value.startsWith(authRoutes.root)) {\n return authRoutes.root;\n }\n\n const protocolRelativePrefix = \"//\";\n\n if (value.startsWith(protocolRelativePrefix)) {\n return authRoutes.root;\n }\n\n return value;\n}\n\nfunction getCurrentBrowserPath(): string {\n return `${window.location.pathname}${window.location.search}${window.location.hash}`;\n}\n\nexport function saveReturnToPath(returnTo: string | undefined): string {\n assertBrowserRuntime();\n\n const fallbackPath = getCurrentBrowserPath();\n const sanitized = sanitizeReturnTo(returnTo ?? fallbackPath);\n window.sessionStorage.setItem(authStorageKeys.returnTo, sanitized);\n return sanitized;\n}\n\nexport function consumeReturnToPath(): string {\n assertBrowserRuntime();\n\n const value = window.sessionStorage.getItem(authStorageKeys.returnTo);\n window.sessionStorage.removeItem(authStorageKeys.returnTo);\n return sanitizeReturnTo(value);\n}\n","import type { SessionListener } from \"../types/auth-client\";\nimport type { GhostlySession } from \"../types/ghostly-session\";\n\ntype SessionResolveState = \"pending\" | \"resolved\";\n\nexport class SessionStore {\n private listeners = new Set<SessionListener>();\n private resolvedSession: GhostlySession | null = null;\n private resolveState: SessionResolveState = \"pending\";\n\n getSessionIfResolved(): GhostlySession | null {\n if (this.resolveState === \"pending\") {\n return null;\n }\n\n return this.resolvedSession;\n }\n\n hasResolvedSession(): boolean {\n return this.resolveState === \"resolved\";\n }\n\n setSession(session: GhostlySession | null): void {\n this.resolveState = \"resolved\";\n this.resolvedSession = session;\n\n for (const listener of this.listeners) {\n listener(session);\n }\n }\n\n subscribe(listener: SessionListener): () => void {\n this.listeners.add(listener);\n\n return () => {\n this.listeners.delete(listener);\n };\n }\n}\n","import { authEndpoints } from \"../constants/auth-endpoints\";\nimport { httpStatus } from \"../constants/http-status\";\nimport { AuthSdkError } from \"../errors/auth-sdk-error\";\nimport type {\n AuthClient,\n LoginOptions,\n ProcessCallbackResult,\n SessionRequestOptions,\n} from \"../types/auth-client\";\nimport { authErrorCode } from \"../types/auth-error-code\";\nimport type { GhostlySession } from \"../types/ghostly-session\";\nimport type { BroadcastSync } from \"./broadcast-sync\";\nimport { createBroadcastSync } from \"./broadcast-sync\";\nimport { readCallbackToken, removeCallbackToken, replaceBrowserHistory } from \"./callback-url\";\nimport { getJson, postEmpty, postJson } from \"./http-client\";\nimport { consumeReturnToPath, saveReturnToPath } from \"./return-to-storage\";\nimport { assertBrowserRuntime } from \"./runtime\";\nimport { isGhostlySession } from \"./session-parser\";\nimport { SessionStore } from \"./session-store\";\n\ninterface ValidateTokenRequest {\n token: string;\n}\n\ninterface ValidateTokenResponse {\n session: unknown;\n}\n\nfunction createPendingRedirectPromise<TValue>(): Promise<TValue> {\n return new Promise(() => {\n // Location redirect never resolves within current runtime execution.\n });\n}\n\nfunction createInvalidSessionPayloadError(path: string): AuthSdkError {\n return new AuthSdkError({\n code: authErrorCode.apiError,\n details: null,\n message: `Auth API response has invalid session shape: ${path}`,\n status: null,\n });\n}\n\nfunction toValidatedSession(payload: unknown, path: string): GhostlySession {\n if (!isGhostlySession(payload)) {\n throw createInvalidSessionPayloadError(path);\n }\n\n return payload;\n}\n\nfunction toCallbackFailure(error: unknown): AuthSdkError {\n if (error instanceof AuthSdkError) {\n if (error.status === httpStatus.unauthorized) {\n return new AuthSdkError({\n code: authErrorCode.callbackInvalidToken,\n details: error.details,\n message: \"Callback JWT is invalid or expired.\",\n status: error.status,\n });\n }\n\n return new AuthSdkError({\n code: authErrorCode.callbackValidationFailed,\n details: error.details,\n message: \"Keycloak callback validation failed.\",\n status: error.status,\n });\n }\n\n return new AuthSdkError({\n code: authErrorCode.callbackValidationFailed,\n details: error,\n message: \"Keycloak callback validation failed.\",\n status: null,\n });\n}\n\nfunction createNoopBroadcastSync(): BroadcastSync {\n return {\n close() {},\n publishSession() {},\n };\n}\n\nfunction createSafeBroadcastSync(\n onSessionUpdated: (session: GhostlySession | null) => void,\n): BroadcastSync {\n try {\n return createBroadcastSync({\n onSessionUpdated,\n });\n } catch (error) {\n if (error instanceof AuthSdkError && error.code === authErrorCode.broadcastChannelUnsupported) {\n return createNoopBroadcastSync();\n }\n\n throw error;\n }\n}\n\nasync function fetchCurrentSessionFromApi(): Promise<GhostlySession | null> {\n const payload = await getJson<unknown>(authEndpoints.session);\n\n if (payload === null) {\n return null;\n }\n\n return toValidatedSession(payload, authEndpoints.session);\n}\n\nexport function createAuthClient(): AuthClient {\n assertBrowserRuntime();\n\n const sessionStore = new SessionStore();\n const broadcastSync = createSafeBroadcastSync((session) => {\n sessionStore.setSession(session);\n });\n\n const getSession = async (options?: SessionRequestOptions): Promise<GhostlySession | null> => {\n const forceRefresh = options?.forceRefresh ?? false;\n\n if (sessionStore.hasResolvedSession() && !forceRefresh) {\n return sessionStore.getSessionIfResolved();\n }\n\n const session = await fetchCurrentSessionFromApi();\n sessionStore.setSession(session);\n broadcastSync.publishSession(session);\n\n return session;\n };\n\n const requireSession = async (): Promise<GhostlySession> => {\n const session = await getSession();\n\n if (session) {\n return session;\n }\n\n throw new AuthSdkError({\n code: authErrorCode.unauthorized,\n details: null,\n message: \"Authenticated session is required.\",\n status: httpStatus.unauthorized,\n });\n };\n\n const login = (options?: LoginOptions): void => {\n saveReturnToPath(options?.returnTo);\n window.location.assign(authEndpoints.loginStart);\n };\n\n const processCallback = async (): Promise<ProcessCallbackResult> => {\n const currentUrl = new URL(window.location.href);\n const token = readCallbackToken(currentUrl);\n\n if (!token) {\n throw new AuthSdkError({\n code: authErrorCode.callbackMissingToken,\n details: null,\n message: \"Missing callback token query parameter.\",\n status: httpStatus.badRequest,\n });\n }\n\n const cleanedUrl = removeCallbackToken(currentUrl);\n replaceBrowserHistory(cleanedUrl);\n\n try {\n const payload = await postJson<ValidateTokenResponse, ValidateTokenRequest>(\n authEndpoints.validateKeycloakToken,\n { token },\n );\n\n const session = toValidatedSession(payload.session, authEndpoints.validateKeycloakToken);\n sessionStore.setSession(session);\n broadcastSync.publishSession(session);\n\n return {\n redirectTo: consumeReturnToPath(),\n session,\n };\n } catch (error) {\n throw toCallbackFailure(error);\n }\n };\n\n const completeCallbackRedirect = async (): Promise<never> => {\n const result = await processCallback();\n window.location.replace(result.redirectTo);\n return createPendingRedirectPromise<never>();\n };\n\n const logout = async (): Promise<void> => {\n await postEmpty(authEndpoints.logout);\n sessionStore.setSession(null);\n broadcastSync.publishSession(null);\n };\n\n const subscribe = sessionStore.subscribe.bind(sessionStore);\n\n return {\n completeCallbackRedirect,\n getSession,\n login,\n logout,\n processCallback,\n requireSession,\n subscribe,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants/auth-endpoints.ts","../src/constants/auth-keys.ts","../src/constants/http-status.ts","../src/errors/auth-sdk-error.ts","../src/types/auth-error-code.ts","../src/core/api-origin.ts","../src/core/object-guards.ts","../src/core/session-parser.ts","../src/core/broadcast-sync.ts","../src/core/http-client.ts","../src/core/runtime.ts","../src/core/return-to-storage.ts","../src/core/session-store.ts","../src/core/auth-client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["const authApiPrefix = \"/oauth\";\n\nexport const authEndpoints = {\n authorize: `${authApiPrefix}/authorize`,\n providerCallback: `${authApiPrefix}/callback/provider`,\n session: `${authApiPrefix}/session`,\n refresh: `${authApiPrefix}/refresh`,\n logout: `${authApiPrefix}/logout`,\n} as const;\n","export const authBroadcast = {\n channelName: \"ghostly-auth-channel\",\n sessionUpdatedEvent: \"session-updated\",\n} as const;\n\nexport const authRoutes = {\n root: \"/\",\n} as const;\n","export const httpStatus = {\n ok: 200,\n found: 302,\n noContent: 204,\n badRequest: 400,\n unauthorized: 401,\n} as const;\n","import type { AuthErrorCode } from \"../types/auth-error-code\";\n\nexport interface AuthSdkErrorPayload {\n code: AuthErrorCode;\n details: unknown;\n message: string;\n status: number | null;\n}\n\nexport class AuthSdkError extends Error {\n readonly code: AuthErrorCode;\n readonly details: unknown;\n readonly status: number | null;\n\n constructor(payload: AuthSdkErrorPayload) {\n super(payload.message);\n this.name = \"AuthSdkError\";\n this.code = payload.code;\n this.details = payload.details;\n this.status = payload.status;\n }\n}\n","export const authErrorCode = {\n unauthorized: \"unauthorized\",\n networkError: \"network_error\",\n apiError: \"api_error\",\n broadcastChannelUnsupported: \"broadcast_channel_unsupported\",\n serverOriginResolutionFailed: \"server_origin_resolution_failed\",\n} as const;\n\nexport type AuthErrorCode = (typeof authErrorCode)[keyof typeof authErrorCode];\n","import { AuthSdkError } from \"../errors/auth-sdk-error\";\nimport { authErrorCode } from \"../types/auth-error-code\";\n\nconst slash = \"/\";\n\nfunction normalizeApiOrigin(apiOrigin: string): string {\n const trimmed = apiOrigin.trim();\n\n if (!trimmed) {\n throw new AuthSdkError({\n code: authErrorCode.apiError,\n details: null,\n message: \"Auth API origin must be a non-empty absolute URL.\",\n status: null,\n });\n }\n\n let parsed: URL;\n\n try {\n parsed = new URL(trimmed);\n } catch (error) {\n throw new AuthSdkError({\n code: authErrorCode.apiError,\n details: error,\n message: \"Auth API origin must be a valid absolute URL.\",\n status: null,\n });\n }\n\n if (parsed.pathname !== slash || parsed.search || parsed.hash) {\n throw new AuthSdkError({\n code: authErrorCode.apiError,\n details: null,\n message: \"Auth API origin must not include path, query, or hash.\",\n status: null,\n });\n }\n\n return parsed.origin;\n}\n\nexport function resolveApiEndpoint(path: string, apiOrigin?: string): string {\n if (!apiOrigin) {\n return path;\n }\n\n return `${normalizeApiOrigin(apiOrigin)}${path}`;\n}\n","export function isObjectRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nexport function isStringValue(value: unknown): value is string {\n return typeof value === \"string\";\n}\n","import type { GhostlySession } from \"../types/ghostly-session\";\nimport { isObjectRecord, isStringValue } from \"./object-guards\";\n\nexport function isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((entry) => isStringValue(entry));\n}\n\nexport function isGhostlySession(value: unknown): value is GhostlySession {\n if (!isObjectRecord(value)) {\n return false;\n }\n\n return (\n isStringValue(value.id) &&\n isStringValue(value.username) &&\n (value.firstName === null || isStringValue(value.firstName)) &&\n (value.lastName === null || isStringValue(value.lastName)) &&\n isStringValue(value.email) &&\n isStringValue(value.role) &&\n isStringArray(value.permissions)\n );\n}\n","import { authBroadcast } from \"../constants/auth-keys\";\nimport { AuthSdkError } from \"../errors/auth-sdk-error\";\nimport { authErrorCode } from \"../types/auth-error-code\";\nimport type { GhostlySession } from \"../types/ghostly-session\";\nimport { isObjectRecord, isStringValue } from \"./object-guards\";\nimport { isGhostlySession } from \"./session-parser\";\n\ninterface SessionUpdatedMessage {\n session: GhostlySession | null;\n type: typeof authBroadcast.sessionUpdatedEvent;\n}\n\nexport interface BroadcastSync {\n close(): void;\n publishSession(session: GhostlySession | null): void;\n}\n\ninterface CreateBroadcastSyncOptions {\n onSessionUpdated: (session: GhostlySession | null) => void;\n}\n\nfunction isSessionUpdatedMessage(value: unknown): value is SessionUpdatedMessage {\n if (!isObjectRecord(value)) {\n return false;\n }\n\n if (!isStringValue(value.type)) {\n return false;\n }\n\n if (value.type !== authBroadcast.sessionUpdatedEvent) {\n return false;\n }\n\n return value.session === null || isGhostlySession(value.session);\n}\n\nfunction createUnsupportedBroadcastChannelError(): AuthSdkError {\n return new AuthSdkError({\n code: authErrorCode.broadcastChannelUnsupported,\n details: null,\n message: \"BroadcastChannel is unavailable in this runtime.\",\n status: null,\n });\n}\n\nexport function createBroadcastSync(options: CreateBroadcastSyncOptions): BroadcastSync {\n if (typeof BroadcastChannel === \"undefined\") {\n throw createUnsupportedBroadcastChannelError();\n }\n\n const channel = new BroadcastChannel(authBroadcast.channelName);\n\n const onMessage: EventListener = (event) => {\n const messageEvent = event as MessageEvent<unknown>;\n\n if (!isSessionUpdatedMessage(messageEvent.data)) {\n return;\n }\n\n options.onSessionUpdated(messageEvent.data.session);\n };\n\n channel.addEventListener(\"message\", onMessage);\n\n return {\n close() {\n channel.removeEventListener(\"message\", onMessage);\n channel.close();\n },\n publishSession(session) {\n const payload: SessionUpdatedMessage = {\n session,\n type: authBroadcast.sessionUpdatedEvent,\n };\n\n channel.postMessage(payload);\n },\n };\n}\n","import { httpStatus } from \"../constants/http-status\";\nimport { AuthSdkError } from \"../errors/auth-sdk-error\";\nimport { authErrorCode } from \"../types/auth-error-code\";\nimport { isObjectRecord, isStringValue } from \"./object-guards\";\n\nconst jsonContentType = \"application/json\";\nconst jsonHeaderName = \"content-type\";\nconst includeCredentials: RequestCredentials = \"include\";\nconst noStoreCache: RequestCache = \"no-store\";\n\ninterface RequestOptions<TBody> {\n body?: TBody;\n expectedStatus?: number;\n method: \"GET\" | \"POST\";\n path: string;\n}\n\ninterface ParsedErrorPayload {\n code: string | null;\n details: unknown;\n message: string | null;\n}\n\nfunction toTypedValue<TValue>(value: unknown): TValue {\n return value as TValue;\n}\n\nfunction mapHttpStatusToAuthErrorCode(status: number) {\n if (status === httpStatus.unauthorized) {\n return authErrorCode.unauthorized;\n }\n\n return authErrorCode.apiError;\n}\n\nasync function parseJsonPayload(response: Response): Promise<unknown> {\n try {\n return await response.json();\n } catch {\n return null;\n }\n}\n\nasync function parseErrorPayload(response: Response): Promise<ParsedErrorPayload> {\n const payload = await parseJsonPayload(response);\n\n if (!isObjectRecord(payload)) {\n return {\n code: null,\n details: null,\n message: null,\n };\n }\n\n const maybeCode = payload.code;\n const maybeMessage = payload.message;\n\n return {\n code: isStringValue(maybeCode) ? maybeCode : null,\n details: \"details\" in payload ? payload.details : null,\n message: isStringValue(maybeMessage) ? maybeMessage : null,\n };\n}\n\nfunction buildApiErrorMessage(method: RequestOptions<unknown>[\"method\"], path: string): string {\n return `Auth API request failed: ${method} ${path}`;\n}\n\nfunction buildNetworkErrorMessage(method: RequestOptions<unknown>[\"method\"], path: string): string {\n return `Auth API network failure: ${method} ${path}`;\n}\n\nasync function request<TResponse, TBody = undefined>(\n options: RequestOptions<TBody>,\n): Promise<TResponse> {\n const expectedStatus = options.expectedStatus ?? httpStatus.ok;\n const headers = new Headers();\n const hasBody = typeof options.body !== \"undefined\";\n\n if (hasBody) {\n headers.set(jsonHeaderName, jsonContentType);\n }\n\n const requestInit: RequestInit = {\n cache: noStoreCache,\n credentials: includeCredentials,\n headers,\n method: options.method,\n };\n\n if (hasBody) {\n requestInit.body = JSON.stringify(options.body);\n }\n\n let response: Response;\n\n try {\n response = await fetch(options.path, requestInit);\n } catch (error) {\n throw new AuthSdkError({\n code: authErrorCode.networkError,\n details: error,\n message: buildNetworkErrorMessage(options.method, options.path),\n status: null,\n });\n }\n\n if (response.status !== expectedStatus) {\n const parsed = await parseErrorPayload(response);\n\n throw new AuthSdkError({\n code: mapHttpStatusToAuthErrorCode(response.status),\n details: {\n apiCode: parsed.code,\n apiDetails: parsed.details,\n },\n message: parsed.message ?? buildApiErrorMessage(options.method, options.path),\n status: response.status,\n });\n }\n\n if (response.status === httpStatus.noContent) {\n return toTypedValue<TResponse>(null);\n }\n\n const payload = await parseJsonPayload(response);\n return toTypedValue<TResponse>(payload);\n}\n\nexport function getJson<TResponse>(path: string): Promise<TResponse> {\n return request<TResponse>({\n method: \"GET\",\n path,\n });\n}\n\nexport function postJson<TResponse, TBody>(path: string, body: TBody): Promise<TResponse> {\n return request<TResponse, TBody>({\n body,\n method: \"POST\",\n path,\n });\n}\n\nexport function postJsonWithoutBody<TResponse>(path: string): Promise<TResponse> {\n return request<TResponse>({\n method: \"POST\",\n path,\n });\n}\n\nexport function postEmpty(path: string): Promise<null> {\n return request<null>({\n expectedStatus: httpStatus.noContent,\n method: \"POST\",\n path,\n });\n}\n","import { AuthSdkError } from \"../errors/auth-sdk-error\";\nimport { authErrorCode } from \"../types/auth-error-code\";\n\nconst browserRuntimeErrorMessage = \"Browser runtime is required for this auth operation.\";\n\nexport function isBrowserRuntime(): boolean {\n return typeof window !== \"undefined\";\n}\n\nexport function assertBrowserRuntime(): void {\n if (isBrowserRuntime()) {\n return;\n }\n\n throw new AuthSdkError({\n code: authErrorCode.apiError,\n details: null,\n message: browserRuntimeErrorMessage,\n status: null,\n });\n}\n","import { authRoutes } from \"../constants/auth-keys\";\nimport { assertBrowserRuntime } from \"./runtime\";\n\nfunction sanitizeReturnTo(value: string | null | undefined): string {\n if (!value) {\n return authRoutes.root;\n }\n\n if (!value.startsWith(authRoutes.root)) {\n return authRoutes.root;\n }\n\n const protocolRelativePrefix = \"//\";\n\n if (value.startsWith(protocolRelativePrefix)) {\n return authRoutes.root;\n }\n\n return value;\n}\n\nfunction getCurrentBrowserPath(): string {\n return `${window.location.pathname}${window.location.search}${window.location.hash}`;\n}\n\nexport function resolveReturnToPath(returnTo: string | undefined): string {\n assertBrowserRuntime();\n\n const fallbackPath = getCurrentBrowserPath();\n return sanitizeReturnTo(returnTo ?? fallbackPath);\n}\n","import type { SessionListener } from \"../types/auth-client\";\nimport type { GhostlySession } from \"../types/ghostly-session\";\n\ntype SessionResolveState = \"pending\" | \"resolved\";\n\nexport class SessionStore {\n private listeners = new Set<SessionListener>();\n private resolvedSession: GhostlySession | null = null;\n private resolveState: SessionResolveState = \"pending\";\n\n getSessionIfResolved(): GhostlySession | null {\n if (this.resolveState === \"pending\") {\n return null;\n }\n\n return this.resolvedSession;\n }\n\n hasResolvedSession(): boolean {\n return this.resolveState === \"resolved\";\n }\n\n setSession(session: GhostlySession | null): void {\n this.resolveState = \"resolved\";\n this.resolvedSession = session;\n\n for (const listener of this.listeners) {\n listener(session);\n }\n }\n\n subscribe(listener: SessionListener): () => void {\n this.listeners.add(listener);\n\n return () => {\n this.listeners.delete(listener);\n };\n }\n}\n","import { authEndpoints } from \"../constants/auth-endpoints\";\nimport { httpStatus } from \"../constants/http-status\";\nimport { AuthSdkError } from \"../errors/auth-sdk-error\";\nimport type {\n AuthClient,\n AuthClientOptions,\n AuthInitOptions,\n AuthInitResult,\n LoginOptions,\n SessionRequestOptions,\n} from \"../types/auth-client\";\nimport { authErrorCode } from \"../types/auth-error-code\";\nimport type { GhostlySession } from \"../types/ghostly-session\";\nimport { resolveApiEndpoint } from \"./api-origin\";\nimport type { BroadcastSync } from \"./broadcast-sync\";\nimport { createBroadcastSync } from \"./broadcast-sync\";\nimport { getJson, postEmpty, postJsonWithoutBody } from \"./http-client\";\nimport { resolveReturnToPath } from \"./return-to-storage\";\nimport { isGhostlySession } from \"./session-parser\";\nimport { SessionStore } from \"./session-store\";\n\nfunction createInvalidSessionPayloadError(path: string): AuthSdkError {\n return new AuthSdkError({\n code: authErrorCode.apiError,\n details: null,\n message: `Auth API response has invalid session shape: ${path}`,\n status: null,\n });\n}\n\nfunction toValidatedSession(payload: unknown, path: string): GhostlySession {\n if (!isGhostlySession(payload)) {\n throw createInvalidSessionPayloadError(path);\n }\n\n return payload;\n}\n\nfunction toSessionPayload(payload: unknown, path: string): GhostlySession | null {\n if (payload === null) {\n return null;\n }\n\n return toValidatedSession(payload, path);\n}\n\nfunction createNoopBroadcastSync(): BroadcastSync {\n return {\n close() {},\n publishSession() {},\n };\n}\n\nfunction createSafeBroadcastSync(\n onSessionUpdated: (session: GhostlySession | null) => void,\n): BroadcastSync {\n try {\n return createBroadcastSync({\n onSessionUpdated,\n });\n } catch (error) {\n if (error instanceof AuthSdkError && error.code === authErrorCode.broadcastChannelUnsupported) {\n return createNoopBroadcastSync();\n }\n\n throw error;\n }\n}\n\nfunction toInitResult(session: GhostlySession | null): AuthInitResult {\n return {\n session,\n status: session ? \"authenticated\" : \"unauthenticated\",\n };\n}\n\nexport function createAuthClient(options: AuthClientOptions = {}): AuthClient {\n let initPromise: Promise<AuthInitResult> | null = null;\n const defaultApplication = options.application?.trim() || \"\";\n\n const sessionStore = new SessionStore();\n const broadcastSync = createSafeBroadcastSync((session) => {\n sessionStore.setSession(session);\n });\n\n const resolveEndpoint = (path: string): string => resolveApiEndpoint(path, options.apiOrigin);\n\n const loadSession = async (): Promise<GhostlySession | null> => {\n const payload = await getJson<unknown>(resolveEndpoint(authEndpoints.session));\n return toSessionPayload(payload, authEndpoints.session);\n };\n\n const init = async (initOptions?: AuthInitOptions): Promise<AuthInitResult> => {\n const forceRefresh = initOptions?.forceRefresh ?? false;\n\n if (sessionStore.hasResolvedSession() && !forceRefresh) {\n return toInitResult(sessionStore.getSessionIfResolved());\n }\n\n if (initPromise) {\n return initPromise;\n }\n\n initPromise = (async () => {\n const session = await loadSession();\n sessionStore.setSession(session);\n broadcastSync.publishSession(session);\n return toInitResult(session);\n })();\n\n try {\n return await initPromise;\n } finally {\n initPromise = null;\n }\n };\n\n const getSession = async (\n requestOptions?: SessionRequestOptions,\n ): Promise<GhostlySession | null> => {\n const result = await init({\n forceRefresh: requestOptions?.forceRefresh ?? false,\n });\n\n return result.session;\n };\n\n const refresh = async (): Promise<GhostlySession | null> => {\n const payload = await postJsonWithoutBody<unknown>(resolveEndpoint(authEndpoints.refresh));\n const session = toSessionPayload(payload, authEndpoints.refresh);\n sessionStore.setSession(session);\n broadcastSync.publishSession(session);\n return session;\n };\n\n const requireSession = async (): Promise<GhostlySession> => {\n const session = await getSession();\n\n if (session) {\n return session;\n }\n\n throw new AuthSdkError({\n code: authErrorCode.unauthorized,\n details: null,\n message: \"Authenticated session is required.\",\n status: httpStatus.unauthorized,\n });\n };\n\n const login = (loginOptions?: LoginOptions): void => {\n const returnTo = resolveReturnToPath(loginOptions?.returnTo);\n const authorizeUrl = new URL(resolveEndpoint(authEndpoints.authorize), window.location.origin);\n authorizeUrl.searchParams.set(\"return_to\", returnTo);\n const application = loginOptions?.application?.trim() || defaultApplication;\n if (application) {\n authorizeUrl.searchParams.set(\"app\", application);\n }\n window.location.assign(authorizeUrl.toString());\n };\n\n const logout = async (): Promise<void> => {\n await postEmpty(resolveEndpoint(authEndpoints.logout));\n sessionStore.setSession(null);\n broadcastSync.publishSession(null);\n };\n\n const subscribe = sessionStore.subscribe.bind(sessionStore);\n\n return {\n init,\n getSession,\n login,\n logout,\n refresh,\n requireSession,\n subscribe,\n };\n}\n"]}
|
package/dist/next.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { G as GhostlySession, A as AuthClient } from './auth-client-
|
|
1
|
+
import { G as GhostlySession, A as AuthClient } from './auth-client-Cdkp07ii.js';
|
|
2
2
|
|
|
3
|
-
type CookieSecureMode = "auto" | boolean;
|
|
4
3
|
interface NextServerSessionRuntimeOptions {
|
|
4
|
+
apiOrigin?: string;
|
|
5
5
|
fetchImplementation?: typeof fetch;
|
|
6
6
|
headers?: Headers;
|
|
7
7
|
protocol?: string;
|
|
@@ -9,34 +9,11 @@ interface NextServerSessionRuntimeOptions {
|
|
|
9
9
|
declare function getNextServerSession(options?: NextServerSessionRuntimeOptions): Promise<GhostlySession | null>;
|
|
10
10
|
declare function tryGetNextServerSession(options?: NextServerSessionRuntimeOptions): Promise<GhostlySession | null>;
|
|
11
11
|
declare function requireNextServerSession(options?: NextServerSessionRuntimeOptions): Promise<GhostlySession>;
|
|
12
|
-
interface NextProxyRouteHandlersOptions {
|
|
13
|
-
baseUrl: string;
|
|
14
|
-
}
|
|
15
|
-
interface NextMockRouteHandlersOptions {
|
|
16
|
-
callbackToken?: string;
|
|
17
|
-
cookieName?: string;
|
|
18
|
-
cookieSecure?: CookieSecureMode;
|
|
19
|
-
cookieValue?: string;
|
|
20
|
-
createSession?: () => GhostlySession;
|
|
21
|
-
frontendCallbackPath?: string;
|
|
22
|
-
}
|
|
23
|
-
interface NextAuthRouteHandlersOptions {
|
|
24
|
-
mock?: NextMockRouteHandlersOptions;
|
|
25
|
-
mode: "mock" | "proxy";
|
|
26
|
-
proxy?: NextProxyRouteHandlersOptions;
|
|
27
|
-
}
|
|
28
|
-
interface NextAuthRouteHandlers {
|
|
29
|
-
keycloakCallbackGet: (request: Request) => Promise<Response>;
|
|
30
|
-
keycloakLoginGet: (request: Request) => Promise<Response>;
|
|
31
|
-
keycloakValidatePost: (request: Request) => Promise<Response>;
|
|
32
|
-
meGet: (request: Request) => Promise<Response>;
|
|
33
|
-
logoutPost: (request: Request) => Promise<Response>;
|
|
34
|
-
}
|
|
35
|
-
declare function createNextAuthRouteHandlers(options: NextAuthRouteHandlersOptions): NextAuthRouteHandlers;
|
|
36
12
|
|
|
37
13
|
declare function ensureClientAuthenticated(client?: AuthClient): Promise<GhostlySession>;
|
|
38
14
|
|
|
39
15
|
interface ServerSessionOptions {
|
|
16
|
+
apiOrigin?: string;
|
|
40
17
|
fetchImplementation?: typeof fetch;
|
|
41
18
|
headers: Headers;
|
|
42
19
|
protocol?: string;
|
|
@@ -44,4 +21,4 @@ interface ServerSessionOptions {
|
|
|
44
21
|
declare function getServerSession(options: ServerSessionOptions): Promise<GhostlySession | null>;
|
|
45
22
|
declare function requireServerSession(options: ServerSessionOptions): Promise<GhostlySession>;
|
|
46
23
|
|
|
47
|
-
export { type
|
|
24
|
+
export { type NextServerSessionRuntimeOptions, type ServerSessionOptions, ensureClientAuthenticated, getNextServerSession, getServerSession, requireNextServerSession, requireServerSession, tryGetNextServerSession };
|