@camstack/addon-auth 1.2.146 → 1.2.147
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/{dist-BtJOajm3.mjs → dist-BGsjH-S3.mjs} +38 -5
- package/dist/{dist-DtqB-MTf.js → dist-DDdB_Mme.js} +43 -4
- package/dist/oidc/auth-oidc.addon.js +5 -3
- package/dist/oidc/auth-oidc.addon.mjs +5 -3
- package/dist/webauthn/{_virtual_mf-localSharedImportMap___mfe_internal__addon_auth_webauthn_widgets-C3_j2tlC.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_auth_webauthn_widgets-DiKn9eAB.mjs} +2 -2
- package/dist/webauthn/auth-webauthn.addon.js +1 -1
- package/dist/webauthn/auth-webauthn.addon.mjs +1 -1
- package/dist/webauthn/{hostInit-H35G8h3o.mjs → hostInit-Cf9MrMyw.mjs} +2 -2
- package/dist/webauthn/remoteEntry.js +1 -1
- package/package.json +1 -1
|
@@ -12327,6 +12327,13 @@ function parseAppAuthCallback(raw) {
|
|
|
12327
12327
|
*/
|
|
12328
12328
|
/** What the app redeems the code for. `step-up` yields a proof, never a session. */
|
|
12329
12329
|
var AppFlowPurposeSchema = _enum(["new-session", "step-up"]);
|
|
12330
|
+
/** The languages the hub's app landing pages are written in (D858). */
|
|
12331
|
+
var AppPageLangSchema = _enum(["en", "it"]);
|
|
12332
|
+
/** Narrows an untrusted `lang` value to the allow-list; anything else is `undefined`, never echoed. */
|
|
12333
|
+
function parseAppPageLang(value) {
|
|
12334
|
+
const parsed = AppPageLangSchema.safeParse(value);
|
|
12335
|
+
return parsed.success ? parsed.data : void 0;
|
|
12336
|
+
}
|
|
12330
12337
|
/** Where the app is sent when the request names no `redirect`. */
|
|
12331
12338
|
var APP_FLOW_DEFAULT_REDIRECT = "camstack://auth-callback";
|
|
12332
12339
|
/** S256 challenge: base64url of 32 bytes = 43 characters, no padding. */
|
|
@@ -12343,7 +12350,8 @@ var STATE_PATTERN = /^[A-Za-z0-9._~-]{1,256}$/;
|
|
|
12343
12350
|
var APP_REFUSED_PATH = "/auth/app/refused";
|
|
12344
12351
|
/**
|
|
12345
12352
|
* Read the app parameters off a start query: `code_challenge`,
|
|
12346
|
-
* `code_challenge_method`, `state`, `purpose`, `redirect
|
|
12353
|
+
* `code_challenge_method`, `state`, `purpose`, `redirect`, and the optional `lang` (an unknown value is
|
|
12354
|
+
* dropped, not refused). Anything missing or
|
|
12347
12355
|
* malformed is refused - there is no lenient default for PKCE or state.
|
|
12348
12356
|
*/
|
|
12349
12357
|
function parseAppFlowRequest(query) {
|
|
@@ -12372,13 +12380,15 @@ function parseAppFlowRequest(query) {
|
|
|
12372
12380
|
ok: false,
|
|
12373
12381
|
reason: "bad-redirect"
|
|
12374
12382
|
};
|
|
12383
|
+
const lang = parseAppPageLang(query["lang"]);
|
|
12375
12384
|
return {
|
|
12376
12385
|
ok: true,
|
|
12377
12386
|
request: {
|
|
12378
12387
|
codeChallenge: challenge,
|
|
12379
12388
|
state,
|
|
12380
12389
|
purpose: purpose.data,
|
|
12381
|
-
redirect
|
|
12390
|
+
redirect,
|
|
12391
|
+
...lang !== void 0 ? { lang } : {}
|
|
12382
12392
|
}
|
|
12383
12393
|
};
|
|
12384
12394
|
}
|
|
@@ -49957,7 +49967,9 @@ var SsoBridgeClaimsSchema = object({
|
|
|
49957
49967
|
codeChallenge: string(),
|
|
49958
49968
|
state: string(),
|
|
49959
49969
|
purpose: _enum(["new-session", "step-up"]),
|
|
49960
|
-
redirect: string()
|
|
49970
|
+
redirect: string(),
|
|
49971
|
+
/** The page language the app asked for (D858); the confirm page speaks it. */
|
|
49972
|
+
lang: _enum(["en", "it"]).optional()
|
|
49961
49973
|
}).optional()
|
|
49962
49974
|
});
|
|
49963
49975
|
method(object({
|
|
@@ -59356,6 +59368,21 @@ DeviceType.Switch, DeviceType.Siren, DeviceType.Light, method(object({
|
|
|
59356
59368
|
on: boolean(),
|
|
59357
59369
|
lastChangedAt: number()
|
|
59358
59370
|
});
|
|
59371
|
+
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
59372
|
+
function hasControlCharacter(value) {
|
|
59373
|
+
for (const char of value) {
|
|
59374
|
+
const code = char.codePointAt(0) ?? 0;
|
|
59375
|
+
if (code <= 31 || code >= 127 && code <= 159) return true;
|
|
59376
|
+
}
|
|
59377
|
+
return false;
|
|
59378
|
+
}
|
|
59379
|
+
string().transform((value) => value.trim()).pipe(string().min(1, "The server name cannot be empty").max(48, `The server name is at most 48 characters`).refine((value) => !hasControlCharacter(value), { message: "The server name cannot contain control characters" }));
|
|
59380
|
+
/** What every reader gets: the name to show, and whether the hub chose it itself. */
|
|
59381
|
+
var ServerNameInfoSchema = object({
|
|
59382
|
+
name: string(),
|
|
59383
|
+
/** `true` when nobody named the hub: `name` is the machine hostname. */
|
|
59384
|
+
isDefault: boolean()
|
|
59385
|
+
});
|
|
59359
59386
|
/**
|
|
59360
59387
|
* system — system-scoped singleton capability exposing hub-level
|
|
59361
59388
|
* health, feature flags, network interface enumeration, and the
|
|
@@ -59385,6 +59412,12 @@ var FeatureManifestSchema = object({
|
|
|
59385
59412
|
backup: boolean(),
|
|
59386
59413
|
repl: boolean()
|
|
59387
59414
|
});
|
|
59415
|
+
/**
|
|
59416
|
+
* `system.info`: the feature flags plus the hub's human name (D861). The name is
|
|
59417
|
+
* `{ name, isDefault }` — `isDefault: true` means nobody named the hub and `name`
|
|
59418
|
+
* is the machine hostname.
|
|
59419
|
+
*/
|
|
59420
|
+
var SystemInfoSchema = FeatureManifestSchema.extend({ serverName: ServerNameInfoSchema });
|
|
59388
59421
|
var HealthStatusSchema = object({
|
|
59389
59422
|
status: literal("ok"),
|
|
59390
59423
|
uptime: number()
|
|
@@ -59857,7 +59890,7 @@ var LoggingSettingsStateSchema = object({
|
|
|
59857
59890
|
opsLogRetentionDays: number().int().min(0),
|
|
59858
59891
|
persisted: boolean()
|
|
59859
59892
|
});
|
|
59860
|
-
method(_void(),
|
|
59893
|
+
method(_void(), SystemInfoSchema), method(_void(), HealthStatusSchema), method(_void(), FeatureManifestSchema), method(_void(), array(NetworkAddressSchema).readonly()), method(_void(), unknown().nullable(), { auth: "admin" }), method(record(string(), unknown()), _null(), {
|
|
59861
59894
|
kind: "mutation",
|
|
59862
59895
|
auth: "admin"
|
|
59863
59896
|
}), method(_void(), _void(), {
|
|
@@ -72892,4 +72925,4 @@ DEFAULT_NATIVE_LEASE_SETTINGS.admission;
|
|
|
72892
72925
|
var MB = 1024 * 1024;
|
|
72893
72926
|
1024 * MB, 3072 * MB;
|
|
72894
72927
|
//#endregion
|
|
72895
|
-
export {
|
|
72928
|
+
export { number as A, arrayItemFieldPath as C, toSecretFieldView as D, isSecretMarker as E, string as M, array as O, SECRET_CLEAR as S, isSecretClear as T, requestMountPrefix as _, addonWidgetsSourceCapability as a, errMsg as b, authProviderCapability as c, loginMethodCapability as d, normalizeOrigin as f, pickRequestOrigin as g, parseAppPageLang as h, addonRoutesCapability as i, object as j, boolean as k, buildAddonRouteProvider as l, parseAppFlowRequest as m, APP_REFUSED_PATH as n, advertisedHubOrigins as o, oidcConnectionsCapability as p, SSO_STATE_COOKIE as r, appFlowLocation as s, APP_FLOW_DEFAULT_REDIRECT as t, claimedRequestOrigins as u, resolveIconKey as v, globalSecretScope as w, BaseAddon as x, userPasskeysCapability as y };
|
|
@@ -12361,6 +12361,13 @@ function parseAppAuthCallback(raw) {
|
|
|
12361
12361
|
*/
|
|
12362
12362
|
/** What the app redeems the code for. `step-up` yields a proof, never a session. */
|
|
12363
12363
|
var AppFlowPurposeSchema = _enum(["new-session", "step-up"]);
|
|
12364
|
+
/** The languages the hub's app landing pages are written in (D858). */
|
|
12365
|
+
var AppPageLangSchema = _enum(["en", "it"]);
|
|
12366
|
+
/** Narrows an untrusted `lang` value to the allow-list; anything else is `undefined`, never echoed. */
|
|
12367
|
+
function parseAppPageLang(value) {
|
|
12368
|
+
const parsed = AppPageLangSchema.safeParse(value);
|
|
12369
|
+
return parsed.success ? parsed.data : void 0;
|
|
12370
|
+
}
|
|
12364
12371
|
/** Where the app is sent when the request names no `redirect`. */
|
|
12365
12372
|
var APP_FLOW_DEFAULT_REDIRECT = "camstack://auth-callback";
|
|
12366
12373
|
/** S256 challenge: base64url of 32 bytes = 43 characters, no padding. */
|
|
@@ -12377,7 +12384,8 @@ var STATE_PATTERN = /^[A-Za-z0-9._~-]{1,256}$/;
|
|
|
12377
12384
|
var APP_REFUSED_PATH = "/auth/app/refused";
|
|
12378
12385
|
/**
|
|
12379
12386
|
* Read the app parameters off a start query: `code_challenge`,
|
|
12380
|
-
* `code_challenge_method`, `state`, `purpose`, `redirect
|
|
12387
|
+
* `code_challenge_method`, `state`, `purpose`, `redirect`, and the optional `lang` (an unknown value is
|
|
12388
|
+
* dropped, not refused). Anything missing or
|
|
12381
12389
|
* malformed is refused - there is no lenient default for PKCE or state.
|
|
12382
12390
|
*/
|
|
12383
12391
|
function parseAppFlowRequest(query) {
|
|
@@ -12406,13 +12414,15 @@ function parseAppFlowRequest(query) {
|
|
|
12406
12414
|
ok: false,
|
|
12407
12415
|
reason: "bad-redirect"
|
|
12408
12416
|
};
|
|
12417
|
+
const lang = parseAppPageLang(query["lang"]);
|
|
12409
12418
|
return {
|
|
12410
12419
|
ok: true,
|
|
12411
12420
|
request: {
|
|
12412
12421
|
codeChallenge: challenge,
|
|
12413
12422
|
state,
|
|
12414
12423
|
purpose: purpose.data,
|
|
12415
|
-
redirect
|
|
12424
|
+
redirect,
|
|
12425
|
+
...lang !== void 0 ? { lang } : {}
|
|
12416
12426
|
}
|
|
12417
12427
|
};
|
|
12418
12428
|
}
|
|
@@ -49991,7 +50001,9 @@ var SsoBridgeClaimsSchema = object({
|
|
|
49991
50001
|
codeChallenge: string(),
|
|
49992
50002
|
state: string(),
|
|
49993
50003
|
purpose: _enum(["new-session", "step-up"]),
|
|
49994
|
-
redirect: string()
|
|
50004
|
+
redirect: string(),
|
|
50005
|
+
/** The page language the app asked for (D858); the confirm page speaks it. */
|
|
50006
|
+
lang: _enum(["en", "it"]).optional()
|
|
49995
50007
|
}).optional()
|
|
49996
50008
|
});
|
|
49997
50009
|
method(object({
|
|
@@ -59390,6 +59402,21 @@ DeviceType.Switch, DeviceType.Siren, DeviceType.Light, method(object({
|
|
|
59390
59402
|
on: boolean(),
|
|
59391
59403
|
lastChangedAt: number()
|
|
59392
59404
|
});
|
|
59405
|
+
/** C0 controls, DEL and the C1 range: none of them belongs in a name. */
|
|
59406
|
+
function hasControlCharacter(value) {
|
|
59407
|
+
for (const char of value) {
|
|
59408
|
+
const code = char.codePointAt(0) ?? 0;
|
|
59409
|
+
if (code <= 31 || code >= 127 && code <= 159) return true;
|
|
59410
|
+
}
|
|
59411
|
+
return false;
|
|
59412
|
+
}
|
|
59413
|
+
string().transform((value) => value.trim()).pipe(string().min(1, "The server name cannot be empty").max(48, `The server name is at most 48 characters`).refine((value) => !hasControlCharacter(value), { message: "The server name cannot contain control characters" }));
|
|
59414
|
+
/** What every reader gets: the name to show, and whether the hub chose it itself. */
|
|
59415
|
+
var ServerNameInfoSchema = object({
|
|
59416
|
+
name: string(),
|
|
59417
|
+
/** `true` when nobody named the hub: `name` is the machine hostname. */
|
|
59418
|
+
isDefault: boolean()
|
|
59419
|
+
});
|
|
59393
59420
|
/**
|
|
59394
59421
|
* system — system-scoped singleton capability exposing hub-level
|
|
59395
59422
|
* health, feature flags, network interface enumeration, and the
|
|
@@ -59419,6 +59446,12 @@ var FeatureManifestSchema = object({
|
|
|
59419
59446
|
backup: boolean(),
|
|
59420
59447
|
repl: boolean()
|
|
59421
59448
|
});
|
|
59449
|
+
/**
|
|
59450
|
+
* `system.info`: the feature flags plus the hub's human name (D861). The name is
|
|
59451
|
+
* `{ name, isDefault }` — `isDefault: true` means nobody named the hub and `name`
|
|
59452
|
+
* is the machine hostname.
|
|
59453
|
+
*/
|
|
59454
|
+
var SystemInfoSchema = FeatureManifestSchema.extend({ serverName: ServerNameInfoSchema });
|
|
59422
59455
|
var HealthStatusSchema = object({
|
|
59423
59456
|
status: literal("ok"),
|
|
59424
59457
|
uptime: number()
|
|
@@ -59891,7 +59924,7 @@ var LoggingSettingsStateSchema = object({
|
|
|
59891
59924
|
opsLogRetentionDays: number().int().min(0),
|
|
59892
59925
|
persisted: boolean()
|
|
59893
59926
|
});
|
|
59894
|
-
method(_void(),
|
|
59927
|
+
method(_void(), SystemInfoSchema), method(_void(), HealthStatusSchema), method(_void(), FeatureManifestSchema), method(_void(), array(NetworkAddressSchema).readonly()), method(_void(), unknown().nullable(), { auth: "admin" }), method(record(string(), unknown()), _null(), {
|
|
59895
59928
|
kind: "mutation",
|
|
59896
59929
|
auth: "admin"
|
|
59897
59930
|
}), method(_void(), _void(), {
|
|
@@ -73106,6 +73139,12 @@ Object.defineProperty(exports, "parseAppFlowRequest", {
|
|
|
73106
73139
|
return parseAppFlowRequest;
|
|
73107
73140
|
}
|
|
73108
73141
|
});
|
|
73142
|
+
Object.defineProperty(exports, "parseAppPageLang", {
|
|
73143
|
+
enumerable: true,
|
|
73144
|
+
get: function() {
|
|
73145
|
+
return parseAppPageLang;
|
|
73146
|
+
}
|
|
73147
|
+
});
|
|
73109
73148
|
Object.defineProperty(exports, "pickRequestOrigin", {
|
|
73110
73149
|
enumerable: true,
|
|
73111
73150
|
get: function() {
|
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
5
|
+
const require_dist = require("../dist-DDdB_Mme.js");
|
|
6
6
|
let node_crypto = require("node:crypto");
|
|
7
7
|
node_crypto = require_dist.__toESM(node_crypto);
|
|
8
8
|
//#region ../../node_modules/jose/dist/webapi/lib/buffer_utils.js
|
|
@@ -1411,7 +1411,8 @@ var AuthOidcAddon = class extends require_dist.BaseAddon {
|
|
|
1411
1411
|
const reason = parsed.ok ? "combined-flow" : parsed.reason;
|
|
1412
1412
|
reply.code(303);
|
|
1413
1413
|
reply.header("Cache-Control", "no-store");
|
|
1414
|
-
|
|
1414
|
+
const lang = require_dist.parseAppPageLang(query["lang"]);
|
|
1415
|
+
reply.header("Location", `${require_dist.APP_REFUSED_PATH}?reason=${reason}${lang !== void 0 ? `&lang=${lang}` : ""}`);
|
|
1415
1416
|
reply.send("");
|
|
1416
1417
|
return;
|
|
1417
1418
|
}
|
|
@@ -1524,7 +1525,8 @@ var AuthOidcAddon = class extends require_dist.BaseAddon {
|
|
|
1524
1525
|
codeChallenge: result.app.codeChallenge,
|
|
1525
1526
|
state: result.app.state,
|
|
1526
1527
|
purpose: result.app.purpose,
|
|
1527
|
-
redirect: result.app.redirect
|
|
1528
|
+
redirect: result.app.redirect,
|
|
1529
|
+
...result.app.lang !== void 0 ? { lang: result.app.lang } : {}
|
|
1528
1530
|
} } : {}
|
|
1529
1531
|
} });
|
|
1530
1532
|
const finish = new URLSearchParams({ bridge: bridgeToken });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { C as arrayItemFieldPath, D as toSecretFieldView, E as isSecretMarker, S as SECRET_CLEAR, T as isSecretClear, _ as requestMountPrefix, b as errMsg, c as authProviderCapability, d as loginMethodCapability, f as normalizeOrigin, g as pickRequestOrigin, h as parseAppPageLang, i as addonRoutesCapability, l as buildAddonRouteProvider, m as parseAppFlowRequest, n as APP_REFUSED_PATH, o as advertisedHubOrigins, p as oidcConnectionsCapability, r as SSO_STATE_COOKIE, s as appFlowLocation, t as APP_FLOW_DEFAULT_REDIRECT, u as claimedRequestOrigins, v as resolveIconKey, w as globalSecretScope, x as BaseAddon } from "../dist-BGsjH-S3.mjs";
|
|
2
2
|
import * as crypto$1 from "node:crypto";
|
|
3
3
|
//#region ../../node_modules/jose/dist/webapi/lib/buffer_utils.js
|
|
4
4
|
var encoder = new TextEncoder(), decoder = new TextDecoder(), strictDecoder = new TextDecoder("utf-8", { fatal: !0 });
|
|
@@ -1406,7 +1406,8 @@ var AuthOidcAddon = class extends BaseAddon {
|
|
|
1406
1406
|
const reason = parsed.ok ? "combined-flow" : parsed.reason;
|
|
1407
1407
|
reply.code(303);
|
|
1408
1408
|
reply.header("Cache-Control", "no-store");
|
|
1409
|
-
|
|
1409
|
+
const lang = parseAppPageLang(query["lang"]);
|
|
1410
|
+
reply.header("Location", `${APP_REFUSED_PATH}?reason=${reason}${lang !== void 0 ? `&lang=${lang}` : ""}`);
|
|
1410
1411
|
reply.send("");
|
|
1411
1412
|
return;
|
|
1412
1413
|
}
|
|
@@ -1519,7 +1520,8 @@ var AuthOidcAddon = class extends BaseAddon {
|
|
|
1519
1520
|
codeChallenge: result.app.codeChallenge,
|
|
1520
1521
|
state: result.app.state,
|
|
1521
1522
|
purpose: result.app.purpose,
|
|
1522
|
-
redirect: result.app.redirect
|
|
1523
|
+
redirect: result.app.redirect,
|
|
1524
|
+
...result.app.lang !== void 0 ? { lang: result.app.lang } : {}
|
|
1523
1525
|
} } : {}
|
|
1524
1526
|
} });
|
|
1525
1527
|
const finish = new URLSearchParams({ bridge: bridgeToken });
|
|
@@ -18,7 +18,7 @@ var e = {
|
|
|
18
18
|
},
|
|
19
19
|
"@camstack/types": {
|
|
20
20
|
name: "@camstack/types",
|
|
21
|
-
version: "1.2.
|
|
21
|
+
version: "1.2.373",
|
|
22
22
|
scope: ["default"],
|
|
23
23
|
loaded: !1,
|
|
24
24
|
from: "addon_auth_webauthn_widgets",
|
|
@@ -33,7 +33,7 @@ var e = {
|
|
|
33
33
|
},
|
|
34
34
|
"@camstack/ui-library": {
|
|
35
35
|
name: "@camstack/ui-library",
|
|
36
|
-
version: "1.2.
|
|
36
|
+
version: "1.2.291",
|
|
37
37
|
scope: ["default"],
|
|
38
38
|
loaded: !1,
|
|
39
39
|
from: "addon_auth_webauthn_widgets",
|
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
5
|
+
const require_dist = require("../dist-DDdB_Mme.js");
|
|
6
6
|
let stream = require("stream");
|
|
7
7
|
stream = require_dist.__toESM(stream, 1);
|
|
8
8
|
let http = require("http");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as number, M as string, O as array, a as addonWidgetsSourceCapability, d as loginMethodCapability, j as object, k as boolean, x as BaseAddon, y as userPasskeysCapability } from "../dist-BGsjH-S3.mjs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import Stream from "stream";
|
|
4
4
|
import http from "http";
|
|
@@ -36,7 +36,7 @@ async function r() {
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"@camstack/types": {
|
|
39
|
-
version: "1.2.
|
|
39
|
+
version: "1.2.373",
|
|
40
40
|
scope: "default",
|
|
41
41
|
shareConfig: {
|
|
42
42
|
singleton: !0,
|
|
@@ -81,7 +81,7 @@ async function r() {
|
|
|
81
81
|
}
|
|
82
82
|
},
|
|
83
83
|
"@camstack/ui-library": {
|
|
84
|
-
version: "1.2.
|
|
84
|
+
version: "1.2.291",
|
|
85
85
|
scope: "default",
|
|
86
86
|
shareConfig: {
|
|
87
87
|
singleton: !0,
|
|
@@ -30,7 +30,7 @@ async function d(e) {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
async function f() {
|
|
33
|
-
return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_auth_webauthn_widgets-
|
|
33
|
+
return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_auth_webauthn_widgets-DiKn9eAB.mjs")).catch((e) => {
|
|
34
34
|
throw l = void 0, e;
|
|
35
35
|
}), l;
|
|
36
36
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-auth",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.147",
|
|
4
4
|
"description": "Authentication bundle — OIDC and WebAuthn/passkey. Multi-entry npm package shipping 2 addons under a single bundle; each addon keeps its own id, capabilities, and runner.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|